基于 logger sdk-logger 封装
package logger
import (
"io/ioutil"
"os"
"path/filepath"
"sync"
"github.com/pkg/errors"
"github.com/rifflock/lfshook"
"github.com/sirupsen/logrus"
)
var loggerIns *logger
type logger struct {
loggerMap *sync.Map
logPath string
env string //环境变量
}
type Config struct {
Env string //环境变量
Path string //日志文件路径
}
//初始化
func InitLogger(config Config) error {
if config.Path == "" {
return errors.New("config path require")
}
if config.Env == "" {
return errors.New("config env require")
}
loggerIns = &logger{
loggerMap: new(sync.Map),
env: config.Env,
logPath: config.Path,
}
return nil
}
//获取实例
func GetLogger(arg ...string) *logrus.Logger {
logName := "all"
if len(arg) > 0 {
logName = arg[0]
}
if log, ok := loggerIns.loggerMap.Load(logName); ok {
return log.(*logrus.Logger)
}
newLog, _ := newLogger(logName)
loggerIns.loggerMap.Store(logName, newLog)
return newLog
}
func newLogger(logName string) (*logrus.Logger, error) {
if logName == "" {
return nil, errors.New("logName require")
}
var logger *logrus.Logger
if _, err := os.Stat(loggerIns.logPath); os.IsNotExist(err) {
if err := os.MkdirAll(loggerIns.logPath, os.ModePerm); err != nil {
return nil, err
}
}
hook := lfshook.NewHook(lfshook.PathMap{
logrus.InfoLevel: filepath.Join(loggerIns.logPath, logName) + ".out.log",
logrus.ErrorLevel: filepath.Join(loggerIns.logPath, logName) + ".err.log",
logrus.DebugLevel: filepath.Join(loggerIns.logPath, logName) + ".debug.log",
logrus.TraceLevel: filepath.Join(loggerIns.logPath, logName) + ".trace.log",
}, &logrus.JSONFormatter{TimestampFormat: "2006-01-02 15:04:05"})
logger = logrus.New()
if loggerIns.env == "online" {
logger.Out = ioutil.Discard
logger.SetLevel(logrus.InfoLevel)
} else {
logger.Out = ioutil.Discard
logger.SetLevel(logrus.DebugLevel)
}
logger.Hooks.Add(hook)
return logger, nil
}
测试文件
package logger_test
import (
"testing"
"xxxx/sdk-logger"
)
func TestMain(t *testing.M) {
config := logger.Config{
Env: "dev",
Path: "./log",
}
if err := logger.InitLogger(config); err != nil {
panic(err)
}
t.Run()
}
func TestGetLogger(t *testing.T) {
logger.GetLogger().Infof("测试日志呀")
logger.GetLogger().WithField("title","测试 key").Debugf("这是 debug 日志")
}
本作品采用《CC 协议》,转载必须注明作者和本文链接
by JeffreyBool blog :point_right: link
下次再发基于 mysql 和 Redis 的provider 封装
要是能封装成laravel 的log组件一样支持多个channel就更完美了
@ALMAS 没懂你说的 支持多个channel 是啥意思
@kenuo 日志《Laravel 5.8 中文文档》
@ALMAS 在我的理解,他的多通道就是日志多实例?
@kenuo 是的
@ALMAS 支持多实例
@kenuo 那这多个实例写入的日志都写入同一个文件里还是每个实例可以指定文件?
@ALMAS 当然是不同的文件了
@kenuo 可同一个目录?
@ALMAS 这本来就是同一个目录啊,代码很清晰,看代码吧,改也很好改
可以用这个做切分:github.com/lestrrat-go/file-rotatelogs
@yourself 我知道这个。这个不好。是软链的。 还不如直接用 linux 系统默认的文件大小切分
@kenuo 期待版主能找到好的用包,或者开源一个
@yourself 我上面封装的这个日志包投入到项目中使用了。还不错。我做支付网关。各种日志都是基于这个日志。 要做日志切分。直接用 linux 系统切分也很方便。 而且性能比程序做更好
好的 感谢分享@kenuo