github.com/GuanceCloud/cliutils@v1.1.21/pipeline/ptinput/funcs/fn_agg.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 funcs 7 8 import ( 9 "fmt" 10 "reflect" 11 "time" 12 13 "github.com/GuanceCloud/cliutils/point" 14 "github.com/GuanceCloud/platypus/pkg/ast" 15 "github.com/GuanceCloud/platypus/pkg/engine/runtime" 16 "github.com/GuanceCloud/platypus/pkg/errchain" 17 ) 18 19 func AggCreateChecking(ctx *runtime.Task, funcExpr *ast.CallExpr) *errchain.PlError { 20 if err := normalizeFuncArgsDeprecated(funcExpr, []string{ 21 "bucket", "on_interval", "on_count", 22 "keep_value", "const_tags", "category", 23 }, 1); err != nil { 24 return runtime.NewRunError(ctx, err.Error(), funcExpr.NamePos) 25 } 26 27 arg := funcExpr.Param[0] 28 switch arg.NodeType { //nolint:exhaustive 29 case ast.TypeStringLiteral: 30 default: 31 return runtime.NewRunError(ctx, fmt.Sprintf("param `bucket` expect StringLiteral, got %s", 32 arg.NodeType), arg.StartPos()) 33 } 34 35 interval := time.Minute 36 if arg := funcExpr.Param[1]; arg != nil { 37 switch arg.NodeType { //nolint:exhaustive 38 case ast.TypeStringLiteral: 39 ts := arg.StringLiteral().Val 40 if v, err := time.ParseDuration(ts); err != nil { 41 return runtime.NewRunError(ctx, fmt.Sprintf("parse on_interval: %s", err.Error()), 42 arg.StartPos()) 43 } else { 44 interval = v 45 } 46 default: 47 return runtime.NewRunError(ctx, fmt.Sprintf("param `on_interval` expect StringLiteral, got %s", 48 arg.NodeType), arg.StartPos()) 49 } 50 } 51 52 count := 0 53 if arg := funcExpr.Param[2]; arg != nil { 54 switch arg.NodeType { //nolint:exhaustive 55 case ast.TypeIntegerLiteral: 56 count = int(arg.IntegerLiteral().Val) 57 default: 58 return runtime.NewRunError(ctx, fmt.Sprintf("param `on_count` expect IntegerLiteral, got %s", 59 arg.NodeType), arg.StartPos()) 60 } 61 } 62 63 if interval <= 0 && count <= 0 { 64 return runtime.NewRunError(ctx, 65 "param `on_interval` and `on_count` cannot be less than or equal to 0 at the same time", arg.StartPos()) 66 } 67 68 if arg := funcExpr.Param[3]; arg != nil { 69 switch arg.NodeType { //nolint:exhaustive 70 case ast.TypeBoolLiteral: 71 default: 72 return runtime.NewRunError(ctx, fmt.Sprintf("param `keep_value` expect BoolLiteral, got %s", 73 arg.NodeType), arg.StartPos()) 74 } 75 } 76 77 return nil 78 } 79 80 func AggCreate(ctx *runtime.Task, funcExpr *ast.CallExpr) *errchain.PlError { 81 pt, err := getPoint(ctx.InData()) 82 if err != nil { 83 return nil 84 } 85 86 buks := pt.GetAggBuckets() 87 if buks == nil { 88 return nil 89 } 90 91 ptCat := point.Metric 92 if arg := funcExpr.Param[5]; arg != nil { 93 if catName, _, err := runtime.RunStmt(ctx, arg); err != nil { 94 return nil 95 } else if catName != nil { 96 if catN, ok := catName.(string); ok { 97 ptCat = ptCategory(catN) 98 if ptCat == point.UnknownCategory { 99 return nil 100 } 101 } else { 102 return runtime.NewRunError(ctx, fmt.Sprintf( 103 "type of parameter expected to be int64, got %s", 104 reflect.TypeOf(catName)), arg.StartPos()) 105 } 106 } 107 } 108 109 bukName := funcExpr.Param[0].StringLiteral().Val 110 if _, ok := buks.GetBucket(ptCat, bukName); ok { 111 return nil 112 } 113 114 interval := time.Minute 115 count := 0 116 keepValue := false 117 118 if arg := funcExpr.Param[1]; arg != nil { 119 interval, _ = time.ParseDuration(arg.StringLiteral().Val) 120 } 121 122 if arg := funcExpr.Param[2]; arg != nil { 123 count = int(arg.IntegerLiteral().Val) 124 } 125 126 if arg := funcExpr.Param[3]; arg != nil { 127 keepValue = arg.BoolLiteral().Val 128 } 129 130 constTags := map[string]string{} 131 if arg := funcExpr.Param[4]; arg != nil { 132 if v, _, err := runtime.RunStmt(ctx, arg); err == nil { 133 if v, ok := v.(map[string]any); ok { 134 for k, v := range v { 135 if v, ok := v.(string); ok { 136 constTags[k] = v 137 } 138 } 139 } 140 } 141 } 142 143 buks.CreateBucket(ptCat, bukName, interval, count, keepValue, constTags) 144 145 return nil 146 } 147 148 func AggAddMetricChecking(ctx *runtime.Task, funcExpr *ast.CallExpr) *errchain.PlError { 149 if err := normalizeFuncArgsDeprecated(funcExpr, []string{ 150 "bucket", "new_field", "agg_fn", 151 "agg_by", "agg_field", "category", 152 }, 5); err != nil { 153 return runtime.NewRunError(ctx, err.Error(), funcExpr.NamePos) 154 } 155 156 arg1 := funcExpr.Param[0] 157 switch arg1.NodeType { //nolint:exhaustive 158 case ast.TypeStringLiteral: 159 default: 160 return runtime.NewRunError(ctx, fmt.Sprintf("param `bucket` expect StringLiteral, got %s", 161 arg1.NodeType), arg1.StartPos()) 162 } 163 164 arg2 := funcExpr.Param[1] 165 switch arg2.NodeType { //nolint:exhaustive 166 case ast.TypeStringLiteral: 167 default: 168 return runtime.NewRunError(ctx, fmt.Sprintf("param `new_field` expect StringLiteral, got %s", 169 arg2.NodeType), arg2.StartPos()) 170 } 171 172 arg3 := funcExpr.Param[2] 173 switch arg3.NodeType { //nolint:exhaustive 174 case ast.TypeStringLiteral: 175 default: 176 return runtime.NewRunError(ctx, fmt.Sprintf("param `agg_fn` expect StringLiteral, got %s", 177 arg3.NodeType), arg3.StartPos()) 178 } 179 180 var tags []string 181 arg4 := funcExpr.Param[3] 182 switch arg4.NodeType { //nolint:exhaustive 183 case ast.TypeListLiteral: 184 for _, v := range arg4.ListLiteral().List { 185 switch v.NodeType { //nolint:exhaustive 186 case ast.TypeStringLiteral: 187 tags = append(tags, v.StringLiteral().Val) 188 default: 189 return runtime.NewRunError(ctx, fmt.Sprintf("agg_by elem expect StringLiteral, got %s", 190 arg4.NodeType), arg4.StartPos()) 191 } 192 } 193 default: 194 return runtime.NewRunError(ctx, fmt.Sprintf("param `agg_by` expect StringLiteral, got %s", 195 arg4.NodeType), arg4.StartPos()) 196 } 197 198 if len(tags) == 0 { 199 return runtime.NewRunError(ctx, "size of param `agg_by` is 0", arg4.StartPos()) 200 } 201 202 funcExpr.PrivateData = tags 203 204 arg5 := funcExpr.Param[4] 205 switch arg5.NodeType { //nolint:exhaustive 206 case ast.TypeStringLiteral: 207 default: 208 return runtime.NewRunError(ctx, fmt.Sprintf("param `agg_field` expect StringLiteral, got %s", 209 arg5.NodeType), arg5.StartPos()) 210 } 211 212 return nil 213 } 214 215 func AggAddMetric(ctx *runtime.Task, funcExpr *ast.CallExpr) *errchain.PlError { 216 pt, err := getPoint(ctx.InData()) 217 if err != nil { 218 return nil 219 } 220 221 buks := pt.GetAggBuckets() 222 if buks == nil { 223 return nil 224 } 225 226 bukName := funcExpr.Param[0].StringLiteral().Val 227 newField := funcExpr.Param[1].StringLiteral().Val 228 aggFn := funcExpr.Param[2].StringLiteral().Val 229 230 aggBy, ok := funcExpr.PrivateData.([]string) 231 if !ok { 232 return nil 233 } 234 235 ptCat := point.Metric 236 if arg := funcExpr.Param[5]; arg != nil { 237 if catName, _, err := runtime.RunStmt(ctx, arg); err != nil { 238 return nil 239 } else if catName != nil { 240 if catN, ok := catName.(string); ok { 241 ptCat = ptCategory(catN) 242 if ptCat == point.UnknownCategory { 243 return nil 244 } 245 } else { 246 return runtime.NewRunError(ctx, fmt.Sprintf( 247 "type of parameter expected to be int64, got %s", 248 reflect.TypeOf(catName)), arg.StartPos()) 249 } 250 } 251 } 252 253 byValue := []string{} 254 for _, by := range aggBy { 255 if v, err := ctx.GetKey(by); err != nil { 256 return nil 257 } else { 258 if v, ok := v.Value.(string); ok { 259 byValue = append(byValue, v) 260 } else { 261 return nil 262 } 263 } 264 } 265 266 if len(aggBy) != len(byValue) { 267 return nil 268 } 269 270 aggField := funcExpr.Param[4].StringLiteral().Val 271 272 fieldValue, err := ctx.GetKey(aggField) 273 if err != nil { 274 return nil 275 } 276 277 buk, ok := buks.GetBucket(ptCat, bukName) 278 if !ok { 279 return nil 280 } 281 282 buk.AddMetric(newField, aggFn, aggBy, byValue, fieldValue.Value) 283 284 return nil 285 }