Micro & pluggable web framework for Go
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

149 lines
3.2KB

  1. // Copyright 2015 The Tango Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package tango
  5. import (
  6. "io"
  7. "time"
  8. "gitea.com/lunny/log"
  9. )
  10. // Logger defines the logger interface for tango use
  11. type Logger interface {
  12. Debugf(format string, v ...interface{})
  13. Debug(v ...interface{})
  14. Infof(format string, v ...interface{})
  15. Info(v ...interface{})
  16. Warnf(format string, v ...interface{})
  17. Warn(v ...interface{})
  18. Errorf(format string, v ...interface{})
  19. Error(v ...interface{})
  20. }
  21. // CompositeLogger defines a composite loggers
  22. type CompositeLogger struct {
  23. loggers []Logger
  24. }
  25. // NewCompositeLogger creates a composite loggers
  26. func NewCompositeLogger(logs ...Logger) Logger {
  27. return &CompositeLogger{loggers: logs}
  28. }
  29. // Debugf implementes Logger interface
  30. func (l *CompositeLogger) Debugf(format string, v ...interface{}) {
  31. for _, log := range l.loggers {
  32. log.Debugf(format, v...)
  33. }
  34. }
  35. // Debug implementes Logger interface
  36. func (l *CompositeLogger) Debug(v ...interface{}) {
  37. for _, log := range l.loggers {
  38. log.Debug(v...)
  39. }
  40. }
  41. // Infof implementes Logger interface
  42. func (l *CompositeLogger) Infof(format string, v ...interface{}) {
  43. for _, log := range l.loggers {
  44. log.Infof(format, v...)
  45. }
  46. }
  47. // Info implementes Logger interface
  48. func (l *CompositeLogger) Info(v ...interface{}) {
  49. for _, log := range l.loggers {
  50. log.Info(v...)
  51. }
  52. }
  53. // Warnf implementes Logger interface
  54. func (l *CompositeLogger) Warnf(format string, v ...interface{}) {
  55. for _, log := range l.loggers {
  56. log.Warnf(format, v...)
  57. }
  58. }
  59. // Warn implementes Logger interface
  60. func (l *CompositeLogger) Warn(v ...interface{}) {
  61. for _, log := range l.loggers {
  62. log.Warn(v...)
  63. }
  64. }
  65. // Errorf implementes Logger interface
  66. func (l *CompositeLogger) Errorf(format string, v ...interface{}) {
  67. for _, log := range l.loggers {
  68. log.Errorf(format, v...)
  69. }
  70. }
  71. // Error implementes Logger interface
  72. func (l *CompositeLogger) Error(v ...interface{}) {
  73. for _, log := range l.loggers {
  74. log.Error(v...)
  75. }
  76. }
  77. // NewLogger use the default logger with special writer
  78. func NewLogger(out io.Writer) Logger {
  79. l := log.New(out, "[tango] ", log.Ldefault())
  80. l.SetOutputLevel(log.Ldebug)
  81. return l
  82. }
  83. // LogInterface defines logger interface to inject logger to struct
  84. type LogInterface interface {
  85. SetLogger(Logger)
  86. }
  87. // Log implementes LogInterface
  88. type Log struct {
  89. Logger
  90. }
  91. // SetLogger implementes LogInterface
  92. func (l *Log) SetLogger(log Logger) {
  93. l.Logger = log
  94. }
  95. // Logging returns handler to log informations
  96. func Logging() HandlerFunc {
  97. return func(ctx *Context) {
  98. start := time.Now()
  99. p := ctx.Req().URL.Path
  100. if len(ctx.Req().URL.RawQuery) > 0 {
  101. p = p + "?" + ctx.Req().URL.RawQuery
  102. }
  103. ctx.Debug("Started", ctx.Req().Method, p, "for", ctx.IP())
  104. if action := ctx.Action(); action != nil {
  105. if l, ok := action.(LogInterface); ok {
  106. l.SetLogger(ctx.Logger)
  107. }
  108. }
  109. ctx.Next()
  110. if !ctx.Written() {
  111. if ctx.Result == nil {
  112. ctx.Result = NotFound()
  113. }
  114. ctx.HandleError()
  115. }
  116. statusCode := ctx.Status()
  117. if statusCode >= 200 && statusCode < 400 {
  118. ctx.Info(ctx.Req().Method, statusCode, time.Since(start), p)
  119. } else {
  120. ctx.Error(ctx.Req().Method, statusCode, time.Since(start), p, ctx.Result)
  121. }
  122. }
  123. }