首页 > 其他分享 >Golang logrus用法

Golang logrus用法

时间:2023-10-21 15:00:11浏览次数:36  
标签:... logrus args 用法 Golang func logger newLogger

package xlog

import (
	"bufio"
	"fmt"
	"github.com/sirupsen/logrus"
    rotatelogs "github.com/lestrrat-go/file-rotatelogs"
    "github.com/rifflock/lfshook"
	"os"
	"time"
)

type Config struct {
	Path         string
	FilePrefix   string
	LevelMode    string
	RotationTime int64

	Server string
}

type Logger struct {
	*logrus.Logger

	globalFields logrus.Fields
}

var logger Logger

func Init(c *Config) (err error) {
	if c.Path == "" {
		return fmt.Errorf("log config.Path is nil")
	}

	newLogger := logrus.New()
	newLogger.AddHook(newDefaultLfsHook(c))

	switch c.LevelMode {
	case "debug": // 如果日志级别不是debug就不要打印日志到控制台了
		newLogger.SetLevel(logrus.DebugLevel)
		newLogger.SetOutput(os.Stderr)
	case "info":
		setNull(newLogger)
		newLogger.SetLevel(logrus.InfoLevel)
	case "warn":
		setNull(newLogger)
		newLogger.SetLevel(logrus.WarnLevel)
	case "error":
		setNull(newLogger)
		newLogger.SetLevel(logrus.ErrorLevel)
	default:
		setNull(newLogger)
		newLogger.SetLevel(logrus.InfoLevel)
	}

	// 设置全局fields
	field := logrus.Fields{"server": c.Server}

	logger = Logger{
		Logger:       newLogger,
		globalFields: field,
	}
	return
}

func GetLogger() Logger {
	return logger
}

// New 自定义初始化 logger 服务
func New(c *Config, suffix string) *logrus.Logger {
	newLogger := logrus.New()
	newLogger.AddHook(newLfsHook(c, suffix))

	/*
	   如果日志级别不是debug就不要打印日志到控制台了
	*/
	switch c.LevelMode {
	case "debug":
		newLogger.SetLevel(logrus.DebugLevel)
		newLogger.SetOutput(os.Stderr)
	case "info":
		setNull(newLogger)
		newLogger.SetLevel(logrus.InfoLevel)
	case "warn":
		setNull(newLogger)
		newLogger.SetLevel(logrus.WarnLevel)
	case "error":
		setNull(newLogger)
		newLogger.SetLevel(logrus.ErrorLevel)
	default:
		setNull(newLogger)
		newLogger.SetLevel(logrus.InfoLevel)
	}
	return newLogger
}

// 取消标准输出
func setNull(logger *logrus.Logger) {
	src, err := os.OpenFile(os.DevNull, os.O_APPEND|os.O_WRONLY, os.ModeAppend)
	if err != nil {
		logger.Errorf("err: %+v", err)
	}
	writer := bufio.NewWriter(src)
	logger.SetOutput(writer)
}

func WithError(err error) *logrus.Entry {
	return logger.Logger.WithFields(logger.globalFields).WithError(err)
}

func WithTime(time time.Time) *logrus.Entry {
	return logger.Logger.WithFields(logger.globalFields).WithTime(time)
}

func WithField(key string, value interface{}) *logrus.Entry {
	return logger.Logger.WithFields(logger.globalFields).WithField(key, value)
}

func WithFields(fields logrus.Fields) *logrus.Entry {
	return logger.Logger.WithFields(logger.globalFields).WithFields(fields)
}

func Tracef(format string, args ...interface{}) {
	logger.WithFields(logger.globalFields).Tracef(format, args...)
}

func Debugf(format string, args ...interface{}) {
	logger.WithFields(logger.globalFields).Debugf(format, args...)
}

func Infof(format string, args ...interface{}) {
	logger.WithFields(logger.globalFields).Infof(format, args...)
}

func Printf(format string, args ...interface{}) {
	logger.WithFields(logger.globalFields).Printf(format, args...)
}

func Warnf(format string, args ...interface{}) {
	logger.WithFields(logger.globalFields).Warnf(format, args...)
}

func Warningf(format string, args ...interface{}) {
	logger.WithFields(logger.globalFields).Warningf(format, args...)
}

func Errorf(format string, args ...interface{}) {
	logger.WithFields(logger.globalFields).Errorf(format, args...)
}

func Fatalf(format string, args ...interface{}) {
	logger.WithFields(logger.globalFields).Fatalf(format, args...)
}

func Panicf(format string, args ...interface{}) {
	logger.WithFields(logger.globalFields).Panicf(format, args...)
}

