exit.go 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. // Go support for leveled logs, analogous to https://code.google.com/p/google-glog/
  2. //
  3. // Copyright 2013 Google Inc. All Rights Reserved.
  4. // Copyright 2022 The Kubernetes Authors.
  5. //
  6. // Licensed under the Apache License, Version 2.0 (the "License");
  7. // you may not use this file except in compliance with the License.
  8. // You may obtain a copy of the License at
  9. //
  10. // http://www.apache.org/licenses/LICENSE-2.0
  11. //
  12. // Unless required by applicable law or agreed to in writing, software
  13. // distributed under the License is distributed on an "AS IS" BASIS,
  14. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. // See the License for the specific language governing permissions and
  16. // limitations under the License.
  17. package klog
  18. import (
  19. "fmt"
  20. "os"
  21. "time"
  22. )
  23. var (
  24. // ExitFlushTimeout is the timeout that klog has traditionally used during
  25. // calls like Fatal or Exit when flushing log data right before exiting.
  26. // Applications that replace those calls and do not have some specific
  27. // requirements like "exit immediately" can use this value as parameter
  28. // for FlushAndExit.
  29. //
  30. // Can be set for testing purpose or to change the application's
  31. // default.
  32. ExitFlushTimeout = 10 * time.Second
  33. // OsExit is the function called by FlushAndExit to terminate the program.
  34. //
  35. // Can be set for testing purpose or to change the application's
  36. // default behavior. Note that the function should not simply return
  37. // because callers of functions like Fatal will not expect that.
  38. OsExit = os.Exit
  39. )
  40. // FlushAndExit flushes log data for a certain amount of time and then calls
  41. // os.Exit. Combined with some logging call it provides a replacement for
  42. // traditional calls like Fatal or Exit.
  43. func FlushAndExit(flushTimeout time.Duration, exitCode int) {
  44. timeoutFlush(flushTimeout)
  45. OsExit(exitCode)
  46. }
  47. // timeoutFlush calls Flush and returns when it completes or after timeout
  48. // elapses, whichever happens first. This is needed because the hooks invoked
  49. // by Flush may deadlock when klog.Fatal is called from a hook that holds
  50. // a lock. Flushing also might take too long.
  51. func timeoutFlush(timeout time.Duration) {
  52. done := make(chan bool, 1)
  53. go func() {
  54. Flush() // calls logging.lockAndFlushAll()
  55. done <- true
  56. }()
  57. select {
  58. case <-done:
  59. case <-time.After(timeout):
  60. fmt.Fprintln(os.Stderr, "klog: Flush took longer than", timeout)
  61. }
  62. }