logger.go 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. // mauLogger - A logger for Go programs
  2. // Copyright (C) 2016-2018 Tulir Asokan
  3. //
  4. // This program is free software: you can redistribute it and/or modify
  5. // it under the terms of the GNU General Public License as published by
  6. // the Free Software Foundation, either version 3 of the License, or
  7. // (at your option) any later version.
  8. //
  9. // This program is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU General Public License
  15. // along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. package maulogger
  17. import (
  18. "fmt"
  19. "os"
  20. "time"
  21. )
  22. // LoggerFileFormat ...
  23. type LoggerFileFormat func(now string, i int) string
  24. type BasicLogger struct {
  25. PrintLevel int
  26. FlushLineThreshold int
  27. FileTimeFormat string
  28. FileFormat LoggerFileFormat
  29. TimeFormat string
  30. FileMode os.FileMode
  31. DefaultSub Logger
  32. writer *os.File
  33. lines int
  34. prefixPrinted bool
  35. }
  36. // Logger contains advanced logging functions and also implements io.Writer
  37. type Logger interface {
  38. Sub(module string) Logger
  39. GetParent() Logger
  40. Write(p []byte) (n int, err error)
  41. Log(level Level, parts ...interface{})
  42. Logln(level Level, parts ...interface{})
  43. Logf(level Level, message string, args ...interface{})
  44. Logfln(level Level, message string, args ...interface{})
  45. Debug(parts ...interface{})
  46. Debugln(parts ...interface{})
  47. Debugf(message string, args ...interface{})
  48. Debugfln(message string, args ...interface{})
  49. Info(parts ...interface{})
  50. Infoln(parts ...interface{})
  51. Infof(message string, args ...interface{})
  52. Infofln(message string, args ...interface{})
  53. Warn(parts ...interface{})
  54. Warnln(parts ...interface{})
  55. Warnf(message string, args ...interface{})
  56. Warnfln(message string, args ...interface{})
  57. Error(parts ...interface{})
  58. Errorln(parts ...interface{})
  59. Errorf(message string, args ...interface{})
  60. Errorfln(message string, args ...interface{})
  61. Fatal(parts ...interface{})
  62. Fatalln(parts ...interface{})
  63. Fatalf(message string, args ...interface{})
  64. Fatalfln(message string, args ...interface{})
  65. }
  66. // Create a Logger
  67. func Create() Logger {
  68. var log = &BasicLogger{
  69. PrintLevel: 10,
  70. FileTimeFormat: "2006-01-02",
  71. FileFormat: func(now string, i int) string { return fmt.Sprintf("%[1]s-%02[2]d.log", now, i) },
  72. TimeFormat: "15:04:05 02.01.2006",
  73. FileMode: 0600,
  74. FlushLineThreshold: 5,
  75. lines: 0,
  76. }
  77. log.DefaultSub = log.Sub("")
  78. return log
  79. }
  80. func (log *BasicLogger) GetParent() Logger {
  81. return nil
  82. }
  83. // SetWriter formats the given parts with fmt.Sprint and logs the result with the SetWriter level
  84. func (log *BasicLogger) SetWriter(w *os.File) {
  85. log.writer = w
  86. }
  87. // OpenFile formats the given parts with fmt.Sprint and logs the result with the OpenFile level
  88. func (log *BasicLogger) OpenFile() error {
  89. now := time.Now().Format(log.FileTimeFormat)
  90. i := 1
  91. for ; ; i++ {
  92. if _, err := os.Stat(log.FileFormat(now, i)); os.IsNotExist(err) {
  93. break
  94. } else if i == 99 {
  95. i = 1
  96. break
  97. }
  98. }
  99. var err error
  100. log.writer, err = os.OpenFile(log.FileFormat(now, i), os.O_WRONLY|os.O_CREATE|os.O_APPEND, log.FileMode)
  101. if err != nil {
  102. return err
  103. } else if log.writer == nil {
  104. return os.ErrInvalid
  105. }
  106. return nil
  107. }
  108. // Close formats the given parts with fmt.Sprint and logs the result with the Close level
  109. func (log *BasicLogger) Close() {
  110. if log.writer != nil {
  111. log.writer.Close()
  112. }
  113. }
  114. // Raw formats the given parts with fmt.Sprint and logs the result with the Raw level
  115. func (log *BasicLogger) Raw(level Level, module, message string) {
  116. if !log.prefixPrinted {
  117. if len(module) == 0 {
  118. message = fmt.Sprintf("[%s] [%s] %s", time.Now().Format(log.TimeFormat), level.Name, message)
  119. } else {
  120. message = fmt.Sprintf("[%s] [%s/%s] %s", time.Now().Format(log.TimeFormat), module, level.Name, message)
  121. }
  122. }
  123. log.prefixPrinted = message[len(message)-1] != '\n'
  124. if log.writer != nil {
  125. _, err := log.writer.WriteString(message)
  126. if err != nil {
  127. fmt.Println("Failed to write to log file:", err)
  128. }
  129. }
  130. if level.Severity >= log.PrintLevel {
  131. if level.Severity >= LevelError.Severity {
  132. os.Stderr.Write(level.GetColor())
  133. os.Stderr.WriteString(message)
  134. os.Stderr.Write(level.GetReset())
  135. } else {
  136. os.Stdout.Write(level.GetColor())
  137. os.Stdout.WriteString(message)
  138. os.Stdout.Write(level.GetReset())
  139. }
  140. }
  141. }