Предисловие:
В этот раз я расскажу об опыте использования логруса в последнее время, там нет продвинутого исходного кода, только некоторые относительно продвинутые конфигурации. Модуль журнала golang по умолчанию немного примитивен, и в нем нет даже базовой информации, предупреждений и методов печати ошибок, поэтому он не очень применим. До использования модуля логрус я использовал инкапсулированный мной модуль лог.Хотя у него не так много функций, как у логруса, но с ним проблем нет.
Другими словами, существует всего несколько модулей логов с самым высоким рейтингом в сообществе golang, logrus, log4j... Просто глядя на активность github, logrus становится еще более очевидным. Большинство известных проектов с открытым исходным кодом golang в стране и за рубежом представляют собой измельчение бревен, реализованное ими самими.
Эта статья будет обновлена позже, оригинальный адресxiaorui.cc/?p=4963
функция сегментации журнала logrus?
Да у логруса по умолчанию нет функции нарезки лога как у logrotate.Я как-то спрашивал sirupsen в теме,почему нет базового logrotate для логов?Его ответ сказал что нет необходимости в расщеплении.Важно то что автор рекомендует выводить журналы на другие серверы журналов, такие как filebeat, logstash, syslog, rsyslog, Fluentd и так далее. Logrus официально поддерживает множество сервисов журналов, насколько мы можем о них думать.
Итак, если я сейчас реализую сегментацию логов в logrus, что мне делать? Два метода.
Первый, с помощью команды linux logrotate.
/devops/app/go/src/task_dispatcher/logs/*.log
{
daily
sharedscripts
dateext
nocompress
size 1G
missingok
notifempty
copytruncate
rotate 3
Второй способ, использовать хук logrus для загрузки модуля github.com/lestrrat/go-file-rotatelogs.Каждый раз, когда мы пишем лог, logrus будет вызывать go-file-rotatelogs, чтобы определить, нужно ли разбивать лог… go -file-rotatelogs может реализовать большинство функций Linux lograte.
package context
import (
"github.com/lestrrat/go-file-rotatelogs"
"github.com/rifflock/lfshook"
log "github.com/sirupsen/logrus"
"github.com/pkg/errors"
"path"
"time"
"os"
"fmt"
"bufio"
)
func InitLogger() {
baseLogPath := path.Join(GlobalConfig.LogConf.Logdir,
GlobalConfig.LogConf.Filename)
writer, err := rotatelogs.New(
baseLogPath+".%Y%m%d%H%M",
rotatelogs.WithLinkName(baseLogPath), // 生成软链,指向最新日志文件
rotatelogs.WithMaxAge(7*24*time.Hour), // 文件最大保存时间
rotatelogs.WithRotationTime(24*time.Hour), // 日志切割时间间隔
)
if err != nil {
log.Errorf("config local file system logger error. %v", errors.WithStack(err))
}
//log.SetFormatter(&log.TextFormatter{})
switch level := GlobalConfig.LogConf.LogLevel; level {
/*
如果日志级别不是debug就不要打印日志到控制台了
*/
case "debug":
log.SetLevel(log.DebugLevel)
log.SetOutput(os.Stderr)
case "info":
setNull()
log.SetLevel(log.InfoLevel)
case "warn":
setNull()
log.SetLevel(log.WarnLevel)
case "error":
setNull()
log.SetLevel(log.ErrorLevel)
default:
setNull()
log.SetLevel(log.InfoLevel)
}
lfHook := lfshook.NewHook(lfshook.WriterMap{
log.DebugLevel: writer, // 为不同级别设置不同的输出目的
log.InfoLevel: writer,
log.WarnLevel: writer,
log.ErrorLevel: writer,
log.FatalLevel: writer,
log.PanicLevel: writer,
})
log.AddHook(lfHook)
}
func setNull() {
src, err := os.OpenFile(os.DevNull, os.O_APPEND|os.O_WRONLY, os.ModeAppend)
if err!= nil{
fmt.Println("err", err)
}
writer := bufio.NewWriter(src)
log.SetOutput(writer)
}
Так как автор рекомендует использовать логрус хук для расширения функции лога, как можно самому написать хук модуль?Это на самом деле очень просто, нужно только реализовать эти методы, в основном смотрите на функцию Fire... Когда мы вызываем логрус .addHook для размещения После загрузки пользовательского хука метод Fire будет вызываться каждый раз, когда мы пишем лог.
Хук logrus — это дизайн, который стоит изучить подробно, и вы можете легко применить его для записи нескольких файлов. Например, журналы ошибок выводятся в файл error.log независимо друг от друга, а остальные объединяются.
package syslog
import (
"fmt"
"log/syslog"
"os"
"github.com/sirupsen/logrus"
)
type SyslogHook struct {
Writer *syslog.Writer
SyslogNetwork string
SyslogRaddr string
}
func NewSyslogHook(network, raddr string, priority syslog.Priority, tag string) (*SyslogHook, error) {
w, err := syslog.Dial(network, raddr, priority, tag)
return &SyslogHook{w, network, raddr}, err
}
func (hook *SyslogHook) Fire(entry *logrus.Entry) error {
line, err := entry.String()
if err != nil {
fmt.Fprintf(os.Stderr, "Unable to read entry, %v", err)
return err
}
switch entry.Level {
case logrus.PanicLevel:
return hook.Writer.Crit(line)
case logrus.FatalLevel:
return hook.Writer.Crit(line)
case logrus.ErrorLevel:
return hook.Writer.Err(line)
case logrus.WarnLevel:
return hook.Writer.Warning(line)
case logrus.InfoLevel:
return hook.Writer.Info(line)
case logrus.DebugLevel:
return hook.Writer.Debug(line)
default:
return nil
}
}
func (hook *SyslogHook) Levels() []logrus.Level {
return logrus.AllLevels
}
Подводя итог, я не очень доволен функциями логруса, есть много функций, которые вообще не используются, а функции, которые действительно используются, не являются простыми и способными. Что касается вопроса о рубке логруса, то я дважды упомянул его автору, а автор мелькнул и закрыл вопрос.
END.