github.com/GuanceCloud/cliutils@v1.1.21/point/lp.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  	"regexp"
    11  	"sort"
    12  	"time"
    13  
    14  	"github.com/influxdata/influxdb1-client/models"
    15  )
    16  
    17  type Precision int
    18  
    19  const (
    20  	PrecNS  Precision = iota // nano-second
    21  	PrecUS                   // micro-second
    22  	PrecMS                   // milli-second
    23  	PrecS                    // second
    24  	PrecM                    // minute
    25  	PrecH                    // hour
    26  	PrecD                    // day
    27  	PrecW                    // week
    28  	PrecDyn                  // dynamic precision
    29  )
    30  
    31  func (p Precision) String() string {
    32  	switch p {
    33  	case PrecNS:
    34  		return "n"
    35  	case PrecUS:
    36  		return "u"
    37  	case PrecMS:
    38  		return "ms"
    39  	case PrecS:
    40  		return "s"
    41  	case PrecM:
    42  		return "m"
    43  	case PrecH:
    44  		return "h"
    45  	case PrecD:
    46  		return "d"
    47  	case PrecW:
    48  		return "w"
    49  	default:
    50  		return "unknown"
    51  	}
    52  }
    53  
    54  func PrecStr(s string) Precision {
    55  	switch s {
    56  	case "n":
    57  		return PrecNS
    58  	case "u":
    59  		return PrecUS
    60  	case "ms":
    61  		return PrecMS
    62  	case "s":
    63  		return PrecS
    64  	case "m":
    65  		return PrecM
    66  	case "h":
    67  		return PrecH
    68  	default:
    69  		return PrecNS
    70  	}
    71  }
    72  
    73  var sepRe = regexp.MustCompile(": ")
    74  
    75  // simplifyLPError used to simplify original line-protocol parse error, the
    76  // parse error will print origin data payload, for large payload, it's hard
    77  // to read the error message.
    78  func simplifyLPError(err error) error {
    79  	parts := sepRe.Split(err.Error(), -1)
    80  	if len(parts) != 2 { // return origin error
    81  		return err
    82  	}
    83  
    84  	return fmt.Errorf("lineproto parse error: %s", parts[1])
    85  }
    86  
    87  // parseLPPoints parse line-protocol payload to Point.
    88  func parseLPPoints(data []byte, c *cfg) ([]*Point, error) {
    89  	if len(data) == 0 {
    90  		return nil, fmt.Errorf("empty data")
    91  	}
    92  
    93  	if c == nil {
    94  		c = GetCfg()
    95  		defer PutCfg(c)
    96  	}
    97  
    98  	ptTime := c.t
    99  	if c.t.IsZero() {
   100  		ptTime = time.Now()
   101  	}
   102  
   103  	// NOTE: always parse point with precision ns, the caller should
   104  	// adjust the time according to specific precision setting.
   105  	lppts, err := models.ParsePointsWithPrecision(data, ptTime, "ns")
   106  	if err != nil {
   107  		return nil, fmt.Errorf("%w: %s. Origin data: %q",
   108  			ErrInvalidLineProtocol, err, data)
   109  	}
   110  
   111  	res := []*Point{}
   112  	chk := checker{cfg: c}
   113  
   114  	for _, x := range lppts {
   115  		if x == nil {
   116  			return nil, fmt.Errorf("line point is empty")
   117  		}
   118  
   119  		if c.extraTags != nil {
   120  			for _, t := range c.extraTags {
   121  				if !x.HasTag([]byte(t.Key)) {
   122  					x.AddTag(t.Key, t.GetS())
   123  				}
   124  			}
   125  		}
   126  
   127  		pt := FromModelsLP(x)
   128  		if pt == nil {
   129  			continue
   130  		}
   131  
   132  		if c.keySorted {
   133  			kvs := KVs(pt.pt.Fields)
   134  			sort.Sort(kvs)
   135  			pt.pt.Fields = kvs
   136  		}
   137  
   138  		pt = chk.check(pt)
   139  		pt.pt.Warns = chk.warns
   140  		chk.reset()
   141  
   142  		// re-sort again: check may update pt.pt.Fields
   143  		if c.keySorted {
   144  			kvs := KVs(pt.pt.Fields)
   145  			sort.Sort(kvs)
   146  			pt.pt.Fields = kvs
   147  		}
   148  
   149  		res = append(res, pt)
   150  	}
   151  
   152  	return res, nil
   153  }