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  }