func Log(level logrus.Level, args ...interface{}) {
	logger.WithFields(logger.globalFields).Log(level, args...)
}

func Trace(args ...interface{}) {
	logger.WithFields(logger.globalFields).Trace(args...)
}

func Debug(args ...interface{}) {
	logger.WithFields(logger.globalFields).Debug(args...)
}

func Info(args ...interface{}) {
	logger.WithFields(logger.globalFields).Info(args...)
}

func Print(args ...interface{}) {
	logger.WithFields(logger.globalFields).Print(args...)
}

func Warn(args ...interface{}) {
	logger.WithFields(logger.globalFields).Warn(args...)
}

func Warning(args ...interface{}) {
	logger.WithFields(logger.globalFields).Warning(args...)
}

func Error(args ...interface{}) {
	logger.WithFields(logger.globalFields).Error(args...)
}

func Fatal(args ...interface{}) {
	logger.WithFields(logger.globalFields).Fatal(args...)
}

func Panic(args ...interface{}) {
	logger.WithFields(logger.globalFields).Panic(args...)
}

func newDefaultLfsHook(c *Config) *lfshook.LfsHook {
	var bathLogPath, bathLinkPath string
	bathLogPath = c.Path + c.FilePrefix
	bathLinkPath = c.Path + "latest.log"
	/* 日志轮转相关函数
	`WithLinkName` 为最新的日志建立软连接
	`WithRotationTime` 设置日志分割的时间,隔多久分割一次
	WithMaxAge 和 WithRotationCount二者只能设置一个
	 `WithMaxAge` 设置文件清理前的最长保存时间
	 `WithRotationCount` 设置文件清理前最多保存的个数
	*/
	// 下面配置日志每隔 1 分钟轮转一个新文件,保留最近 3 分钟的日志文件,多余的自动清理掉。
	writer, err := rotatelogs.New(
		bathLogPath,
		rotatelogs.WithLinkName(bathLinkPath),
		//rotatelogs.WithMaxAge(time.Duration(180)*time.Second),
		//rotatelogs.WithRotationTime(time.Duration(60)*time.Second),
		rotatelogs.WithRotationTime(time.Duration(c.RotationTime)*time.Second),
	)

	if err != nil {
		logrus.Errorf("config local file system logger error. %+v", err)
	}

	return lfshook.NewHook(
		lfshook.WriterMap{
			logrus.DebugLevel: writer, // 为不同级别设置不同的输出目的
			logrus.InfoLevel:  writer,
			logrus.WarnLevel:  writer,
			logrus.ErrorLevel: writer,
			logrus.FatalLevel: writer,
			logrus.PanicLevel: writer,
		}, &logrus.JSONFormatter{
			TimestampFormat: "2006-01-02T15:04:05Z07:00",
			FieldMap: logrus.FieldMap{
				logrus.FieldKeyLevel: "logLevel",
				logrus.FieldKeyMsg:   "msg",
				logrus.FieldKeyTime:  "@timestamp",
			},
		})
}

func newLfsHook(c *Config, suffix string) *lfshook.LfsHook {
	var bathLogPath, bathLinkPath, bathErrorPath string
	if suffix != "" {
		bathLogPath = c.Path + suffix + "." + c.FilePrefix
		bathLinkPath = c.Path + suffix + ".log"
		bathErrorPath = c.Path + suffix + "_error" + ".log"
	} else {
		bathLogPath = c.Path + c.FilePrefix
		bathLinkPath = c.Path + "go.log"
		bathErrorPath = c.Path + "error.log"
	}
	/* 日志轮转相关函数
	`WithLinkName` 为最新的日志建立软连接
	`WithRotationTime` 设置日志分割的时间,隔多久分割一次
	WithMaxAge 和 WithRotationCount二者只能设置一个
	 `WithMaxAge` 设置文件清理前的最长保存时间
	 `WithRotationCount` 设置文件清理前最多保存的个数
	*/
	// 下面配置日志每隔 1 分钟轮转一个新文件,保留最近 3 分钟的日志文件,多余的自动清理掉。
	writer, err := rotatelogs.New(
		bathLogPath,
		rotatelogs.WithLinkName(bathLinkPath),
		rotatelogs.WithMaxAge(time.Duration(180)*time.Second),
		rotatelogs.WithRotationTime(time.Duration(c.RotationTime)*time.Second),
	)

	if err != nil {
		logrus.Errorf("config local file system logger error. %+v", err)
	}

	errWriter, err := rotatelogs.New(
		bathErrorPath,
		//rotatelogs.WithMaxAge(time.Duration(180)*time.Second),
		rotatelogs.WithRotationTime(time.Duration(c.RotationTime)*time.Second),
	)

	if err != nil {
		logrus.Errorf("config local file system logger error. %+v", err)
	}

	return lfshook.NewHook(
		lfshook.WriterMap{
			logrus.DebugLevel: writer, // 为不同级别设置不同的输出目的
			logrus.InfoLevel:  writer,
			logrus.WarnLevel:  writer,
			logrus.ErrorLevel: errWriter,
			logrus.FatalLevel: errWriter,
			logrus.PanicLevel: errWriter,
		}, &JSONFormatter{
			TimestampFormat: "2006-01-02T15:04:05Z07:00",
			FieldMap: FieldMap{
				logrus.FieldKeyLevel: "logLevel",
				logrus.FieldKeyMsg:   "msg",
				logrus.FieldKeyTime:  "@timestamp",
			},
		})
}

