logger.go 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. package logger
  2. import (
  3. "context"
  4. "io"
  5. "net/http"
  6. "os"
  7. "github.com/porter-dev/porter/api/types"
  8. "github.com/porter-dev/porter/internal/models"
  9. "github.com/rs/zerolog"
  10. )
  11. // Logger is a wrapper for a zerolog Logger
  12. type Logger struct {
  13. logger *zerolog.Logger
  14. }
  15. // New constructs a new Logger which logs via an os.File struct
  16. func New(isDebug bool, file *os.File) *Logger {
  17. logLevel := zerolog.InfoLevel
  18. if isDebug {
  19. logLevel = zerolog.DebugLevel
  20. }
  21. zerolog.SetGlobalLevel(logLevel)
  22. logger := zerolog.New(file).With().Timestamp().Logger()
  23. return &Logger{logger: &logger}
  24. }
  25. // NewConsole uses os.Stdout construct a Logger
  26. func NewConsole(isDebug bool) *Logger {
  27. return New(isDebug, os.Stdout)
  28. }
  29. // NewErrorConsole uses os.Stderr construct a Logger
  30. func NewErrorConsole(isDebug bool) *Logger {
  31. return New(isDebug, os.Stderr)
  32. }
  33. // Output duplicates the global logger and sets w as its output.
  34. func (l *Logger) Output(w io.Writer) zerolog.Logger {
  35. return l.logger.Output(w)
  36. }
  37. // With creates a child logger with the field added to its context.
  38. func (l *Logger) With() zerolog.Context {
  39. return l.logger.With()
  40. }
  41. // Level creates a child logger with the minimum accepted level set to level.
  42. func (l *Logger) Level(level zerolog.Level) zerolog.Logger {
  43. return l.logger.Level(level)
  44. }
  45. // Sample returns a logger with the s sampler.
  46. func (l *Logger) Sample(s zerolog.Sampler) zerolog.Logger {
  47. return l.logger.Sample(s)
  48. }
  49. // Hook returns a logger with the h Hook.
  50. func (l *Logger) Hook(h zerolog.Hook) zerolog.Logger {
  51. return l.logger.Hook(h)
  52. }
  53. // Debug starts a new message with debug level.
  54. //
  55. // You must call Msg on the returned event in order to send the event.
  56. func (l *Logger) Debug() *zerolog.Event {
  57. return l.logger.Debug()
  58. }
  59. // Info starts a new message with info level.
  60. //
  61. // You must call Msg on the returned event in order to send the event.
  62. func (l *Logger) Info() *zerolog.Event {
  63. return l.logger.Info()
  64. }
  65. // Warn starts a new message with warn level.
  66. //
  67. // You must call Msg on the returned event in order to send the event.
  68. func (l *Logger) Warn() *zerolog.Event {
  69. return l.logger.Warn()
  70. }
  71. // Error starts a new message with error level.
  72. //
  73. // You must call Msg on the returned event in order to send the event.
  74. func (l *Logger) Error() *zerolog.Event {
  75. return l.logger.Error()
  76. }
  77. // Fatal starts a new message with fatal level. The os.Exit(1) function
  78. // is called by the Msg method.
  79. //
  80. // You must call Msg on the returned event in order to send the event.
  81. func (l *Logger) Fatal() *zerolog.Event {
  82. return l.logger.Fatal()
  83. }
  84. // Panic starts a new message with panic level. The message is also sent
  85. // to the panic function.
  86. //
  87. // You must call Msg on the returned event in order to send the event.
  88. func (l *Logger) Panic() *zerolog.Event {
  89. return l.logger.Panic()
  90. }
  91. // WithLevel starts a new message with level.
  92. //
  93. // You must call Msg on the returned event in order to send the event.
  94. func (l *Logger) WithLevel(level zerolog.Level) *zerolog.Event {
  95. return l.logger.WithLevel(level)
  96. }
  97. // Log starts a new message with no level. Setting zerolog.GlobalLevel to
  98. // zerolog.Disabled will still disable events produced by this method.
  99. //
  100. // You must call Msg on the returned event in order to send the event.
  101. func (l *Logger) Log() *zerolog.Event {
  102. return l.logger.Log()
  103. }
  104. // Print sends a log event using debug level and no extra field.
  105. // Arguments are handled in the manner of fmt.Print.
  106. func (l *Logger) Print(v ...interface{}) {
  107. l.logger.Print(v...)
  108. }
  109. // Printf sends a log event using debug level and no extra field.
  110. // Arguments are handled in the manner of fmt.Printf.
  111. func (l *Logger) Printf(format string, v ...interface{}) {
  112. l.logger.Printf(format, v...)
  113. }
  114. // Ctx returns the Logger associated with the ctx. If no logger
  115. // is associated, a disabled logger is returned.
  116. func (l *Logger) Ctx(ctx context.Context) *Logger {
  117. return &Logger{logger: zerolog.Ctx(ctx)}
  118. }
  119. func AddLoggingContextScopes(ctx context.Context, event *zerolog.Event) map[string]interface{} {
  120. res := make(map[string]interface{})
  121. // case on the context values that exist, add them to event
  122. if userVal := ctx.Value(types.UserScope); userVal != nil {
  123. if userModel, ok := userVal.(*models.User); ok {
  124. event.Uint("user_id", userModel.ID)
  125. res["user_id"] = userModel.ID
  126. }
  127. }
  128. // if this is a project-scoped route, add various scopes
  129. if reqScopesVal := ctx.Value(types.RequestScopeCtxKey); reqScopesVal != nil {
  130. if reqScopes, ok := reqScopesVal.(map[types.PermissionScope]*types.RequestAction); ok {
  131. for key, scope := range reqScopes {
  132. if scope.Resource.Name != "" {
  133. event.Str(string(key), scope.Resource.Name)
  134. res[string(key)] = scope.Resource.Name
  135. }
  136. if scope.Resource.UInt != 0 {
  137. event.Uint(string(key), scope.Resource.UInt)
  138. res[string(key)] = scope.Resource.UInt
  139. }
  140. }
  141. }
  142. }
  143. return res
  144. }
  145. func AddLoggingRequestMeta(r *http.Request, event *zerolog.Event) {
  146. event.Str("method", r.Method)
  147. event.Str("url", r.URL.String())
  148. }