zoukankan      html  css  js  c++  java
  • Go语言Zap日志库使用封装(日志分割)

    1. 日志目录结果

    └── 01_zap_log
        ├── log
        │   └── test.log
        ├── logger.go
        └── logger_test.go
    

    logger.go 文件

    package zap_log
    
    // 安装以下依赖库
    // go get -u go.uber.org/zap
    // go get -u github.com/natefinch/lumberjack
    // go get gopkg.in/alecthomas/kingpin.v2
    import (
    	"github.com/natefinch/lumberjack"
    	"go.uber.org/zap"
    	"go.uber.org/zap/zapcore"
    	"gopkg.in/alecthomas/kingpin.v2"
    	"os"
    	"path/filepath"
    	"strconv"
    )
    
    const (
    	defaultlogpath           = "/var/log/test" // 【默认】日志文件路径
    	defaultlogfilename       = "test.log"      // 【默认】日志文件名称
    	defaultloglevel          = "info"          // 【默认】日志打印级别 debug  info  warning  error
    	defaultlogfilemaxsize    = 5               // 【日志分割】  【默认】单个日志文件最多存储量 单位(mb)
    	defaultlogfilemaxbackups = 10              // 【日志分割】  【默认】日志备份文件最多数量
    	logmaxage                = 1000            // 【默认】日志保留时间,单位: 天 (day)
    	logcompress              = false           // 【默认】是否压缩日志
    	logstdout                = false           // 【默认】是否输出到控制台
    )
    
    var logger *zap.sugaredlogger // 定义日志打印全局变量
    
    var (
    	// kingpin 可以在启动时通过输入参数,来修改日志参数
    	level             = kingpin.flag("log.level", "only log messages with the given severity or above. one of: [debug, info, warn, error]").default(defaultloglevel).string()
    	format            = kingpin.flag("log.format", "output format of log messages. one of: [logfmt, json]").default("logfmt").string()
    	logpath           = kingpin.flag("log.path", "output log path").default(defaultlogpath).string()
    	logfilename       = kingpin.flag("log.filename", "output log filename").default(defaultlogfilename).string()
    	logfilemaxsize    = kingpin.flag("log.file-max-size", "output logfile max size, unit mb").default(strconv.itoa(defaultlogfilemaxsize)).int()
    	logfilemaxbackups = kingpin.flag("log.file-max-backups", "output logfile max backups").default(strconv.itoa(defaultlogfilemaxbackups)).int()
    )
    
    // 初始化 logger
    func initlogger() error {
    	loglevel := map[string]zapcore.level{
    		"debug": zapcore.debuglevel,
    		"info":  zapcore.infolevel,
    		"warn":  zapcore.warnlevel,
    		"error": zapcore.errorlevel,
    	}
    	writesyncer, err := getlogwriter() // 日志文件配置 文件位置和切割
    	if err != nil {
    		return err
    	}
    	encoder := getencoder()       // 获取日志输出编码
    	level, ok := loglevel[*level] // 日志打印级别
    	if !ok {
    		level = loglevel["info"]
    	}
    	core := zapcore.newcore(encoder, writesyncer, level)
    	logger := zap.new(core, zap.addcaller()) //  zap.addcaller() 输出日志打印文件和行数如: logger/logger_test.go:33
    	logger = logger.sugar()
    	return nil
    }
    
    // 编码器(如何写入日志)
    func getencoder() zapcore.encoder {
    	encoderconfig := zap.newproductionencoderconfig()
    	encoderconfig.encodetime = zapcore.iso8601timeencoder   // looger 时间格式 例如: 2021-09-11t20:05:54.852+0800
    	encoderconfig.encodelevel = zapcore.capitallevelencoder // 输出level序列化为全大写字符串,如 info debug error
    	//encoderconfig.encodecaller = zapcore.fullcallerencoder
    	//encoderconfig.encodelevel = zapcore.capitalcolorlevelencoder
    	if *format == "json" {
    		return zapcore.newjsonencoder(encoderconfig) // 以json格式写入
    	}
    	return zapcore.newconsoleencoder(encoderconfig) // 以logfmt格式写入
    }
    
    // 获取日志输出方式  日志文件 控制台
    func getlogwriter() (zapcore.writesyncer, error) {
    	// 判断日志路径是否存在,如果不存在就创建
    	if exist := isexist(*logpath); !exist {
    		if *logpath == "" {
    			*logpath = defaultlogpath
    		}
    		if err := os.mkdirall(*logpath, os.modeperm); err != nil {
    			*logpath = defaultlogpath
    			if err := os.mkdirall(*logpath, os.modeperm); err != nil {
    				return nil, err
    			}
    		}
    	}
    	// 日志文件 与 日志切割 配置
    	lumberjacklogger := &lumberjack.logger{
    		filename:   filepath.join(*logpath, *logfilename), // 日志文件路径
    		maxsize:    *logfilemaxsize,                       // 单个日志文件最大多少 mb
    		maxbackups: *logfilemaxbackups,                    // 日志备份数量
    		maxage:     logmaxage,                             // 日志最长保留时间
    		compress:   logcompress,                           // 是否压缩日志
    	}
    	if logstdout {
    		// 日志同时输出到控制台和日志文件中
    		return zapcore.newmultiwritesyncer(zapcore.addsync(lumberjacklogger), zapcore.addsync(os.stdout)), nil
    	} else {
    		// 日志只输出到控制台
    		return zapcore.addsync(lumberjacklogger), nil
    	}
    }
    
    // 判断文件或者目录是否存在
    func isexist(path string) bool {
    	_, err := os.stat(path)
    	return err == nil || os.isexist(err)
    }
    

    3. logger_test.go 文件

    package zap_log
    
    import (
    	"errors"
    	"go.uber.org/zap"
    	"gopkg.in/alecthomas/kingpin.v2"
    	"testing"
    )
    
    func testinitlogger(t *testing.t) {
    	if _, err := kingpin.commandline.parse([]string{
    		"--log.level", "debug",
    		"--log.format", "logfmt",
    		"--log.path", "../01_zap_log/log",
    		"--log.filename", "test.log",
    		"--log.file-max-size", "3",
    		"--log.file-max-backups", "2"}); err != nil {
    		t.fatal(err)
    	}
    	if err := initlogger(); err != nil {
    		t.fatal(err)
    	}
    
    	var logger *zap.sugaredlogger
    	logger = logger
    	logger.infof("测试一下啊:%s", "111")  // logger infof 用法
    	logger.debugf("测试一下啊:%s", "111") // logger debugf 用法
    	logger.errorf("测试一下啊:%s", "111") // logger errorf 用法
    	logger.warnf("测试一下啊:%s", "111")  // logger warnf 用法
    	logger.infof("测试一下啊:%s, %d, %v, %f", "111", 1111, errors.new("collector returned no data"), 3333.33)
    	logger = logger.with("collector", "cpu", "name", "主机") // logger with 用法
    }
    

    4. 输出日志文件 test.log

    2021-09-11t20:24:07.938+0800	info	01_zap_log/logger_test.go:26	测试一下啊:111
    2021-09-11t20:24:07.939+0800	debug	01_zap_log/logger_test.go:27	测试一下啊:111
    2021-09-11t20:24:07.939+0800	error	01_zap_log/logger_test.go:28	测试一下啊:111
    2021-09-11t20:24:07.939+0800	warn	01_zap_log/logger_test.go:29	测试一下啊:111
    2021-09-11t20:24:07.939+0800	info	01_zap_log/logger_test.go:30	测试一下啊:111, 1111, collector returned no data, 3333.330000
    
  • 相关阅读:
    Struts整合Spring3时注意
    Android组件通讯之BroadcastReceiver应用闹钟服务
    Android组件通讯之Pending Intent与Notification
    Android组件通讯之Service的基础绑定
    Android网络编程之Web Service初步(服务器端搭建)
    Android数据存储之ContentProvider调用联系人数据
    Android网络编程之Socket方式上传对象序列化文件(服务器端)
    Android组件通讯之可跨进程的远程Service调用
    Android网络编程之Web Service初步(客户端)
    Android网络编程之Socket方式上传对象序列化文件(客户端)
  • 原文地址:https://www.cnblogs.com/guohewei/p/15256698.html
Copyright © 2011-2022 走看看