标签:...,logrus,args,用法,Golang,func,logger,newLogger
From: https://www.cnblogs.com/qcy-blog/p/17778981.html

相关文章

  • Golang sync包中errgroup的使用详解
    WaitGroup主要用于控制任务组下的并发子任务。它的具体做法就是,子任务goroutine执行前通过Add方法添加任务数目,子任务goroutine结束时调用Done标记已完成任务数,主任务goroutine通过Wait方法等待所有的任务完成后才能执行后续逻辑packagemainimport("ne......
  • golang之xorm简单使用
    gogetgithub.com/go-xorm/xormpackagemainimport("fmt"_"github.com/go-sql-driver/mysql""github.com/go-xorm/xorm")typePointInfostruct{Idint64`xorm:"pkautoincr"`Product......
  • mysqldump之where用法
    文档课题:mysqldump之where用法.数据库:MySQL5.7.21应用场景:实际生产中,需要运用mysqldump导出指定条件的数据,并且以insert语句的形式呈现,如下为相关测试.1、数据库信息mysql>select*fromstaffs;+----+------+-----+---------+---------------------+|id|name|age|p......
  • Object.defineProperty用法
    1、能干啥?Object.defineProperty()可以给传入的对象动态的添加或修改属性2、怎么玩?Object.defineProperty(obj,prop,desc)它有三个参数:obj:需要定义属性的当前对象prop:当前需要定义的属性名;注意是string类型desc:属性描述符;注意是object类型desc常用的属性:value:......
  • 统计学Pearson,Kendall和Spearman 用法及公式。
    假设存在X1,X2,X3,…,Xn.n组对比参数,则有以下信息: I:KL散度、JS散度以及交叉熵对比1) Kl-div(KL散度):1、简介KL散度(Kullback–Leiblerdivergence)又称KL距离,相对熵。(数值归一化处理)当P(x)和Q(x)的相似度越高,KL散度越小。KL散度主要有两个性质:(1)不对称性尽管KL散......
  • MySQL CASE()用法
    MySQL中的CASE表达式用于根据条件进行条件判断和返回多个可能的值。它允许在查询中执行简单的逻辑判断,并根据不同的条件返回不同的值或执行不同的操作。CASE表达式有两种形式:简单CASE和搜索CASE。简单CASE形式:CASEexpressionWHENvalue1THENresult1WHE......
  • MySQL IF()用法
    MySQL中的IF函数用于根据条件返回两个值中的一个。它可以应用于复杂查询和更新语句中,以便根据条件动态生成值。IF函数的语法如下:IF(condition,value_if_true,value_if_false)其中,condition是一个布尔表达式或一个返回布尔值的函数,value_if_true是条件为TRUE时返回......
  • Mysql FIND_IN_SET()用法
    MySQL中的FIND_IN_SET函数用于在逗号分隔的字符串列表中查找指定字符串的位置。它接受两个参数:要查找的字符串和逗号分隔的字符串列表。语法如下:FIND_IN_SET(string,string_list)其中,string是要查找的字符串,string_list是逗号分隔的字符串列表。返回值为待查找字符串......
  • 什么是线程池,线程池的状态,线程池的用法示例
    线程池(ThreadPool)是一种用于管理和重复使用线程的并发编程机制。它是一种有效的方式来管理线程的生命周期、控制并发任务的执行,以及减少线程创建和销毁的开销。线程池在多线程应用程序中被广泛使用,因为它可以提高性能、资源利用率和响应速度。线程池通常包含以下主要组件:工作......
  • Go笔记(1)-变量的详细用法
    变量(1)变量的定义Go语言是静态类型的语言,所有类型都需要明确的定义。var是声明变量的关键字使用格式:var变量名变量类型变量命名规范:遵循驼峰格式,首个单词小写,每个新单词的首字母大写varnameString="WY"//var创建String类型的变量namename="JB"......