github.com/songzhibin97/gkit@v1.2.13/watching/option.go (about)

     1  package watching
     2  
     3  import (
     4  	"os"
     5  	"path"
     6  	"path/filepath"
     7  	"sync/atomic"
     8  	"time"
     9  	"unsafe"
    10  
    11  	"github.com/docker/go-units"
    12  	"github.com/songzhibin97/gkit/options"
    13  )
    14  
    15  // WithCollectInterval : interval must be valid time duration string,
    16  // eg. "ns", "us" (or "µs"), "ms", "s", "m", "h".
    17  func WithCollectInterval(interval string) options.Option {
    18  	return func(o interface{}) {
    19  		opts := o.(*Watching)
    20  		var err error
    21  		// CollectInterval wouldn't be zero value, because it
    22  		// will be initialized as defaultInterval at newOptions()
    23  		newInterval, err := time.ParseDuration(interval)
    24  		if err != nil || opts.config.CollectInterval.Seconds() == newInterval.Seconds() {
    25  			return
    26  		}
    27  		opts.config.CollectInterval = newInterval
    28  		opts.config.intervalResetting <- struct{}{}
    29  		return
    30  	}
    31  }
    32  
    33  // WithCoolDown : coolDown must be valid time duration string,
    34  // eg. "ns", "us" (or "µs"), "ms", "s", "m", "h".
    35  func WithCoolDown(coolDown string) options.Option {
    36  	return func(o interface{}) {
    37  		opts := o.(*Watching)
    38  		var err error
    39  		opts.config.CoolDown, err = time.ParseDuration(coolDown)
    40  		if err != nil {
    41  			panic(err)
    42  		}
    43  		return
    44  	}
    45  }
    46  
    47  // WithCPUMax : set the CPUMaxPercent parameter as max
    48  func WithCPUMax(max int) options.Option {
    49  	return func(o interface{}) {
    50  		opts := o.(*Watching)
    51  		opts.config.CPUMaxPercent = max
    52  	}
    53  }
    54  
    55  // WithDumpPath set the dump path for Watching.
    56  func WithDumpPath(dumpPath string, loginfo ...string) options.Option {
    57  	return func(o interface{}) {
    58  		opts := o.(*Watching)
    59  		var err error
    60  		var logger *os.File
    61  		f := path.Join(dumpPath, defaultLoggerName)
    62  		if len(loginfo) > 0 {
    63  			f = dumpPath + "/" + path.Join(loginfo...)
    64  		}
    65  		opts.config.DumpPath = filepath.Dir(f)
    66  		logger, err = os.OpenFile(f, defaultLoggerFlags, defaultLoggerPerm)
    67  		if err != nil && os.IsNotExist(err) {
    68  			if err = os.MkdirAll(opts.config.DumpPath, 0o755); err != nil {
    69  				return
    70  			}
    71  			logger, err = os.OpenFile(f, defaultLoggerFlags, defaultLoggerPerm)
    72  			if err != nil {
    73  				return
    74  			}
    75  		}
    76  		old := opts.config.Logger
    77  		if atomic.CompareAndSwapPointer((*unsafe.Pointer)(unsafe.Pointer(&opts.config.Logger)), unsafe.Pointer(opts.config.Logger), unsafe.Pointer(logger)) {
    78  			if old != os.Stdout {
    79  				_ = old.Close()
    80  			}
    81  		}
    82  		return
    83  	}
    84  }
    85  
    86  // WithBinaryDump set dump mode to binary.
    87  func WithBinaryDump() options.Option {
    88  	return withDumpProfileType(binaryDump)
    89  }
    90  
    91  // WithTextDump set dump mode to text.
    92  func WithTextDump() options.Option {
    93  	return withDumpProfileType(textDump)
    94  }
    95  
    96  // WithFullStack set to dump full stack or top 10 stack, when dump in text mode.
    97  func WithFullStack(isFull bool) options.Option {
    98  	return func(o interface{}) {
    99  		opts := o.(*Watching)
   100  		opts.config.DumpFullStack = isFull
   101  		return
   102  	}
   103  }
   104  
   105  func withDumpProfileType(profileType dumpProfileType) options.Option {
   106  	return func(o interface{}) {
   107  		opts := o.(*Watching)
   108  		opts.config.DumpProfileType = profileType
   109  		return
   110  	}
   111  }
   112  
   113  // WithLoggerSplit set the split log options.
   114  // eg. "b/B", "k/K" "kb/Kb" "mb/Mb", "gb/Gb" "tb/Tb" "pb/Pb".
   115  func WithLoggerSplit(enable bool, shardLoggerSize string) options.Option {
   116  	return func(o interface{}) {
   117  		opts := o.(*Watching)
   118  		opts.config.logConfigs.RotateEnable = enable
   119  		if !enable {
   120  			return
   121  		}
   122  
   123  		parseShardLoggerSize, err := units.FromHumanSize(shardLoggerSize)
   124  		if err != nil {
   125  			panic(err)
   126  		}
   127  		if parseShardLoggerSize <= 0 {
   128  			opts.config.logConfigs.SplitLoggerSize = defaultShardLoggerSize
   129  			return
   130  		}
   131  		opts.config.logConfigs.SplitLoggerSize = parseShardLoggerSize
   132  		return
   133  	}
   134  }
   135  
   136  // WithGoroutineDump set the goroutine dump options.
   137  func WithGoroutineDump(min int, diff int, abs int, max int) options.Option {
   138  	return func(o interface{}) {
   139  		opts := o.(*Watching)
   140  		opts.config.GroupConfigs.TriggerMin = min
   141  		opts.config.GroupConfigs.TriggerDiff = diff
   142  		opts.config.GroupConfigs.TriggerAbs = abs
   143  		opts.config.GroupConfigs.GoroutineTriggerNumMax = max
   144  		return
   145  	}
   146  }
   147  
   148  // WithMemDump set the memory dump options.
   149  func WithMemDump(min int, diff int, abs int) options.Option {
   150  	return func(o interface{}) {
   151  		opts := o.(*Watching)
   152  		opts.config.MemConfigs.TriggerMin = min
   153  		opts.config.MemConfigs.TriggerDiff = diff
   154  		opts.config.MemConfigs.TriggerAbs = abs
   155  	}
   156  }
   157  
   158  // WithCPUDump set the cpu dump options.
   159  func WithCPUDump(min int, diff int, abs int) options.Option {
   160  	return func(o interface{}) {
   161  		opts := o.(*Watching)
   162  		opts.config.CpuConfigs.TriggerMin = min
   163  		opts.config.CpuConfigs.TriggerDiff = diff
   164  		opts.config.CpuConfigs.TriggerAbs = abs
   165  		return
   166  	}
   167  }
   168  
   169  // WithGoProcAsCPUCore set Watching use cgroup or not.
   170  func WithGoProcAsCPUCore(enabled bool) options.Option {
   171  	return func(o interface{}) {
   172  		opts := o.(*Watching)
   173  		opts.config.UseGoProcAsCPUCore = enabled
   174  		return
   175  	}
   176  }
   177  
   178  // WithThreadDump set the thread dump options.
   179  func WithThreadDump(min, diff, abs int) options.Option {
   180  	return func(o interface{}) {
   181  		opts := o.(*Watching)
   182  		opts.config.ThreadConfigs.TriggerMin = min
   183  		opts.config.ThreadConfigs.TriggerDiff = diff
   184  		opts.config.ThreadConfigs.TriggerAbs = abs
   185  		return
   186  	}
   187  }
   188  
   189  // WithLoggerLevel set logger level
   190  func WithLoggerLevel(level int) options.Option {
   191  	return func(o interface{}) {
   192  		opts := o.(*Watching)
   193  		opts.config.LogLevel = level
   194  		return
   195  	}
   196  }
   197  
   198  // WithCGroup set Watching use cgroup or not.
   199  func WithCGroup(useCGroup bool) options.Option {
   200  	return func(o interface{}) {
   201  		opts := o.(*Watching)
   202  		opts.config.UseCGroup = useCGroup
   203  		return
   204  	}
   205  }
   206  
   207  // WithGCHeapDump set the GC heap dump options.
   208  func WithGCHeapDump(min int, diff int, abs int) options.Option {
   209  	return func(o interface{}) {
   210  		opts := o.(*Watching)
   211  		opts.config.GCHeapConfigs.TriggerMin = min
   212  		opts.config.GCHeapConfigs.TriggerDiff = diff
   213  		opts.config.GCHeapConfigs.TriggerAbs = abs
   214  		return
   215  	}
   216  }
   217  
   218  // WithCPUCore overwrite the system level CPU core number when it > 0.
   219  // it's not a good idea to modify it on fly since it affects the CPU percent caculation.
   220  func WithCPUCore(cpuCore float64) options.Option {
   221  	return func(o interface{}) {
   222  		opts := o.(*Watching)
   223  		opts.config.cpuCore = cpuCore
   224  		return
   225  	}
   226  }
   227  
   228  // WithMemoryLimit overwrite the system level memory limit when it > 0.
   229  func WithMemoryLimit(limit uint64) options.Option {
   230  	return func(o interface{}) {
   231  		opts := o.(*Watching)
   232  		opts.config.memoryLimit = limit
   233  		return
   234  	}
   235  }
   236  
   237  // WithShrinkThread enable/disable shrink thread when the thread number exceed the max threshold.
   238  func WithShrinkThread(enable bool, threshold int, delay time.Duration) options.Option {
   239  	return func(o interface{}) {
   240  		opts := o.(*Watching)
   241  		opts.config.ShrinkThrConfigs.Enable = enable
   242  		if threshold > 0 {
   243  			opts.config.ShrinkThrConfigs.Threshold = threshold
   244  		}
   245  		opts.config.ShrinkThrConfigs.Delay = delay
   246  		return
   247  	}
   248  }
   249  
   250  // WithProfileReporter will enable reporter
   251  // reopens profile reporter through WithProfileReporter(h.opts.rptOpts.reporter)
   252  func WithProfileReporter(r ProfileReporter) options.Option {
   253  	return func(o interface{}) {
   254  		opts := o.(*Watching)
   255  		if r == nil {
   256  			return
   257  		}
   258  
   259  		opts.config.rptConfigs.reporter = r
   260  		atomic.StoreInt32(&opts.config.rptConfigs.active, 1)
   261  		return
   262  	}
   263  }