log.go 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. package log
  2. import (
  3. "io"
  4. "os"
  5. "path/filepath"
  6. "github.com/Sirupsen/logrus"
  7. )
  8. var userHook *ShowuserlogHook
  9. var defaultLogLevel logrus.Level
  10. var debugThisLogger = false
  11. type Fields logrus.Fields
  12. type Level logrus.Level
  13. type Logger logrus.Logger
  14. const (
  15. // PanicLevel level, highest level of severity. Logs and then calls panic with the
  16. // message passed to Debug, Info, ...
  17. PanicLevel Level = iota
  18. // FatalLevel level. Logs and then calls `os.Exit(1)`. It will exit even if the
  19. // logging level is set to Panic.
  20. FatalLevel
  21. // ErrorLevel level. Logs. Used for errors that should definitely be noted.
  22. // Commonly used for hooks to send errors to an error tracking service.
  23. ErrorLevel
  24. // WarnLevel level. Non-critical entries that deserve eyes.
  25. WarnLevel
  26. // InfoLevel level. General operational entries about what's going on inside the
  27. // application.
  28. InfoLevel
  29. // DebugLevel level. Usually only enabled when debugging. Very verbose logging.
  30. DebugLevel
  31. )
  32. func SetOutput(out io.Writer) {
  33. logrus.SetOutput(out)
  34. }
  35. func SetDefaultLevel(level Level) {
  36. defaultLogLevel = logrus.Level(level)
  37. }
  38. func SetLevel(level Level) {
  39. if userHook != nil {
  40. userHook.Level = logrus.Level(level)
  41. } else {
  42. logrus.SetLevel(logrus.Level(level))
  43. }
  44. }
  45. func GetLevel() Level {
  46. if userHook != nil {
  47. return Level(userHook.Level)
  48. }
  49. return Level(logrus.GetLevel())
  50. }
  51. func Debugf(format string, args ...interface{}) {
  52. logrus.Debugf(format, args...)
  53. }
  54. func Infof(format string, args ...interface{}) {
  55. logrus.Infof(format, args...)
  56. }
  57. func Printf(format string, args ...interface{}) {
  58. logrus.Printf(format, args...)
  59. }
  60. func Warnf(format string, args ...interface{}) {
  61. logrus.Warnf(format, args...)
  62. }
  63. func Warningf(format string, args ...interface{}) {
  64. logrus.Warningf(format, args...)
  65. }
  66. func Errorf(format string, args ...interface{}) {
  67. logrus.Errorf(format, args...)
  68. }
  69. func Fatalf(format string, args ...interface{}) {
  70. logrus.Fatalf(format, args...)
  71. }
  72. func Panicf(format string, args ...interface{}) {
  73. logrus.Panicf(format, args...)
  74. }
  75. func Debug(args ...interface{}) {
  76. logrus.Debug(args...)
  77. }
  78. func Info(args ...interface{}) {
  79. logrus.Info(args...)
  80. }
  81. func Print(args ...interface{}) {
  82. logrus.Print(args...)
  83. }
  84. func Warn(args ...interface{}) {
  85. logrus.Warn(args...)
  86. }
  87. func Warning(args ...interface{}) {
  88. logrus.Warning(args...)
  89. }
  90. func Error(args ...interface{}) {
  91. logrus.Error(args...)
  92. }
  93. func Fatal(args ...interface{}) {
  94. logrus.Fatal(args...)
  95. }
  96. func Panic(args ...interface{}) {
  97. logrus.Panic(args...)
  98. }
  99. func WithField(key string, value interface{}) *logrus.Entry {
  100. return logrus.WithField(key, value)
  101. }
  102. func WithFields(fields Fields) *logrus.Entry {
  103. return logrus.WithFields(logrus.Fields(fields))
  104. }
  105. // InitLogger sets up Logging to log to /dev/kmsg and to Syslog
  106. func InitLogger() {
  107. if logTheseApps() {
  108. innerInit(false)
  109. FsReady()
  110. pwd, err := os.Getwd()
  111. if err != nil {
  112. logrus.Error(err)
  113. }
  114. logrus.Debugf("START: %v in %s", os.Args, pwd)
  115. }
  116. }
  117. func logTheseApps() bool {
  118. // TODO: mmm, not very functional.
  119. if filepath.Base(os.Args[0]) == "ros" ||
  120. // filepath.Base(os.Args[0]) == "system-docker" ||
  121. filepath.Base(os.Args[0]) == "host_ros" {
  122. return false
  123. }
  124. return true
  125. }
  126. // InitDeferedLogger stores the log messages until FsReady() is called
  127. // TODO: actually store them :)
  128. // TODO: need to work out how to pass entries from a binary run before we switchfs back to init and have it store and write it later
  129. func InitDeferedLogger() {
  130. if logTheseApps() {
  131. innerInit(true)
  132. //logrus.SetOutput(ioutil.Discard)
  133. // write to dmesg until we can write to file. (maybe we can do this if rancher.debug=true?)
  134. f, err := os.OpenFile("/dev/kmsg", os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0644)
  135. if err == nil {
  136. logrus.SetOutput(f)
  137. }
  138. pwd, err := os.Getwd()
  139. if err != nil {
  140. logrus.Error(err)
  141. }
  142. logrus.Debugf("START: %v in %s", os.Args, pwd)
  143. }
  144. }
  145. func innerInit(deferedHook bool) {
  146. if userHook != nil {
  147. return // we've already initialised it
  148. }
  149. // All logs go through the Hooks, and they choose what to do with them.
  150. logrus.StandardLogger().Level = logrus.DebugLevel
  151. if logTheseApps() {
  152. AddUserHook(deferedHook)
  153. }
  154. }
  155. func FsReady() {
  156. filename := "/var/log/boot/" + filepath.Base(os.Args[0]) + ".log"
  157. if err := os.MkdirAll(filepath.Dir(filename), os.ModeDir|0755); debugThisLogger && err != nil {
  158. logrus.Errorf("FsReady mkdir(%s): %s", filename, err)
  159. }
  160. f, err := os.OpenFile(filename, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0644)
  161. if err != nil {
  162. if debugThisLogger {
  163. logrus.Errorf("FsReady opening %s: %s", filename, err)
  164. }
  165. } else {
  166. if debugThisLogger {
  167. logrus.Infof("Setting log output for %s to: %s", os.Args[0], filename)
  168. }
  169. logrus.SetOutput(f)
  170. }
  171. }
  172. // AddUserHook is used to filter what log messages are written to the screen
  173. func AddUserHook(deferedHook bool) error {
  174. if userHook != nil {
  175. return nil
  176. }
  177. printLogLevel := logrus.InfoLevel
  178. uh, err := NewShowuserlogHook(printLogLevel, filepath.Base(os.Args[0]))
  179. if err != nil {
  180. logrus.Errorf("error creating userHook(%s): %s", os.Args[0], err)
  181. return err
  182. }
  183. userHook = uh
  184. logrus.StandardLogger().Hooks.Add(uh)
  185. if debugThisLogger {
  186. if deferedHook {
  187. logrus.Debugf("------------info Starting defered User Hook (%s)", os.Args[0])
  188. } else {
  189. logrus.Debugf("------------info Starting User Hook (%s)", os.Args[0])
  190. }
  191. }
  192. return nil
  193. }