const ( DEBUG=iota TRACE INFO WARNING ERROR FATAL )2、定义log接口
// 定义log接口
type Log interface {
Debug(msg string)
TRACE(msg string)
INFO(msg string)
WARNING(msg string)
ERROR(msg string)
FATAL(msg string)
}
输出方式一:将日志记录在控制台
实现log接口中的方法。
1、根据调用的级别输出,将日志级别(int)转为string类型,例如DEBUG(int)实际值为0,转为"DEBUG"(string)
2、在控制台输入,输入的时候带上日期
import (
"fmt"
"runtime"
"time"
)
// 当前日志级别
type Logger struct {
Level int8
}
// 构造方法
func NewLogger(level int8) Logger {
return Logger{Level: level,}
}
// 设置当前日志级别
func (this *Logger)SetLogger(level int8) {
this.Level=level
}
// 实现Log接口中的方法
func (this Logger)Debug(msg string) {
this.printLog(DEBUG,msg)
}
func (this Logger)TRACE(msg string) {
this.printLog(TRACE,msg)
}
func (this Logger)INFO(msg string) {
this.printLog(INFO,msg)
}
func (this Logger)WARNING(msg string) {
this.printLog(WARNING,msg)
}
func (this Logger)ERROR(msg string) {
this.printLog(ERROR,msg)
}
func (this Logger)FATAL(msg string) {
this.printLog(FATAL,msg)
}
// 根据日志级别输出日志信息:日志输出到控制台
func (this Logger)printLog(level int8,msg string) {
var l string
switch level {
case DEBUG:l="DEBUG"
case TRACE:l="TRACE"
case INFO:l="INFO"
case WARNING:l="WARNING"
case ERROR:l="ERROR"
case FATAL:l="FATAL"
}
// 当前级别大于日志级别才输出 否则不输出
if level >= this.Level {
_, file, line, ok := runtime.Caller(2)
if !ok {
fmt.Printf("[%s] [%s] [%s:%d] %sn",time.Now().Format("2006-01-02 15:04:05"),"ERROR",file,line,"runtime.Caller() fail")
return
}
// 日志信息输出到控制台
fmt.Printf("[%s] [%s] [%s:%d] %sn",time.Now().Format("2006-01-02 15:04:05"),l,file,line,msg)
}
}
测试代码:
import (
"helloworld/exercise/logger"
"time"
)
func main() {
my:=logger.Logger{}
my.Level=logger.TRACE // 设置日志级别
for{
my.Debug("这是一条Debug信息")
time.Sleep(time.Second)
my.TRACE("这是一条Trace信息")
time.Sleep(time.Second)
my.INFO("这是一条Info信息")
time.Sleep(time.Second)
my.WARNING("这是一条Warning信息")
time.Sleep(time.Second)
my.ERROR("这是一条Error信息")
time.Sleep(time.Second)
my.FATAL("这是一条Fatal信息")
time.Sleep(time.Second)
}
}
运行结果:由于设置了日志级别,因此Debug级别日志没有输出。
输出方式二:将日志记录在文件中 文件按日期区分
实现接口中定义的方法。
1、创建日志结构体的时候,需要指定日志存放路径
2、创建日志文件,命名格式年月日,例如20210907,日志同一天的存放在一个文件中
3、向日志中写入内容的时候,判断当前日志文件是否需要更新(是否是新的一天)
4、当前日志等级是否需要记录该日志,例如当前日志级别是ERROR,那么之前等级如TRACE的都不需要记录。
5、将日志写进文件中
import (
"fmt"
"os"
"path"
"runtime"
"time"
)
// 按照日期存储日志信息
type Logger2 struct {
level int8 // 打印日志级别
path string // 文件存储路径
filename string // 文件名称
file *os.File //文件指针
time *time.Time // 文件日期
}
// 构造方法
func NewLogger2(path string) Logger2{
l:=Logger2{path: path}
l.newLogFile()
return l
}
// 设置日志级别
func (this *Logger2)SetLevel(level int8) {
this.level=level
}
// 设置日志文件路径
func (this *Logger2)SetPath(path string) {
this.path=path
}
// 向日志中追加内容
func (this *Logger2)writeToLog(level int8,msg string) {
// 当前日志文件已过期,需要用新的日志文件记录,更新Logger信息
if !this.isOneDay() {
this=this.newLogFile()
}
var l string
switch level {
case DEBUG:l="DEBUG"
case TRACE:l="TRACE"
case INFO:l="INFO"
case WARNING:l="WARNING"
case ERROR:l="ERROR"
case FATAL:l="FATAL"
}
// 当前级别大于日志级别才输出 否则不输出
if level >= this.level {
_, file, line, ok := runtime.Caller(2)
if !ok {
fmt.Fprintln(this.file,"[",time.Now().Format("2006-01-02 15:04:05"),"]","[ERROR]","[",file,":",line,"]","runtime.Caller() fail")
return
}
// 日志信息写入文件中
fmt.Fprintln(this.file,"[",time.Now().Format("2006-01-02 15:04:05"),"]","[",l,"]","[",file,":",line,"]",msg)
}
}
// 实现Log接口中的方法
func (this Logger2)Debug(msg string) {
this.writeToLog(DEBUG,msg)
}
func (this Logger2)TRACE(msg string) {
this.writeToLog(TRACE,msg)
}
func (this Logger2)INFO(msg string) {
this.writeToLog(INFO,msg)
}
func (this Logger2)WARNING(msg string) {
this.writeToLog(WARNING,msg)
}
func (this Logger2)ERROR(msg string) {
this.writeToLog(ERROR,msg)
}
func (this Logger2)FATAL(msg string) {
this.writeToLog(FATAL,msg)
}
// 判断当前time是否是同一天
func (this Logger2) isOneDay() bool {
now := time.Now()
day := this.time
// 比较年月日是否相同
return now.Day()==day.Day() && now.Month()==day.Month() && now.Year()==day.Year()
}
// 若当前是新的一天,则需要创建新文件,同时更新文件信息
func (this *Logger2) newLogFile() *Logger2 {
// 获取当前日期
now:=time.Now()
filename:=now.Format("20060102")+".log"
// 获取日志路径
road := this.path
newPath := path.Join(road, filename)
// 创建新的文件 以当前年月日命名
file, err := os.OpenFile(newPath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
if err != nil {
// 将err作为日志输出在文件中
_, f, line, _ := runtime.Caller(0)
fmt.Fprintln(this.file,"[",time.Now().Format("2006-01-02 15:04:05"),"]","[ERROR]","[",f,":",line,"]","create log file failed!")
return this
}
// 更新结构体数据
this.filename=filename
this.file=file
this.time=&now
return this
}
测试代码:
import (
"helloworld/exercise/logger"
"os"
"path"
"time"
)
func main() {
getwd, _ := os.Getwd() // 设置文件存储路径在当前工作目录下
newPath := path.Join(getwd,"./exercise/logger/logFile")
my := logger.NewLogger2(newPath)
my.SetLevel(2) // 设置日志记录级别
for{
my.Debug("这是一条Debug信息")
time.Sleep(time.Second)
my.TRACE("这是一条Trace信息")
time.Sleep(time.Second)
my.INFO("这是一条Info信息")
time.Sleep(time.Second)
my.WARNING("这是一条Warning信息")
time.Sleep(time.Second)
my.ERROR("这是一条Error信息")
time.Sleep(time.Second)
my.FATAL("这是一条Fatal信息")
time.Sleep(time.Second)
}
}
运行结果:



