log.go 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  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. }
  76. func InitErrorLogger(file string) error {
  77. logger, err := newFileLogWriter(file)
  78. if err != nil {
  79. Error("Failed to create error logger on file (", file, "): ", err)
  80. return err
  81. }
  82. streamLoggerInstance = logger
  83. return nil
  84. }
  85. // Debug outputs a debug log with given format and optional arguments.
  86. func Debug(v ...interface{}) {
  87. debugLogger.Log(&errorLog{
  88. prefix: "[Debug]",
  89. values: v,
  90. })
  91. }
  92. // Info outputs an info log with given format and optional arguments.
  93. func Info(v ...interface{}) {
  94. infoLogger.Log(&errorLog{
  95. prefix: "[Info]",
  96. values: v,
  97. })
  98. }
  99. // Warning outputs a warning log with given format and optional arguments.
  100. func Warning(v ...interface{}) {
  101. warningLogger.Log(&errorLog{
  102. prefix: "[Warning]",
  103. values: v,
  104. })
  105. }
  106. // Error outputs an error log with given format and optional arguments.
  107. func Error(v ...interface{}) {
  108. errorLogger.Log(&errorLog{
  109. prefix: "[Error]",
  110. values: v,
  111. })
  112. }