github.com/GuanceCloud/cliutils@v1.1.21/pipeline/ptinput/funcs/fn_adjust_timezone.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/pipeline/ptinput"
    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  const defaultMinuteDelta = int64(2)
    20  
    21  func AdjustTimezoneChecking(ctx *runtime.Task, funcExpr *ast.CallExpr) *errchain.PlError {
    22  	if len(funcExpr.Param) != 1 {
    23  		return runtime.NewRunError(ctx, fmt.Sprintf(
    24  			"func `%s' expected 1 arg", funcExpr.Name),
    25  			funcExpr.NamePos)
    26  	}
    27  
    28  	if _, err := getKeyName(funcExpr.Param[0]); err != nil {
    29  		return runtime.NewRunError(ctx, err.Error(), funcExpr.Param[0].StartPos())
    30  	}
    31  
    32  	return nil
    33  }
    34  
    35  func AdjustTimezone(ctx *runtime.Task, funcExpr *ast.CallExpr) *errchain.PlError {
    36  	key, err := getKeyName(funcExpr.Param[0])
    37  	if err != nil {
    38  		return runtime.NewRunError(ctx, err.Error(), funcExpr.Param[0].StartPos())
    39  	}
    40  
    41  	// 默认允许 +2 分钟误差
    42  	minuteAllow := defaultMinuteDelta
    43  	if len(funcExpr.Param) == 2 {
    44  		switch funcExpr.Param[1].NodeType { //nolint:exhaustive
    45  		case ast.TypeFloatLiteral:
    46  			minuteAllow = int64(funcExpr.Param[1].FloatLiteral().Val)
    47  		case ast.TypeIntegerLiteral:
    48  			minuteAllow = funcExpr.Param[1].IntegerLiteral().Val
    49  		default:
    50  		}
    51  	}
    52  
    53  	if minuteAllow > 15 {
    54  		minuteAllow = 15
    55  	} else if minuteAllow < 0 {
    56  		minuteAllow = 0
    57  	}
    58  
    59  	minuteAllow *= int64(time.Minute)
    60  
    61  	logTS, err := ctx.GetKey(key)
    62  	if err != nil {
    63  		l.Debug(err)
    64  		return nil
    65  	}
    66  
    67  	switch cont := logTS.Value.(type) {
    68  	case int64:
    69  		cont = detectTimezone(cont, time.Now().UnixNano(), minuteAllow)
    70  		_ = addKey2PtWithVal(ctx.InData(), key, cont, ast.Int, ptinput.KindPtDefault)
    71  	default:
    72  		return runtime.NewRunError(ctx, fmt.Sprintf(
    73  			"param value expect int64, got `%s`", reflect.TypeOf(cont)),
    74  			funcExpr.Param[0].StartPos())
    75  	}
    76  
    77  	return nil
    78  }
    79  
    80  func detectTimezone(logTS, nowTS, minuteDuration int64) int64 {
    81  	logTS -= (logTS/int64(time.Hour) - nowTS/int64(time.Hour)) * int64(time.Hour)
    82  
    83  	if logTS-nowTS > minuteDuration {
    84  		logTS -= int64(time.Hour)
    85  	} else if logTS-nowTS <= -int64(time.Hour)+minuteDuration {
    86  		logTS += int64(time.Hour)
    87  	}
    88  
    89  	return logTS
    90  }