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 }