Обзор
В предыдущей статье была описана конфигурация маршрутизации среды Gin, а в этой — ведение журнала.
После проверки большого количества информации ведение журнала Go является наиболее часто используемым.github.com/sirupsen/logrus
.
Logrus is a structured logger for Go (golang), completely API compatible with the standard library logger.
Лог фреймворка Gin по умолчанию будет выводиться только в консоль, мы используемLogrus
Обертывает промежуточное ПО, которое ведет журнал в файл.
Эта статья посвящена изучению и использованиюLogrus
.
формат журнала
Например, договариваемся, что формат лога Текстовый, а поля такие:
请求时间
,日志级别
,状态码
,执行时间
,请求IP
,请求方式
,请求路由
.
Далее мы используемLogrus
Пойми.
Логрус использует
использоватьdep
способ установки.
существуетGopkg.toml
Дополнения к файлам:
[[constraint]]
name = "github.com/sirupsen/logrus"
version = "1.4.2"
Импорт в проект:
import "github.com/sirupsen/logrus"
Выполните в командной строке проекта:
dep ensure
В это время вvendor/github.com/
вы увидите в каталогеsirupsen
содержание.
Готовы начать, давайте спланируем перед началом работы и установим эту функцию в качестве промежуточного программного обеспечения, например:logger.go
.
Журналы можно записывать в файл, определитьLoggerToFile
метод.
Журналы могут быть зарегистрированы в MongoDB, определитеLoggerToMongo
метод.
Журналы могут быть зарегистрированы в ES, определитьLoggerToES
метод.
Журналы могут быть зарегистрированы в MQ, определитьLoggerToMQ
метод.
...
На этот раз мы сначала реализуем запись в файл, реализуемLoggerToFile
метод, и другие могут быть реализованы в соответствии с их собственными потребностями.
этоlogger
Промежуточное программное обеспечение, однажды созданное, может быть перенесено и использовано в других проектах по желанию.
Без лишних слов, просто посмотрите на код.
package middleware
import (
"fmt"
"ginDemo/config"
"github.com/gin-gonic/gin"
"github.com/sirupsen/logrus"
"os"
"path"
"time"
)
// 日志记录到文件
func LoggerToFile() gin.HandlerFunc {
logFilePath := config.Log_FILE_PATH
logFileName := config.LOG_FILE_NAME
//日志文件
fileName := path.Join(logFilePath, logFileName)
//写入文件
src, err := os.OpenFile(fileName, os.O_APPEND|os.O_WRONLY, os.ModeAppend)
if err != nil {
fmt.Println("err", err)
}
//实例化
logger := logrus.New()
//设置输出
logger.Out = src
//设置日志级别
logger.SetLevel(logrus.DebugLevel)
//设置日志格式
logger.SetFormatter(&logrus.TextFormatter{})
return func(c *gin.Context) {
// 开始时间
startTime := time.Now()
// 处理请求
c.Next()
// 结束时间
endTime := time.Now()
// 执行时间
latencyTime := endTime.Sub(startTime)
// 请求方式
reqMethod := c.Request.Method
// 请求路由
reqUri := c.Request.RequestURI
// 状态码
statusCode := c.Writer.Status()
// 请求IP
clientIP := c.ClientIP()
// 日志格式
logger.Infof("| %3d | %13v | %15s | %s | %s |",
statusCode,
latencyTime,
clientIP,
reqMethod,
reqUri,
)
}
}
// 日志记录到 MongoDB
func LoggerToMongo() gin.HandlerFunc {
return func(c *gin.Context) {
}
}
// 日志记录到 ES
func LoggerToES() gin.HandlerFunc {
return func(c *gin.Context) {
}
}
// 日志记录到 MQ
func LoggerToMQ() gin.HandlerFunc {
return func(c *gin.Context) {
}
}
В журнале middleware написано, как его назвать?
Просто добавьте в main.go:
engine := gin.Default() //在这行后新增
engine.Use(middleware.LoggerToFile())
Запустите его и посмотрите лог:
time="2019-07-17T22:10:45+08:00" level=info msg="| 200 | 27.698µs | ::1 | GET | /v1/product/add?name=a&price=10 |"
time="2019-07-17T22:10:46+08:00" level=info msg="| 200 | 27.239µs | ::1 | GET | /v1/product/add?name=a&price=10 |"
этоtime="2019-07-17T22:10:45+08:00"
, этот формат времени не тот, что нам нужен, что нам делать?
Время должно быть отформатировано и измененоlogger.SetFormatter
//设置日志格式
logger.SetFormatter(&logrus.TextFormatter{
TimestampFormat:"2006-01-02 15:04:05",
})
Выполните следующее, а затем просмотрите журнал:
time="2019-07-17 22:15:57" level=info msg="| 200 | 185.027µs | ::1 | GET | /v1/product/add?name=a&price=10 |"
time="2019-07-17 22:15:58" level=info msg="| 200 | 56.989µs | ::1 | GET | /v1/product/add?name=a&price=10 |"
Время стало нормальным.
Мне не нравится текстовый формат, мне нравится формат JSON, что мне делать?
//设置日志格式
logger.SetFormatter(&logrus.JSONFormatter{
TimestampFormat:"2006-01-02 15:04:05",
})
Выполните следующее, а затем просмотрите журнал:
{"level":"info","msg":"| 200 | 24.78µs | ::1 | GET | /v1/product/add?name=a\u0026price=10 |","time":"2019-07-17 22:23:55"}
{"level":"info","msg":"| 200 | 26.946µs | ::1 | GET | /v1/product/add?name=a\u0026price=10 |","time":"2019-07-17 22:23:56"}
В msg слишком много информации, неудобно просматривать, что делать?
// 日志格式
logger.WithFields(logrus.Fields{
"status_code" : statusCode,
"latency_time" : latencyTime,
"client_ip" : clientIP,
"req_method" : reqMethod,
"req_uri" : reqUri,
}).Info()
Выполните следующее, а затем просмотрите журнал:
{"client_ip":"::1","latency_time":26681,"level":"info","msg":"","req_method":"GET","req_uri":"/v1/product/add?name=a\u0026price=10","status_code":200,"time":"2019-07-17 22:37:54"}
{"client_ip":"::1","latency_time":24315,"level":"info","msg":"","req_method":"GET","req_uri":"/v1/product/add?name=a\u0026price=10","status_code":200,"time":"2019-07-17 22:37:55"}
Объяснять:time
,msg
,level
Эти параметры автоматически добавляются logrus.
Поддерживает ли logrus выходные имена файлов и номера строк?
Не поддерживается, ответ автора слишком требователен к производительности.
Тем не менее, некоторые люди в Интернете реализовали его с помощью Hook, поэтому, решив использовать его в производственной среде, не забудьте провести тестирование производительности.
Поддерживает ли logrus разделение логов?
Не поддерживается, но есть способы добиться этого.
1. Можно использоватьLinux logrotate
, который обрабатывается единообразно при эксплуатации и обслуживании.
2, можно использоватьfile-rotatelogs
выполнить.
Пакеты необходимо импортировать:
github.com/lestrrat-go/file-rotatelogs
github.com/rifflock/lfshook
Вот полный код:
package middleware
import (
"fmt"
"ginDemo/config"
"github.com/gin-gonic/gin"
rotatelogs "github.com/lestrrat-go/file-rotatelogs"
"github.com/rifflock/lfshook"
"github.com/sirupsen/logrus"
"os"
"path"
"time"
)
// 日志记录到文件
func LoggerToFile() gin.HandlerFunc {
logFilePath := config.Log_FILE_PATH
logFileName := config.LOG_FILE_NAME
// 日志文件
fileName := path.Join(logFilePath, logFileName)
// 写入文件
src, err := os.OpenFile(fileName, os.O_APPEND|os.O_WRONLY, os.ModeAppend)
if err != nil {
fmt.Println("err", err)
}
// 实例化
logger := logrus.New()
// 设置输出
logger.Out = src
// 设置日志级别
logger.SetLevel(logrus.DebugLevel)
// 设置 rotatelogs
logWriter, err := rotatelogs.New(
// 分割后的文件名称
fileName + ".%Y%m%d.log",
// 生成软链,指向最新日志文件
rotatelogs.WithLinkName(fileName),
// 设置最大保存时间(7天)
rotatelogs.WithMaxAge(7*24*time.Hour),
// 设置日志切割时间间隔(1天)
rotatelogs.WithRotationTime(24*time.Hour),
)
writeMap := lfshook.WriterMap{
logrus.InfoLevel: logWriter,
logrus.FatalLevel: logWriter,
logrus.DebugLevel: logWriter,
logrus.WarnLevel: logWriter,
logrus.ErrorLevel: logWriter,
logrus.PanicLevel: logWriter,
}
lfHook := lfshook.NewHook(writeMap, &logrus.JSONFormatter{
TimestampFormat:"2006-01-02 15:04:05",
})
// 新增 Hook
logger.AddHook(lfHook)
return func(c *gin.Context) {
// 开始时间
startTime := time.Now()
// 处理请求
c.Next()
// 结束时间
endTime := time.Now()
// 执行时间
latencyTime := endTime.Sub(startTime)
// 请求方式
reqMethod := c.Request.Method
// 请求路由
reqUri := c.Request.RequestURI
// 状态码
statusCode := c.Writer.Status()
// 请求IP
clientIP := c.ClientIP()
// 日志格式
logger.WithFields(logrus.Fields{
"status_code" : statusCode,
"latency_time" : latencyTime,
"client_ip" : clientIP,
"req_method" : reqMethod,
"req_uri" : reqUri,
}).Info()
}
}
// 日志记录到 MongoDB
func LoggerToMongo() gin.HandlerFunc {
return func(c *gin.Context) {
}
}
// 日志记录到 ES
func LoggerToES() gin.HandlerFunc {
return func(c *gin.Context) {
}
}
// 日志记录到 MQ
func LoggerToMQ() gin.HandlerFunc {
return func(c *gin.Context) {
}
}
Будет создан новый файлsystem.log.20190717.log
, содержимое журнала соответствует приведенному выше формату.
Наконец,logrus
Есть много расширяемых хуков, вы можете найти их в Интернете.
Некоторые читатели предположили, что просматривать код на мобильном телефоне неудобно, и рекомендуется обновить его на GitHub.
Теперь обновлено, адрес выглядит следующим образом:
Рекомендуемое чтение
Джин каркас
- Gin Framework — привязка и проверка данных
- Gin Framework — ведение журнала с помощью Logrus
- Gin framework — установка и настройка маршрутизации
Основы
- Перейти - функции
- Идти - петля
- Go - Коллекция карт
- Перейти — Структура Структура
- Идти - Нарезать
- Перейти — Массивы
- Go - объявление переменной
- Перейти — Установка среды
Эту статью можно переслать, пожалуйста, укажите автора и источник для пересылки, спасибо!