github.com/GuanceCloud/cliutils@v1.1.21/pipeline/ptinput/point.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 ptinput impl ppl input interface
     7  package ptinput
     8  
     9  import (
    10  	"errors"
    11  	"fmt"
    12  	"time"
    13  
    14  	"github.com/GuanceCloud/cliutils/pipeline/ptinput/ipdb"
    15  	"github.com/GuanceCloud/cliutils/pipeline/ptinput/plcache"
    16  	"github.com/GuanceCloud/cliutils/pipeline/ptinput/plmap"
    17  	"github.com/GuanceCloud/cliutils/pipeline/ptinput/ptwindow"
    18  	"github.com/GuanceCloud/cliutils/pipeline/ptinput/refertable"
    19  	"github.com/GuanceCloud/cliutils/pipeline/ptinput/utils"
    20  	"github.com/GuanceCloud/cliutils/point"
    21  	"github.com/GuanceCloud/platypus/pkg/ast"
    22  	plruntime "github.com/GuanceCloud/platypus/pkg/engine/runtime"
    23  
    24  	"github.com/spf13/cast"
    25  )
    26  
    27  type (
    28  	KeyKind uint
    29  	PtFlag  uint
    30  )
    31  
    32  var _ PlInputPt = (*PlPoint)(nil)
    33  
    34  type PlInputPt interface {
    35  	GetPtName() string
    36  	SetPtName(m string)
    37  
    38  	Get(key string) (any, ast.DType, error)
    39  	Set(key string, value any, dtype ast.DType) bool
    40  
    41  	Delete(key string)
    42  	RenameKey(from, to string) error
    43  
    44  	SetTag(key string, value any, dtype ast.DType) bool
    45  
    46  	PtTime() time.Time
    47  
    48  	GetAggBuckets() *plmap.AggBuckets
    49  	SetAggBuckets(*plmap.AggBuckets)
    50  
    51  	SetPtWinPool(w *ptwindow.WindowPool)
    52  	PtWinRegister(before, after int, k, v []string)
    53  	PtWinHit()
    54  	CallbackPtWinMove() (result []*point.Point)
    55  
    56  	AppendSubPoint(PlInputPt)
    57  	GetSubPoint() []PlInputPt
    58  	Category() point.Category
    59  
    60  	KeyTime2Time()
    61  
    62  	MarkDrop(bool)
    63  	Dropped() bool
    64  	Point() *point.Point
    65  
    66  	GetIPDB() ipdb.IPdb
    67  	SetIPDB(ipdb.IPdb)
    68  
    69  	GetPlReferTables() refertable.PlReferTables
    70  	SetPlReferTables(refertable.PlReferTables)
    71  
    72  	Tags() map[string]string
    73  	Fields() map[string]any
    74  
    75  	GetCache() *plcache.Cache
    76  	SetCache(*plcache.Cache)
    77  }
    78  
    79  const (
    80  	PtMeasurement PtFlag = iota
    81  	PtTag
    82  	PtField
    83  	PtTFDefaulutOrKeep
    84  	PtTime
    85  )
    86  
    87  const (
    88  	KindPtDefault KeyKind = iota
    89  	KindPtTag
    90  )
    91  
    92  const Originkey = "message"
    93  
    94  type InputWithVarbMapRW interface {
    95  	Get(key string) (any, ast.DType, bool)
    96  	Set(key string, value any, dtype ast.DType) bool
    97  	Delete(key string) bool
    98  }
    99  
   100  type InputWithVarbMapR interface {
   101  	Get(key string) (any, ast.DType, bool)
   102  }
   103  
   104  type InputWithoutVarbMap interface{}
   105  
   106  type DoFeedCache func(name, category string, pt *point.Point) error
   107  
   108  var DoFeedNOP = func(name, category string, pt *point.Point) error { return nil }
   109  
   110  type PlmapManager interface {
   111  	// createPtCaheMap(category string, source PtSource) (*fucs.PtCacheMap, bool)
   112  }
   113  
   114  type PlPoint struct {
   115  	name   string
   116  	tags   map[string]string
   117  	fields map[string]any // int, float, bool, string, map, slice, array
   118  	time   time.Time
   119  
   120  	aggBuckets *plmap.AggBuckets
   121  	ipdb       ipdb.IPdb
   122  	refTable   refertable.PlReferTables
   123  
   124  	subPlpt []PlInputPt
   125  
   126  	cache *plcache.Cache
   127  
   128  	ptWindowPool       *ptwindow.WindowPool
   129  	winKeyVal          [2][]string
   130  	ptWindowRegistered bool
   131  
   132  	drop     bool
   133  	category point.Category
   134  }
   135  
   136  func NewPlPoint(category point.Category, name string,
   137  	tags map[string]string, fields map[string]any, ptTime time.Time,
   138  ) PlInputPt {
   139  	if tags == nil {
   140  		tags = map[string]string{}
   141  	}
   142  
   143  	if fields == nil {
   144  		fields = map[string]any{}
   145  	}
   146  
   147  	dPt := &PlPoint{
   148  		name:     name,
   149  		tags:     tags,
   150  		fields:   fields,
   151  		time:     ptTime,
   152  		category: category,
   153  	}
   154  	return dPt
   155  }
   156  
   157  func valueDtype(v any) (any, ast.DType) {
   158  	switch v := v.(type) {
   159  	case int32, int8, int16, int,
   160  		uint, uint16, uint32, uint64, uint8:
   161  		return cast.ToInt64(v), ast.Int
   162  	case int64:
   163  		return v, ast.Int
   164  	case float32:
   165  		return cast.ToFloat64(v), ast.Float
   166  	case float64:
   167  		return v, ast.Float
   168  	case bool:
   169  		return v, ast.Bool
   170  	case []byte:
   171  		return string(v), ast.String
   172  	case string:
   173  		return v, ast.String
   174  	}
   175  
   176  	// ignore unknown type
   177  	return nil, ast.Nil
   178  }
   179  
   180  func (pt *PlPoint) GetPtName() string {
   181  	return pt.name
   182  }
   183  
   184  func (pt *PlPoint) SetPtName(m string) {
   185  	pt.name = m
   186  }
   187  
   188  func (pt *PlPoint) AppendSubPoint(plpt PlInputPt) {
   189  	pt.subPlpt = append(pt.subPlpt, plpt)
   190  }
   191  
   192  func (pt *PlPoint) GetSubPoint() []PlInputPt {
   193  	return pt.subPlpt
   194  }
   195  
   196  func (pt *PlPoint) Category() point.Category {
   197  	return pt.category
   198  }
   199  
   200  var ErrKeyNotExist = errors.New("key not exist")
   201  
   202  func (pt *PlPoint) Get(key string) (any, ast.DType, error) {
   203  	if v, ok := pt.tags[key]; ok {
   204  		return v, ast.String, nil
   205  	}
   206  
   207  	if v, ok := pt.fields[key]; ok {
   208  		v, dtype := valueDtype(v)
   209  		return v, dtype, nil
   210  	}
   211  	return nil, ast.Nil, ErrKeyNotExist
   212  }
   213  
   214  func (pt *PlPoint) GetWithIsTag(key string) (any, bool, bool) {
   215  	if v, ok := pt.tags[key]; ok {
   216  		return v, true, true
   217  	}
   218  
   219  	if v, ok := pt.fields[key]; ok {
   220  		v, _ := valueDtype(v)
   221  		return v, false, true
   222  	}
   223  	return nil, false, false
   224  }
   225  
   226  func (pt *PlPoint) Set(key string, value any, dtype ast.DType) bool {
   227  	if _, ok := pt.tags[key]; ok { // is tag
   228  		if dtype == ast.Void || dtype == ast.Invalid {
   229  			delete(pt.tags, key)
   230  			return true
   231  		}
   232  		if v, err := plruntime.Conv2String(value, dtype); err == nil {
   233  			pt.tags[key] = v
   234  			return true
   235  		} else {
   236  			return false
   237  		}
   238  	} else { // is field
   239  		switch dtype { //nolint:exhaustive
   240  		case ast.Nil, ast.Void, ast.Invalid:
   241  			pt.fields[key] = nil
   242  			return true
   243  		case ast.List, ast.Map:
   244  			if v, err := plruntime.Conv2String(value, dtype); err == nil {
   245  				pt.fields[key] = v
   246  			} else {
   247  				pt.fields[key] = nil
   248  				return true
   249  			}
   250  		default:
   251  			pt.fields[key] = value
   252  		}
   253  	}
   254  	return true
   255  }
   256  
   257  func (pt *PlPoint) Delete(key string) {
   258  	if _, ok := pt.tags[key]; ok {
   259  		delete(pt.tags, key)
   260  	} else {
   261  		delete(pt.fields, key)
   262  	}
   263  }
   264  
   265  func (pt *PlPoint) RenameKey(from, to string) error {
   266  	if v, ok := pt.fields[from]; ok {
   267  		pt.fields[to] = v
   268  		delete(pt.fields, from)
   269  	} else if v, ok := pt.tags[from]; ok {
   270  		pt.tags[to] = v
   271  		delete(pt.tags, from)
   272  	} else {
   273  		return fmt.Errorf("key(from) %s not found", from)
   274  	}
   275  	return nil
   276  }
   277  
   278  func (pt *PlPoint) SetTag(key string, value any, dtype ast.DType) bool {
   279  	delete(pt.fields, key)
   280  
   281  	if str, err := plruntime.Conv2String(value, dtype); err == nil {
   282  		pt.tags[key] = str
   283  		return true
   284  	} else {
   285  		pt.tags[key] = ""
   286  		return false
   287  	}
   288  }
   289  
   290  func (pt *PlPoint) PtTime() time.Time {
   291  	return pt.time
   292  }
   293  
   294  func (pt *PlPoint) GetAggBuckets() *plmap.AggBuckets {
   295  	return pt.aggBuckets
   296  }
   297  
   298  func (pt *PlPoint) SetAggBuckets(buks *plmap.AggBuckets) {
   299  	pt.aggBuckets = buks
   300  }
   301  
   302  func (pt *PlPoint) SetPlReferTables(refTable refertable.PlReferTables) {
   303  	pt.refTable = refTable
   304  }
   305  
   306  func (pt *PlPoint) GetPlReferTables() refertable.PlReferTables {
   307  	return pt.refTable
   308  }
   309  
   310  func (pt *PlPoint) SetPtWinPool(w *ptwindow.WindowPool) {
   311  	pt.ptWindowPool = w
   312  }
   313  
   314  func (pt *PlPoint) PtWinRegister(before, after int, k, v []string) {
   315  	if len(k) != len(v) || len(k) == 0 {
   316  		return
   317  	}
   318  	if pt.ptWindowPool != nil && !pt.ptWindowRegistered {
   319  		pt.ptWindowRegistered = true
   320  		pt.ptWindowPool.Register(before, after, k, v)
   321  		pt.winKeyVal = [2][]string{k, v}
   322  	}
   323  }
   324  
   325  func (pt *PlPoint) PtWinHit() {
   326  	if pt.ptWindowPool != nil && pt.ptWindowRegistered {
   327  		if len(pt.winKeyVal[0]) != len(pt.winKeyVal[1]) || len(pt.winKeyVal[0]) == 0 {
   328  			return
   329  		}
   330  
   331  		// 不校验 pipeline 中 point_window 函数执行后的 tag 的值的变化
   332  		//
   333  		if v, ok := pt.ptWindowPool.Get(pt.winKeyVal[0], pt.winKeyVal[1]); ok {
   334  			v.Hit()
   335  		}
   336  	}
   337  }
   338  
   339  func (pt *PlPoint) CallbackPtWinMove() (result []*point.Point) {
   340  	if pt.ptWindowPool != nil && pt.ptWindowRegistered {
   341  		if v, ok := pt.ptWindowPool.Get(pt.winKeyVal[0], pt.winKeyVal[1]); ok {
   342  			if pt.Dropped() {
   343  				result = v.Move(pt.Point())
   344  			} else {
   345  				result = v.Move(nil)
   346  			}
   347  		}
   348  	}
   349  	return
   350  }
   351  
   352  func (pt *PlPoint) SetIPDB(db ipdb.IPdb) {
   353  	pt.ipdb = db
   354  }
   355  
   356  func (pt *PlPoint) GetIPDB() ipdb.IPdb {
   357  	return pt.ipdb
   358  }
   359  
   360  func (pt *PlPoint) KeyTime2Time() {
   361  	if v, _, err := pt.Get("time"); err == nil {
   362  		if nanots, ok := v.(int64); ok {
   363  			t := time.Unix(nanots/int64(time.Second),
   364  				nanots%int64(time.Second))
   365  			if !t.IsZero() {
   366  				pt.time = t
   367  			}
   368  		}
   369  		pt.Delete("time")
   370  	}
   371  }
   372  
   373  func (pt *PlPoint) MarkDrop(drop bool) {
   374  	pt.drop = drop
   375  }
   376  
   377  func (pt *PlPoint) Dropped() bool {
   378  	return pt.drop
   379  }
   380  
   381  func (pt *PlPoint) Tags() map[string]string {
   382  	return pt.tags
   383  }
   384  
   385  func (pt *PlPoint) Fields() map[string]any {
   386  	return pt.fields
   387  }
   388  
   389  func (pt *PlPoint) Point() *point.Point {
   390  	opt := utils.PtCatOption(pt.category)
   391  	opt = append(opt, point.WithTime(pt.PtTime()))
   392  
   393  	fieldsKVS := point.NewTags(pt.tags)
   394  	fieldsKVS = append(fieldsKVS, point.NewKVs(pt.fields)...)
   395  	return point.NewPointV2(pt.name, fieldsKVS, opt...)
   396  }
   397  
   398  func WrapPoint(cat point.Category, pt *point.Point) PlInputPt {
   399  	if pt == nil {
   400  		return nil
   401  	}
   402  
   403  	return NewPlPoint(cat, pt.Name(),
   404  		pt.MapTags(), pt.InfluxFields(), pt.Time())
   405  }
   406  
   407  func (pt *PlPoint) GetCache() *plcache.Cache {
   408  	return pt.cache
   409  }
   410  
   411  func (pt *PlPoint) SetCache(c *plcache.Cache) {
   412  	pt.cache = c
   413  }