golang中log包自定义输出日志格式与写入到文件

2023-12-05 0 462
目录
  • 1.背景:
  • 2.代码:
  • 总结

1.背景:

平时开发项目时打印日志用到logrus包,但是觉得logrus配置比较麻烦,于是想着直接使用go自带的log包输出日志,其提供了一些配置,比如SetPrefix(), 可以让我们自己二次封装,让自己的日志内容更鲜明些。

2.代码:

package log

import (
\”fmt\”
\”github.com/robfig/cron/v3\”
\”io\”
\”log\”
\”os\”
\”my_log/config\”
\”runtime\”
\”strconv\”
\”strings\”
\”sync\”
\”time\”
)

var (
debug *log.Logger
info *log.Logger
warn *log.Logger
error *log.Logger
dayChangeLock sync.RWMutex
)

const (
debugLevel = iota //iota=0
infoLevel
warnLevel
errorLevel
)

func init() {
dayChangeLock = sync.RWMutex{}
createLogFile()
go logJob()
}

func createLogFile() {
dayChangeLock.Lock()
defer dayChangeLock.Unlock()
now := time.Now()
postFix := now.Format(\”20060102\”)
logFile := \”plume_log_\” + postFix + \”.log\”
logOut, err := os.OpenFile(logFile, os.O_RDWR|os.O_CREATE|os.O_APPEND, os.ModePerm)
if err != nil {
panic(err)
} else {
multiWriter := io.MultiWriter(os.Stdout, logOut)
debug = log.New(multiWriter, \”[DEBUG] \”, log.Ldate|log.Ltime)
info = log.New(multiWriter, \”[INFO] \”, log.Ldate|log.Ltime)
warn = log.New(multiWriter, \”[WARN] \”, log.Ldate|log.Ltime)
error = log.New(multiWriter, \”[ERROR] \”, log.Ldate|log.Ltime)
}
}

func Debug(format string, v …any) {
if config.Conf.Level <= debugLevel {
debug.Printf(getLineNo()+format, v…)
}
}

func Info(format string, v …any) {
if config.Conf.Level <= infoLevel {
info.Printf(getLineNo()+format, v…)
}
}

func Warn(format string, v …any) {
if config.Conf.Level <= warnLevel {
warn.Printf(getLineNo()+format, v…)
}
}

func Error(format string, v …any) {
if config.Conf.Level <= errorLevel {
error.Printf(getLineNo()+format, v…)
}
}

func getLineNo() string {
_, file, line, ok := runtime.Caller(2)
if ok {
split := strings.Split(file, \”/\”)
file = split[len(split)-1]
fileLine := file + \”:\” + strconv.Itoa(line) + \” \”
return fileLine
}
return \”\”
}

// logJob 定时操作日志
func logJob() {
c := cron.New(cron.WithSeconds())
c.AddFunc(\”@daily\”, func() {
Info(\”执行log定时任务。。。\”)
now := time.Now()
createLogFile()
closeYesterdayLogFile := fmt.Sprintf(\”plume_log_%s.log\”, now.Add(-24*time.Hour).Format(\”20060102\”))
file, _ := os.Open(closeYesterdayLogFile)
file.Sync()
file.Close()
// 删除n天前的日志
removeLogFile := fmt.Sprintf(\”plume_log_%s.log\”, time.Now().Add(time.Duration(config.Conf.Log.KeepDays)*-24*time.Hour).Format(\”20060102\”))
open, err := os.Open(removeLogFile)
if err != nil {
Error(err.Error())
return
}
go func () {
// 设置for select 的原因是文件虽然被关闭了,但文件所占的process还在进行中,每10秒轮询一次,执行删除操作,确保文件有被删除
loop:
for {
select {
case <-time.After(10 * time.Second):
removeErr := os.Remove(removeLogFile)
if removeErr != nil {
Error(removeErr.Error())
} else {
Info(\”删除日志成功:%s\”, removeLogFile)
break loop
}
}
}
}()
})
c.Start()
}

