gitee.com/h79/goutils@v1.22.10/perf/perf.go (about)

     1  package perf
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"gitee.com/h79/goutils/alarm"
     7  	"gitee.com/h79/goutils/common/random"
     8  	"gitee.com/h79/goutils/common/result"
     9  	"gitee.com/h79/goutils/common/timer"
    10  	"go.uber.org/zap"
    11  	"path/filepath"
    12  	"runtime"
    13  	"time"
    14  )
    15  
    16  type Config struct {
    17  	DisableLog  bool `json:"disableLog" yaml:"disableLog"`
    18  	DisableWarn bool `json:"disableWarn" yaml:"disableWarn"`
    19  }
    20  
    21  type RunTime struct {
    22  	warn  int64
    23  	start int64
    24  }
    25  
    26  func Begin(warn int64) *RunTime {
    27  	if warn == 0 {
    28  		warn = 3000
    29  	}
    30  	return &RunTime{start: timer.CurrentMS(), warn: warn}
    31  }
    32  
    33  func (t *RunTime) Start() int64 {
    34  	return t.start
    35  }
    36  
    37  func (t *RunTime) End() int64 {
    38  	end := timer.CurrentMS()
    39  	diff := end - t.start
    40  	if diff >= t.warn {
    41  		return diff
    42  	}
    43  	return 0
    44  }
    45  
    46  type Perf struct {
    47  	Config
    48  	id      string
    49  	model   string
    50  	funName string
    51  	file    string
    52  	line    int
    53  	warn    int64
    54  	start   int64
    55  	mid     int64
    56  }
    57  
    58  func (p *Perf) EnableLog(enable bool) *Perf {
    59  	p.DisableLog = !enable
    60  	return p
    61  }
    62  
    63  func (p *Perf) EnableWarn(enable bool) *Perf {
    64  	p.DisableWarn = !enable
    65  	return p
    66  }
    67  
    68  func (p *Perf) WithModel(model string) *Perf {
    69  	p.model = model
    70  	return p
    71  }
    72  
    73  func (p *Perf) WithWarn(t int64) *Perf {
    74  	p.warn = t
    75  	return p
    76  }
    77  
    78  func (p *Perf) WithPerfId(id string) *Perf {
    79  	p.id = id
    80  	return p
    81  }
    82  
    83  func (p *Perf) Start() *Perf {
    84  	p.start = timer.CurrentMS()
    85  	p.mid = p.start
    86  	return p
    87  }
    88  
    89  func (p *Perf) End() {
    90  	end := timer.CurrentMS()
    91  	dif := end - p.start
    92  	p.mid = end
    93  	p.waring(end, dif, "end")
    94  }
    95  
    96  func (p *Perf) Out(detail string) {
    97  	end := timer.CurrentMS()
    98  	dif := end - p.mid
    99  	p.mid = end
   100  	p.waring(end, dif, detail)
   101  }
   102  
   103  func (p *Perf) log(end, dif int64, detail string) {
   104  	zap.L().WithOptions(zap.AddCallerSkip(2)).Debug("Perf",
   105  		zap.String("perfId", p.id),
   106  		zap.String("model", p.model),
   107  		zap.String("detail", detail),
   108  		zap.Int64("start", p.start),
   109  		zap.Int64("end", end),
   110  		zap.Duration("dif", time.Duration(dif)*time.Millisecond),
   111  		zap.String("func", p.funName),
   112  		zap.String("file", p.file),
   113  		zap.Int("line", p.line))
   114  }
   115  
   116  func (p *Perf) waring(end, dif int64, detail string) {
   117  	//执行时间太长,告警
   118  	wa := p.warn
   119  	if wa <= 0 {
   120  		wa = 2000
   121  	}
   122  	if p.DisableWarn {
   123  		if !p.DisableLog {
   124  			p.log(end, dif, detail)
   125  		}
   126  		return
   127  	}
   128  	if dif >= p.warn+1000 {
   129  		p.log(end, dif, detail)
   130  		alarm.Tight(context.Background(), result.ErrTimeout,
   131  			"perf", "",
   132  			fmt.Sprintf("%s, detail=> '%s', run time too long=> %dms, start=> %d,end=> %d", p.info(), detail, dif, p.start, end), nil)
   133  	} else if dif >= p.warn {
   134  		p.log(end, dif, detail)
   135  		alarm.Important(context.Background(), result.ErrTimeout,
   136  			"perf", "",
   137  			fmt.Sprintf("%s, detail=> '%s', run time too long=> %dms,start=> %d,end=> %d", p.info(), detail, dif, p.start, end), nil)
   138  	}
   139  }
   140  
   141  func (p *Perf) info() string {
   142  	return fmt.Sprintf("perfId: '%s', model: '%s',funcName: '%s', fileName: '%s', line: %d",
   143  		p.id, p.model, p.funName, p.file, p.line)
   144  }
   145  
   146  // T OWNER
   147  func T() *Perf {
   148  	pc, file, line, _ := runtime.Caller(1)
   149  	return &Perf{
   150  		id:      random.GenerateNumString(16),
   151  		model:   "",
   152  		warn:    2000,
   153  		funName: filepath.Base(runtime.FuncForPC(pc).Name()),
   154  		file:    filepath.Base(file),
   155  		line:    line,
   156  	}
   157  }
   158  
   159  // C caller
   160  func C() *Perf {
   161  	pc, file, line, _ := runtime.Caller(2)
   162  	return &Perf{
   163  		id:      random.GenerateNumString(16),
   164  		model:   "",
   165  		warn:    2000,
   166  		funName: filepath.Base(runtime.FuncForPC(pc).Name()),
   167  		file:    filepath.Base(file),
   168  		line:    line,
   169  	}
   170  }