log.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. package log
  2. import (
  3. "fmt"
  4. "github.com/v2ray/v2ray-core/common"
  5. "github.com/v2ray/v2ray-core/common/alloc"
  6. "github.com/v2ray/v2ray-core/common/serial"
  7. )
  8. const (
  9. DebugLevel = LogLevel(0)
  10. InfoLevel = LogLevel(1)
  11. WarningLevel = LogLevel(2)
  12. ErrorLevel = LogLevel(3)
  13. NoneLevel = LogLevel(999)
  14. )
  15. type LogEntry interface {
  16. common.Releasable
  17. serial.String
  18. }
  19. type errorLog struct {
  20. prefix string
  21. values []interface{}
  22. }
  23. func (this *errorLog) Release() {
  24. for index := range this.values {
  25. this.values[index] = nil
  26. }
  27. this.values = nil
  28. }
  29. func (this *errorLog) String() string {
  30. b := alloc.NewSmallBuffer().Clear()
  31. defer b.Release()
  32. b.AppendString(this.prefix)
  33. for _, value := range this.values {
  34. switch typedVal := value.(type) {
  35. case string:
  36. b.AppendString(typedVal)
  37. case *string:
  38. b.AppendString(*typedVal)
  39. case serial.String:
  40. b.AppendString(typedVal.String())
  41. case error:
  42. b.AppendString(typedVal.Error())
  43. default:
  44. b.AppendString(fmt.Sprint(value))
  45. }
  46. }
  47. return b.String()
  48. }
  49. var (
  50. noOpLoggerInstance logWriter = &noOpLogWriter{}
  51. streamLoggerInstance logWriter = newStdOutLogWriter()
  52. debugLogger = noOpLoggerInstance
  53. infoLogger = noOpLoggerInstance
  54. warningLogger = streamLoggerInstance
  55. errorLogger = streamLoggerInstance
  56. )
  57. type LogLevel int
  58. func SetLogLevel(level LogLevel) {
  59. debugLogger = noOpLoggerInstance
  60. if level <= DebugLevel {
  61. debugLogger = streamLoggerInstance
  62. }
  63. infoLogger = noOpLoggerInstance
  64. if level <= InfoLevel {
  65. infoLogger = streamLoggerInstance
  66. }
  67. warningLogger = noOpLoggerInstance
  68. if level <= WarningLevel {
  69. warningLogger = streamLoggerInstance
  70. }
  71. errorLogger = noOpLoggerInstance
  72. if level <= ErrorLevel {
  73. errorLogger = streamLoggerInstance
  74. }
  75. if level == NoneLevel {
  76. accessLoggerInstance = noOpLoggerInstance
  77. }
  78. }
  79. func InitErrorLogger(file string) error {
  80. logger, err := newFileLogWriter(file)
  81. if err != nil {
  82. Error("Failed to create error logger on file (", file, "): ", err)
  83. return err
  84. }
  85. streamLoggerInstance = logger
  86. return nil
  87. }
  88. // Debug outputs a debug log with given format and optional arguments.
  89. func Debug(v ...interface{}) {
  90. debugLogger.Log(&errorLog{
  91. prefix: "[Debug]",
  92. values: v,
  93. })
  94. }
  95. // Info outputs an info log with given format and optional arguments.
  96. func Info(v ...interface{}) {
  97. infoLogger.Log(&errorLog{
  98. prefix: "[Info]",
  99. values: v,
  100. })
  101. }
  102. // Warning outputs a warning log with given format and optional arguments.
  103. func Warning(v ...interface{}) {
  104. warningLogger.Log(&errorLog{
  105. prefix: "[Warning]",
  106. values: v,
  107. })
  108. }
  109. // Error outputs an error log with given format and optional arguments.
  110. func Error(v ...interface{}) {
  111. errorLogger.Log(&errorLog{
  112. prefix: "[Error]",
  113. values: v,
  114. })
  115. }