github.com/lingyao2333/mo-zero@v1.4.1/rest/internal/log.go (about)

     1  package internal
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"net/http"
     7  	"sync"
     8  
     9  	"github.com/lingyao2333/mo-zero/core/logx"
    10  	"github.com/lingyao2333/mo-zero/rest/httpx"
    11  )
    12  
    13  // LogContext is a context key.
    14  var LogContext = contextKey("request_logs")
    15  
    16  // A LogCollector is used to collect logs.
    17  type LogCollector struct {
    18  	Messages []string
    19  	lock     sync.Mutex
    20  }
    21  
    22  // Append appends msg into log context.
    23  func (lc *LogCollector) Append(msg string) {
    24  	lc.lock.Lock()
    25  	lc.Messages = append(lc.Messages, msg)
    26  	lc.lock.Unlock()
    27  }
    28  
    29  // Flush flushes collected logs.
    30  func (lc *LogCollector) Flush() string {
    31  	var buffer bytes.Buffer
    32  
    33  	start := true
    34  	for _, message := range lc.takeAll() {
    35  		if start {
    36  			start = false
    37  		} else {
    38  			buffer.WriteByte('\n')
    39  		}
    40  		buffer.WriteString(message)
    41  	}
    42  
    43  	return buffer.String()
    44  }
    45  
    46  func (lc *LogCollector) takeAll() []string {
    47  	lc.lock.Lock()
    48  	messages := lc.Messages
    49  	lc.Messages = nil
    50  	lc.lock.Unlock()
    51  
    52  	return messages
    53  }
    54  
    55  // Error logs the given v along with r in error log.
    56  func Error(r *http.Request, v ...interface{}) {
    57  	logx.WithContext(r.Context()).Error(format(r, v...))
    58  }
    59  
    60  // Errorf logs the given v with format along with r in error log.
    61  func Errorf(r *http.Request, format string, v ...interface{}) {
    62  	logx.WithContext(r.Context()).Error(formatf(r, format, v...))
    63  }
    64  
    65  // Info logs the given v along with r in access log.
    66  func Info(r *http.Request, v ...interface{}) {
    67  	appendLog(r, format(r, v...))
    68  }
    69  
    70  // Infof logs the given v with format along with r in access log.
    71  func Infof(r *http.Request, format string, v ...interface{}) {
    72  	appendLog(r, formatf(r, format, v...))
    73  }
    74  
    75  func appendLog(r *http.Request, message string) {
    76  	logs := r.Context().Value(LogContext)
    77  	if logs != nil {
    78  		logs.(*LogCollector).Append(message)
    79  	}
    80  }
    81  
    82  func format(r *http.Request, v ...interface{}) string {
    83  	return formatWithReq(r, fmt.Sprint(v...))
    84  }
    85  
    86  func formatf(r *http.Request, format string, v ...interface{}) string {
    87  	return formatWithReq(r, fmt.Sprintf(format, v...))
    88  }
    89  
    90  func formatWithReq(r *http.Request, v string) string {
    91  	return fmt.Sprintf("(%s - %s) %s", r.RequestURI, httpx.GetRemoteAddr(r), v)
    92  }
    93  
    94  type contextKey string
    95  
    96  func (c contextKey) String() string {
    97  	return "rest/internal context key " + string(c)
    98  }