options.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. package logger
  2. import (
  3. "os"
  4. "path/filepath"
  5. "strings"
  6. "time"
  7. )
  8. const (
  9. // DefaultContainerLogPath 为容器内默认日志文件路径。
  10. DefaultContainerLogPath = "/app/data/logs/sub2api.log"
  11. defaultLogFilename = "sub2api.log"
  12. )
  13. type InitOptions struct {
  14. Level string
  15. Format string
  16. ServiceName string
  17. Environment string
  18. Caller bool
  19. StacktraceLevel string
  20. Output OutputOptions
  21. Rotation RotationOptions
  22. Sampling SamplingOptions
  23. }
  24. type OutputOptions struct {
  25. ToStdout bool
  26. ToFile bool
  27. FilePath string
  28. }
  29. type RotationOptions struct {
  30. MaxSizeMB int
  31. MaxBackups int
  32. MaxAgeDays int
  33. Compress bool
  34. LocalTime bool
  35. }
  36. type SamplingOptions struct {
  37. Enabled bool
  38. Initial int
  39. Thereafter int
  40. }
  41. func (o InitOptions) normalized() InitOptions {
  42. out := o
  43. out.Level = strings.ToLower(strings.TrimSpace(out.Level))
  44. if out.Level == "" {
  45. out.Level = "info"
  46. }
  47. out.Format = strings.ToLower(strings.TrimSpace(out.Format))
  48. if out.Format == "" {
  49. out.Format = "console"
  50. }
  51. out.ServiceName = strings.TrimSpace(out.ServiceName)
  52. if out.ServiceName == "" {
  53. out.ServiceName = "sub2api"
  54. }
  55. out.Environment = strings.TrimSpace(out.Environment)
  56. if out.Environment == "" {
  57. out.Environment = "production"
  58. }
  59. out.StacktraceLevel = strings.ToLower(strings.TrimSpace(out.StacktraceLevel))
  60. if out.StacktraceLevel == "" {
  61. out.StacktraceLevel = "error"
  62. }
  63. if !out.Output.ToStdout && !out.Output.ToFile {
  64. out.Output.ToStdout = true
  65. }
  66. out.Output.FilePath = resolveLogFilePath(out.Output.FilePath)
  67. if out.Rotation.MaxSizeMB <= 0 {
  68. out.Rotation.MaxSizeMB = 100
  69. }
  70. if out.Rotation.MaxBackups < 0 {
  71. out.Rotation.MaxBackups = 10
  72. }
  73. if out.Rotation.MaxAgeDays < 0 {
  74. out.Rotation.MaxAgeDays = 7
  75. }
  76. if out.Sampling.Enabled {
  77. if out.Sampling.Initial <= 0 {
  78. out.Sampling.Initial = 100
  79. }
  80. if out.Sampling.Thereafter <= 0 {
  81. out.Sampling.Thereafter = 100
  82. }
  83. }
  84. return out
  85. }
  86. func resolveLogFilePath(explicit string) string {
  87. explicit = strings.TrimSpace(explicit)
  88. if explicit != "" {
  89. return explicit
  90. }
  91. dataDir := strings.TrimSpace(os.Getenv("DATA_DIR"))
  92. if dataDir != "" {
  93. return filepath.Join(dataDir, "logs", defaultLogFilename)
  94. }
  95. return DefaultContainerLogPath
  96. }
  97. func bootstrapOptions() InitOptions {
  98. return InitOptions{
  99. Level: "info",
  100. Format: "console",
  101. ServiceName: "sub2api",
  102. Environment: "bootstrap",
  103. Output: OutputOptions{
  104. ToStdout: true,
  105. ToFile: false,
  106. },
  107. Rotation: RotationOptions{
  108. MaxSizeMB: 100,
  109. MaxBackups: 10,
  110. MaxAgeDays: 7,
  111. Compress: true,
  112. LocalTime: true,
  113. },
  114. Sampling: SamplingOptions{
  115. Enabled: false,
  116. Initial: 100,
  117. Thereafter: 100,
  118. },
  119. }
  120. }
  121. func parseLevel(level string) (Level, bool) {
  122. switch strings.ToLower(strings.TrimSpace(level)) {
  123. case "debug":
  124. return LevelDebug, true
  125. case "info":
  126. return LevelInfo, true
  127. case "warn":
  128. return LevelWarn, true
  129. case "error":
  130. return LevelError, true
  131. default:
  132. return LevelInfo, false
  133. }
  134. }
  135. func parseStacktraceLevel(level string) (Level, bool) {
  136. switch strings.ToLower(strings.TrimSpace(level)) {
  137. case "none":
  138. return LevelFatal + 1, true
  139. case "error":
  140. return LevelError, true
  141. case "fatal":
  142. return LevelFatal, true
  143. default:
  144. return LevelError, false
  145. }
  146. }
  147. func samplingTick() time.Duration {
  148. return time.Second
  149. }