//var (
// kernel32 = syscall.NewLazyDLL(`kernel32.dll`)
// proc = kernel32.NewProc(`SetConsoleTextAttribute`)
// CloseHandle = kernel32.NewProc(`CloseHandle`)
// // 给字体颜色对象赋值
// FontColor = Color{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}
//)

//type Color struct {
// black int // 黑色
// blue int // 蓝色
// green int // 绿色
// cyan int // 青色
// red int // 红色
// purple int // 紫色
// yellow int // 黄色
// light_gray int // 淡灰色(系统默认值)
// gray int // 灰色
// light_blue int // 亮蓝色
// light_green int // 亮绿色
// light_cyan int // 亮青色
// light_red int // 亮红色
// light_purple int // 亮紫色
// light_yellow int // 亮黄色
// white int // 白色
//}

// 输出有颜色的字体
//func ColorPrint4Window(s, t string) {
// switch t {
// case \”DEBUG\”:
// proc.Call(uintptr(syscall.Stdout), uintptr(FontColor.light_cyan))
// Debug(s)
// case \”INFO\”:
// proc.Call(uintptr(syscall.Stdout), uintptr(FontColor.green))
// Info(s)
// case \”WARN\”:
// proc.Call(uintptr(syscall.Stdout), uintptr(FontColor.light_yellow))
// Warn(s)
// case \”ERROR\”:
// proc.Call(uintptr(syscall.Stdout), uintptr(FontColor.red))
// Error(s)
// default:
// proc.Call(uintptr(syscall.Stdout), uintptr(FontColor.black))
// Info(s)
// }
//}

使用viper读取配置:

package config

import (
\”github.com/spf13/viper\”
\”os\”
)

var Conf *Config

type Config struct {
Log
}

type Log struct {
Level int
KeepDays int
Prefix string
}

func init() {
Conf = &Config{}
config := viper.New()
path, _ := os.Getwd()
config.SetConfigName(\”config\”) // 配置文件名字,注意没有扩展名
config.SetConfigType(\”toml\”)
config.AddConfigPath(path)
if err := config.ReadInConfig(); err != nil {
panic(err)
}
Conf.Level = config.GetInt(\”log.level\”)
Conf.Log.KeepDays = config.GetInt(\”log.keep-days\”)
Conf.Log.Prefix = config.GetString(\”log.prefix\”)
}
package main

import (
\”my_log/log\”
)

func main() {
log.Debug(\”我是debug日志\”)
log.Info(\”我是info日志\”)
log.Warn(\”我是warn日志\”)
log.Error(\”我是error日志\”)
}

日志配置文件(config.toml):

[log]
level = 0
keep-days = 7
prefix = \”test_\”

控制台输出:

golang中log包自定义输出日志格式与写入到文件

生成的日志文件内容:

golang中log包自定义输出日志格式与写入到文件

碰到的问题:

The process cannot access the file because it is being used by another process.

// 问题的产生:
file := \”test_log.log\”
os.Open(file)
file.Close()
os.Remove(file)
// 因为程序还在运行中,该日志文件所占的process还未停止
// 解决办法:
// 延迟删除文件,比如time.Sleep()
// 推荐使用:label:for + select 轮询删除,删除完毕 break:label
// 示例代码:
loop:
for {
select {
case <-time.After(10 * time.Second):
removeErr := os.Remove(file)
if removeErr != nil {
Error(removeErr.Error())
} else {
Info(\”删除日志成功:%s\”, file)
break loop
}
}
}

总结

到此这篇关于golang中log包自定义输出日志格式与写入到文件的文章就介绍到这了,更多相关go log包自定义输出日志格式内容请搜索悠久资源网以前的文章或继续浏览下面的相关文章希望大家以后多多支持悠久资源网!

您可能感兴趣的文章:

  • Go初学者踩坑之go mod init与自定义包的使用
  • Go 自定义package包设置与导入操作
  • golang import自定义包方式
  • 浅谈goland导入自定义包时出错(一招解决问题)
  • Go语言自定义包构建自己的编程工具库

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

悠久资源 Golang golang中log包自定义输出日志格式与写入到文件 https://www.u-9.cn/jiaoben/golang/102010.html

常见问题

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务