github.com/GuanceCloud/cliutils@v1.1.21/point/easyproto.go (about) 1 // Unless explicitly stated otherwise all files in this repository are licensed 2 // under the MIT License. 3 // This product includes software developed at Guance Cloud (https://www.guance.com/). 4 // Copyright 2021-present Guance, Inc. 5 6 package point 7 8 import ( 9 "fmt" 10 "time" 11 12 "github.com/VictoriaMetrics/easyproto" 13 ) 14 15 var mp easyproto.MarshalerPool 16 17 // marshal. 18 func marshalPoints(pts []*Point, dst []byte) []byte { 19 m := mp.Get() 20 mm := m.MessageMarshaler() 21 22 for _, pt := range pts { 23 if pt == nil || pt.pt == nil { 24 continue 25 } 26 27 marshalPoint(pt, mm.AppendMessage(1)) 28 } 29 30 dst = m.Marshal(dst) 31 mp.Put(m) 32 return dst 33 } 34 35 func marshalPoint(pt *Point, mm *easyproto.MessageMarshaler) { 36 mm.AppendString(1, pt.pt.Name) 37 for _, f := range pt.pt.Fields { 38 f.marshalProtobuf(mm.AppendMessage(2)) 39 } 40 41 mm.AppendInt64(3, pt.pt.Time) 42 43 for _, w := range pt.pt.Warns { 44 w.marshalProtobuf(mm.AppendMessage(4)) 45 } 46 47 for _, d := range pt.pt.Debugs { 48 d.marshalProtobuf(mm.AppendMessage(5)) 49 } 50 } 51 52 func (kv *Field) marshalProtobuf(mm *easyproto.MessageMarshaler) { 53 mm.AppendString(1, kv.Key) 54 55 switch x := kv.Val.(type) { 56 case *Field_I: 57 mm.AppendInt64(2, x.I) 58 case *Field_U: 59 mm.AppendUint64(3, x.U) 60 case *Field_F: 61 mm.AppendDouble(4, x.F) 62 case *Field_B: 63 mm.AppendBool(5, x.B) 64 case *Field_D: 65 mm.AppendBytes(6, x.D) 66 case *Field_S: 67 mm.AppendString(11, x.S) 68 case *Field_A: 69 // TODO 70 } 71 72 mm.AppendBool(8, kv.IsTag) 73 mm.AppendInt32(9, int32(kv.Type)) 74 mm.AppendString(10, kv.Unit) 75 } 76 77 func (w *Warn) marshalProtobuf(mm *easyproto.MessageMarshaler) { 78 mm.AppendString(1, w.Type) 79 mm.AppendString(2, w.Msg) 80 } 81 82 func (d *Debug) marshalProtobuf(mm *easyproto.MessageMarshaler) { 83 mm.AppendString(1, d.Info) 84 } 85 86 type Points []*Point 87 88 // unmarshal. 89 func unmarshalPoints(src []byte) ([]*Point, error) { 90 var ( 91 fc easyproto.FieldContext 92 pts []*Point 93 err error 94 ) 95 96 for len(src) > 0 { 97 src, err = fc.NextField(src) 98 if err != nil { 99 return nil, fmt.Errorf("read next field for PBPoints failed: %w", err) 100 } 101 102 if fc.FieldNum == 1 { 103 data, ok := fc.MessageData() 104 if !ok { 105 return nil, fmt.Errorf("cannot read read Arr for PBPoints") 106 } 107 108 if pt, err := unmarshalPoint(data); err != nil { 109 return nil, fmt.Errorf("unmarshal point failed: %w", err) 110 } else { 111 pts = append(pts, pt) 112 } 113 } 114 } 115 116 return pts, nil 117 } 118 119 func unmarshalPoint(src []byte) (*Point, error) { 120 var ( 121 fc easyproto.FieldContext 122 kvs KVs 123 warns []*Warn 124 debugs []*Debug 125 name string 126 ts int64 127 err error 128 ) 129 130 for len(src) > 0 { 131 src, err = fc.NextField(src) 132 if err != nil { 133 return nil, fmt.Errorf("read next field for PBPoint failed: %w", err) 134 } 135 136 switch fc.FieldNum { 137 case 1: 138 if x, ok := fc.String(); ok { 139 name = x 140 } else { 141 return nil, fmt.Errorf("cannot read PBPoint name") 142 } 143 case 2: 144 data, ok := fc.MessageData() 145 if !ok { 146 return nil, fmt.Errorf("cannot read Fields for PBPoint") 147 } 148 149 if kv, err := unmarshalField(data); err == nil { 150 kvs = kvs.AddKV(kv, false) 151 } else { 152 return nil, fmt.Errorf("cannot unmarshal field: %w", err) 153 } 154 case 3: 155 if x, ok := fc.Int64(); ok { 156 ts = x 157 } else { 158 return nil, fmt.Errorf("cannot read PBPoint time") 159 } 160 161 case 4: // Warns 162 data, ok := fc.MessageData() 163 if !ok { 164 return nil, fmt.Errorf("cannot read Warn for PBPoint") 165 } 166 167 if x, err := unmarshalWarn(data); err == nil { 168 warns = append(warns, x) 169 } 170 171 case 5: // Debugs 172 data, ok := fc.MessageData() 173 if !ok { 174 return nil, fmt.Errorf("cannot read Debug for PBPoint") 175 } 176 177 if x, err := unmarshalDebug(data); err == nil { 178 debugs = append(debugs, x) 179 } 180 } 181 } 182 183 pt := NewPointV2(name, kvs, WithTime(time.Unix(0, ts))) 184 pt.pt.Warns = warns 185 pt.pt.Debugs = debugs 186 187 return pt, err 188 } 189 190 func unmarshalWarn(src []byte) (*Warn, error) { 191 var ( 192 wtype, wmsg string 193 fc easyproto.FieldContext 194 err error 195 ) 196 197 for len(src) > 0 { 198 src, err = fc.NextField(src) 199 if err != nil { 200 return nil, fmt.Errorf("read next field for Warn failed: %w", err) 201 } 202 203 switch fc.FieldNum { 204 case 1: 205 if x, ok := fc.String(); ok { 206 wtype = x 207 } 208 case 2: 209 if x, ok := fc.String(); ok { 210 wmsg = x 211 } 212 } 213 } 214 215 return &Warn{Type: wtype, Msg: wmsg}, nil 216 } 217 218 func unmarshalDebug(src []byte) (*Debug, error) { 219 var ( 220 info string 221 fc easyproto.FieldContext 222 err error 223 ) 224 225 for len(src) > 0 { 226 src, err = fc.NextField(src) 227 if err != nil { 228 return nil, fmt.Errorf("read next field for Debug failed: %w", err) 229 } 230 231 if fc.FieldNum == 1 { 232 if x, ok := fc.String(); ok { 233 info = x 234 } 235 } 236 } 237 238 return &Debug{Info: info}, nil 239 } 240 241 func unmarshalField(src []byte) (*Field, error) { 242 var ( 243 fc easyproto.FieldContext 244 key, unit string 245 isTag bool 246 f *Field 247 metricType MetricType 248 err error 249 ) 250 251 for len(src) > 0 { 252 src, err = fc.NextField(src) 253 if err != nil { 254 return nil, fmt.Errorf("read next field for Field failed: %w", err) 255 } 256 257 switch fc.FieldNum { 258 case 1: 259 if x, ok := fc.String(); ok { 260 key = x 261 } else { 262 return nil, fmt.Errorf("cannot read Field key") 263 } 264 265 case 8: 266 if x, ok := fc.Bool(); ok { 267 isTag = x 268 } else { 269 return nil, fmt.Errorf("cannot unmarshal is-tag for Field") 270 } 271 272 case 2: 273 if x, ok := fc.Int64(); ok { 274 f = NewKV(key, x) 275 } 276 277 case 3: 278 if x, ok := fc.Uint64(); ok { 279 f = NewKV(key, x) 280 } 281 case 4: 282 if x, ok := fc.Double(); ok { 283 f = NewKV(key, x) 284 } 285 case 5: 286 if x, ok := fc.Bool(); ok { 287 f = NewKV(key, x) 288 } 289 case 6: 290 if x, ok := fc.Bytes(); ok { 291 f = NewKV(key, x) 292 } 293 294 case 11: 295 if x, ok := fc.String(); ok { 296 f = NewKV(key, x) 297 } 298 299 case 9: 300 if x, ok := fc.Int32(); ok { 301 metricType = MetricType(x) 302 } 303 case 10: 304 if x, ok := fc.String(); ok { 305 unit = x 306 } 307 default: // pass 308 } 309 } 310 311 if f != nil { 312 f.Unit = unit 313 f.Type = metricType 314 f.IsTag = isTag 315 } 316 317 return f, err 318 }