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 }