|
7 | 7 | "runtime" |
8 | 8 | "strconv" |
9 | 9 | "strings" |
| 10 | + "sync/atomic" |
10 | 11 | "time" |
11 | 12 |
|
12 | 13 | log "github.com/InjectiveLabs/suplog" |
@@ -165,26 +166,28 @@ func reportTiming(ctx context.Context, fn string, tags ...Tags) (context.Context |
165 | 166 | tagArray = append(tagArray, getSingleTag("func_name", fn)) |
166 | 167 |
|
167 | 168 | doneC := make(chan struct{}) |
168 | | - go func(name string, start time.Time) { |
169 | | - timeout := time.NewTimer(config.StuckFunctionTimeout) |
170 | | - defer timeout.Stop() |
171 | | - |
172 | | - select { |
173 | | - case <-doneC: |
174 | | - return |
175 | | - case <-timeout.C: |
176 | | - clientMux.RLock() |
177 | | - defer clientMux.RUnlock() |
178 | | - |
179 | | - err := fmt.Errorf("detected stuck function: %s stuck for %v", name, time.Since(start)) |
180 | | - fmt.Println(err) |
181 | | - client.Incr("func.stuck", tagArray, 1) |
182 | | - if span != nil { |
183 | | - span.SetStatus(codes.Error, "stuck") |
184 | | - span.End() |
| 169 | + if !disableStuckFuncReport.Load() { |
| 170 | + go func(name string, start time.Time) { |
| 171 | + timeout := time.NewTimer(config.StuckFunctionTimeout) |
| 172 | + defer timeout.Stop() |
| 173 | + |
| 174 | + select { |
| 175 | + case <-doneC: |
| 176 | + return |
| 177 | + case <-timeout.C: |
| 178 | + clientMux.RLock() |
| 179 | + defer clientMux.RUnlock() |
| 180 | + |
| 181 | + err := fmt.Errorf("detected stuck function: %s stuck for %v", name, time.Since(start)) |
| 182 | + fmt.Println(err) |
| 183 | + client.Incr("func.stuck", tagArray, 1) |
| 184 | + if span != nil { |
| 185 | + span.SetStatus(codes.Error, "stuck") |
| 186 | + span.End() |
| 187 | + } |
185 | 188 | } |
186 | | - } |
187 | | - }(fn, t) |
| 189 | + }(fn, t) |
| 190 | + } |
188 | 191 |
|
189 | 192 | return spanCtx, func(stopTags ...Tags) { |
190 | 193 | d := time.Since(t) |
@@ -212,21 +215,24 @@ func ReportClosureFuncTiming(name string, tags ...Tags) StopTimerFunc { |
212 | 215 | tagArray = append(tagArray, getSingleTag("func_name", name)) |
213 | 216 |
|
214 | 217 | doneC := make(chan struct{}) |
215 | | - go func(name string, start time.Time) { |
216 | | - timeout := time.NewTimer(config.StuckFunctionTimeout) |
217 | | - defer timeout.Stop() |
218 | | - |
219 | | - select { |
220 | | - case <-doneC: |
221 | | - return |
222 | | - case <-timeout.C: |
223 | | - clientMux.RLock() |
224 | | - defer clientMux.RUnlock() |
225 | | - |
226 | | - log.Warningf("detected stuck function: %s stuck for %v", name, time.Since(start)) |
227 | | - client.Incr("func.stuck", tagArray, 1) |
228 | | - } |
229 | | - }(name, t) |
| 218 | + |
| 219 | + if !disableStuckFuncReport.Load() { |
| 220 | + go func(name string, start time.Time) { |
| 221 | + timeout := time.NewTimer(config.StuckFunctionTimeout) |
| 222 | + defer timeout.Stop() |
| 223 | + |
| 224 | + select { |
| 225 | + case <-doneC: |
| 226 | + return |
| 227 | + case <-timeout.C: |
| 228 | + clientMux.RLock() |
| 229 | + defer clientMux.RUnlock() |
| 230 | + |
| 231 | + log.Warningf("detected stuck function: %s stuck for %v", name, time.Since(start)) |
| 232 | + client.Incr("func.stuck", tagArray, 1) |
| 233 | + } |
| 234 | + }(name, t) |
| 235 | + } |
230 | 236 |
|
231 | 237 | return func(stopTags ...Tags) { |
232 | 238 | d := time.Since(t) |
@@ -432,65 +438,108 @@ func ToString(i interface{}) (v string, ok bool) { |
432 | 438 | case float64: |
433 | 439 | v = strconv.FormatFloat(x, 'f', -1, 64) |
434 | 440 | case *string: |
435 | | - if x != nil { |
| 441 | + if x == nil { |
| 442 | + v = "nil" |
| 443 | + } else { |
436 | 444 | v = *x |
437 | 445 | } |
438 | 446 | case *int: |
439 | | - if x != nil { |
| 447 | + if x == nil { |
| 448 | + v = "nil" |
| 449 | + } else { |
440 | 450 | v = strconv.FormatInt(int64(*x), 10) |
441 | 451 | } |
442 | 452 | case *int8: |
443 | | - if x != nil { |
| 453 | + if x == nil { |
| 454 | + v = "nil" |
| 455 | + } else { |
444 | 456 | v = strconv.FormatInt(int64(*x), 10) |
445 | 457 | } |
446 | 458 | case *int16: |
447 | | - if x != nil { |
| 459 | + if x == nil { |
| 460 | + v = "nil" |
| 461 | + } else { |
448 | 462 | v = strconv.FormatInt(int64(*x), 10) |
449 | 463 | } |
450 | 464 | case *int32: |
451 | | - if x != nil { |
| 465 | + if x == nil { |
| 466 | + v = "nil" |
| 467 | + } else { |
452 | 468 | v = strconv.FormatInt(int64(*x), 10) |
453 | 469 | } |
454 | 470 | case *int64: |
455 | | - if x != nil { |
| 471 | + if x == nil { |
| 472 | + v = "nil" |
| 473 | + } else { |
456 | 474 | v = strconv.FormatInt(*x, 10) |
457 | 475 | } |
458 | 476 | case *uint: |
459 | | - if x != nil { |
| 477 | + if x == nil { |
| 478 | + v = "nil" |
| 479 | + } else { |
460 | 480 | v = strconv.FormatUint(uint64(*x), 10) |
461 | 481 | } |
462 | 482 | case *uint8: |
463 | | - if x != nil { |
| 483 | + if x == nil { |
| 484 | + v = "nil" |
| 485 | + } else { |
464 | 486 | v = strconv.FormatUint(uint64(*x), 10) |
465 | 487 | } |
466 | 488 | case *uint16: |
467 | | - if x != nil { |
| 489 | + if x == nil { |
| 490 | + v = "nil" |
| 491 | + } else { |
468 | 492 | v = strconv.FormatUint(uint64(*x), 10) |
469 | 493 | } |
470 | 494 | case *uint32: |
471 | | - if x != nil { |
| 495 | + if x == nil { |
| 496 | + v = "nil" |
| 497 | + } else { |
472 | 498 | v = strconv.FormatUint(uint64(*x), 10) |
473 | 499 | } |
474 | 500 | case *uint64: |
475 | | - if x != nil { |
| 501 | + if x == nil { |
| 502 | + v = "nil" |
| 503 | + } else { |
476 | 504 | v = strconv.FormatUint(*x, 10) |
477 | 505 | } |
478 | 506 | case *float32: |
479 | | - if x != nil { |
| 507 | + if x == nil { |
| 508 | + v = "nil" |
| 509 | + } else { |
480 | 510 | v = strconv.FormatFloat(float64(*x), 'f', -1, 32) |
481 | 511 | } |
482 | 512 | case *float64: |
483 | | - if x != nil { |
| 513 | + if x == nil { |
| 514 | + v = "nil" |
| 515 | + } else { |
484 | 516 | v = strconv.FormatFloat(*x, 'f', -1, 64) |
485 | 517 | } |
486 | 518 | case bool: |
487 | 519 | v = strconv.FormatBool(x) |
488 | 520 | case *bool: |
489 | | - v = strconv.FormatBool(*x) |
| 521 | + if x == nil { |
| 522 | + v = "nil" |
| 523 | + } else { |
| 524 | + v = strconv.FormatBool(*x) |
| 525 | + } |
| 526 | + case fmt.Stringer: |
| 527 | + rv := reflect.ValueOf(x) |
| 528 | + if rv.Kind() == reflect.Ptr && rv.IsNil() { |
| 529 | + v = "nil" |
| 530 | + } else { |
| 531 | + v = x.String() |
| 532 | + } |
490 | 533 | case nil: |
491 | 534 | v = "nil" |
492 | 535 | default: |
493 | 536 | ok = false |
494 | 537 | } |
495 | 538 | return v, ok |
496 | 539 | } |
| 540 | + |
| 541 | +var disableStuckFuncReport atomic.Bool |
| 542 | + |
| 543 | +func DisableStuckFuncReport() { |
| 544 | + disableStuckFuncReport.Store(true) |
| 545 | +} |
0 commit comments