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  }