清醒的魔女UR角色推荐奶妈篇攻略

热点 31℃

1、言语引标准库log引见

  • Go言语内置的日记log包完成了复杂的日记处事 。

1 、言语引独霸Logger

  • log包定义了Logger圭表类型  ,日记该圭表类型供给了一些格式化输进的言语引编制  。
  • log包也供给了一个预定义的日记“标准”logger ,可以经由过程调用函数Print系列(Print|Printf|Println)、言语引Fatal系列(Fatal|Fatalf|Fatalln)、日记和Panic系列(Panic|Panicf|Panicln)来独霸 ,言语引比自行成立一个logger对象更随便独霸。日记

logger会打印每条日记信息的言语引日期、时分,日记默许输进到琐细的言语引标准偏向 。

Fatal系列函数会在写进日记信息后调用os.Exit(1) 。日记

Panic系列函数会在写进日记信息后panic。言语引

示例 :

// 直接调用print来输进日记到终端func main() { 	log.Println("这是一条很深化的日记
。")	v := "很深化的"	log.Printf("这是一条%s日记。\n", v)	log.Fatalln("这是一条会触发fatal的日记
。")	log.Panicln("这是一条会触发panic的日记。")}

2 、设置设备放置logger

 2.1、标准logger的设置设备放置

  • 默许气候下的logger只会供给日记的时分信息 ,可是良多气候下我们希看掉落踪掉落踪更多信息,比如记实该日记的文件名和行号等。
  • log标准库中为我们供给了定制这些设置的编制。log标准库中的Flags函数会前去标准logger的输进设置设备放置  ,而SetFlags函数用来设置标准logger的输进设置设备放置 。

2 、自定义日记库

 1、需求知足的需求

 1 、支撑网不合中心输进日记

2 、日记要支撑开关键制

3 、无缺的日记要包含时分、行号 、文件名 、日记级别、日记信息

4  、日记文件要能切割

5、日记级别

  • Debug
  • Trace
  • Info
  • Warning
  • Error
  • Fatal

2  、体味下runtime包

  • runtime.Caller() 编制,会前去函数调用的信息,在()内传进int圭表类型数据,代表调用的层数(0代表第一层被调用,1代表第二层 ,一次类推) 。runtime.Caller()前去以下四个参数:

pc: 记实了调用的函数消息,如函数名等
file: 调用的文件名
line: 行数
OK: 前去的bool值

// 掉落踪掉落踪代码行号func getinfo(n int) { 	/*		runtime.Caller()前去四个参数:		pc: 记实了调用的函数消息,如函数名等		file: 调用的文件名		line: 行数		OK: 前去的bool值	*/	pc, file, line, ok := runtime.Caller(n)	if !ok { 		fmt.Printf("runtime.Caller() failed\n")		return	}	fmt.Println(pc)  // 用于调用函数消息	funcName := runtime.FuncForPC(pc).Name() // 独霸 runtime.FuncForPC()编制,参数pc序号,可以调出函数名	fmt.Println(funcName)	fmt.Println(file)   // 打印出奉行的文件的尽对路途	fmt.Println(path.Base(file))  // path.Base()编制可以掉落踪掉落踪传进的尽对路途的末尾一个文件称号	fmt.Println(line)   // 打印出奉行的行号}func main() { 	getinfo(0)}

3 、自定义日记库

1、在 E:\GoProject\src\gitee.com 项目目次下 ,新建 mylogger 包目次,存放日记库代码

在mylogger包目次下console.go文件中,放将日记输进到终端的代码

# E:\GoProject\src\gitee.com\mylogger\console.gopackage myloggerimport (	"fmt"	"strings"	"time")// 终端输进的日记内容// Logger 日记筹划体type ConsoleLogger struct { 	Level LogLevel}// 构造函数func NewLog(levelStr string) ConsoleLogger { 	level, err := parseLogLevel(levelStr)	if err != nil { 		panic(err)	}	return ConsoleLogger{ 		Level: level,	}}// 定义日记等第斗劲func (c ConsoleLogger) enable(level LogLevel) bool { 	return c.Level <= level}// 定义一个日记打印编制func (c ConsoleLogger) outLog(lv LogLevel, format string, a ...inte***ce{ }) { 	level := parseLogLevelStr(lv)	if c.enable(lv) { 		msg := fmt.Sprintf(format, a...) // 支撑格式化独霸,a...展示对领受的接口举办展开		level = strings.ToUpper(level)		fileName, funcName, linenu := getinfo(3)		fmt.Printf("[%s] [%s] [FileName:%s lineNum:%d:%s] %s\n", time.Now().Format("2006-01-02 15:04:05"), level, fileName, linenu, funcName, msg)	}}// Debug日记func (c ConsoleLogger) Debug(msg string, a ...inte***ce{ }) { 	c.outLog(DEBUG, msg, a...)}// Info日记func (c ConsoleLogger) Info(msg string, a ...inte***ce{ }) { 	c.outLog(INFO, msg, a...)}// Warning日记func (c ConsoleLogger) Warning(msg string, a ...inte***ce{ }) { 	c.outLog(WARNING, msg, a...)}// Error日记func (c ConsoleLogger) Error(msg string, a ...inte***ce{ }) { 	c.outLog(ERROR, msg, a...)}// Fatal日记func (c ConsoleLogger) Fatal(msg string, a ...inte***ce{ }) { 	c.outLog(FATAL, msg, a...)}

在mylogger包目次下logfile.go文件中  ,放将日记输进到文件的代码

# E:\GoProject\src\gitee.com\mylogger\logfile.gopackage mylogger// 向文件中写日记的相干独霸import (	"fmt"	"os"	"path"	"strings"	"time")// Logger 日记筹划体type FileLogger struct { 	Level       LogLevel	logPath     string // 日记文件目次	fileName    string // 日记文件称号	maxFileSize int64  // 日记文件大年夜小	fileObj     *os.File	errFileObj  *os.File}// 构造函数func NewFileLog(levelStr, fp, fn string, maxSize int64) *FileLogger { 	level, err := parseLogLevel(levelStr)	if err != nil { 		panic(err)	}	f1 := &FileLogger{ 		Level:       level,		logPath:     fp,		fileName:    fn,		maxFileSize: maxSize,	}	err = f1.initFile()	if err != nil { 		panic(err)	}	return f1}// 定义文件初始化编制
	,翻开文件func (f *FileLogger) initFile() error { 	// 翻开文件	fullPath := path.Join(f.logPath, f.fileName)	fileObj, err := os.OpenFile(fullPath, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644)	if err != nil { 		fmt.Printf("open logFile failed,Err:%v", err)		return err	}	// 翻开偏向日记文件	errFileObj, err := os.OpenFile("error-"+fullPath, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644)	if err != nil { 		fmt.Printf("open errorLogFile failed,Err:%v", err)		return err	}	// 将文件句柄赋值给筹划体中的元素	f.fileObj = fileObj	f.errFileObj = errFileObj	return nil}// 封锁文件编制func (f *FileLogger) closeFile() { 	f.fileObj.Close()	f.errFileObj.Close()}// 定义日记等第斗劲func (f *FileLogger) enable(level LogLevel) bool { 	return f.Level <= level}// 定义搜检日记大年夜小举办切割的编制func (f *FileLogger) checkLogSize(file *os.File) bool {  // 独霸os.Open()编制翻开的文件句柄圭表类型都是 *os.File 这类指针圭表类型	fileInfo, err := file.Stat()	if err != nil { 		fmt.Printf("get file info failed,err:%v\n", err)		return false		// panic(err)	}	if fileInfo.Size() > f.maxFileSize { 		return true	}	return false}func (f *FileLogger) cutFile(file *os.File) (*os.File, error) { 	// 取妥往后文件名	fileInfo, err := file.Stat()	if err != nil { 		fmt.Printf("get file info failed,err:%v\n", err)		return nil, err	}	append := "_" + time.Now().Format("2006-01-02-15-04-05") + ".log" // 时分戳后缀	fileName := fileInfo.Name()	newFileName := fileName + append	oldPath := path.Join(f.logPath, fileName) // 日记文件的全路途	newPath := path.Join(f.logPath, newFileName)	// 封锁往后文件句柄	file.Close()	// 举办改名备份	os.Rename(oldPath, newPath)	// 再翻开一个文件	fileObj, err := os.OpenFile(oldPath, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644)	if err != nil { 		fmt.Printf("open logFile failed,Err:%v\n", err)		return nil, err	}	return fileObj, nil}// 定义一个日记输进的编制func (f *FileLogger) outLog(lv LogLevel, format string, a ...inte***ce{ }) { 	level := parseLogLevelStr(lv)	if f.enable(lv) { 		msg := fmt.Sprintf(format, a...) // 支撑格式化独霸
,a...展示对领受的接口举办展开		level = strings.ToUpper(level)		fileName, funcName, linenu := getinfo(3)		// 剖断日记可否需求切割		if f.checkLogSize(f.fileObj) { 			fileobj, err := f.cutFile(f.fileObj)			if err != nil { 				fmt.Printf("log cut failed,err:%v\n", err)			}			f.fileObj = fileobj		}		// 将日记记真实日记文件中		fmt.Fprintf(f.fileObj, "[%s] [%s] [FileName:%s lineNum:%d:%s] %s\n", time.Now().Format("2006-01-02 15:04:05"), level, fileName, linenu, funcName, msg)		if lv >= ERROR { 			// 剖断偏向日记可否需求切割			if f.checkLogSize(f.errFileObj) { 				fileobj, err := f.cutFile(f.errFileObj)				if err != nil { 					fmt.Printf("log cut failed,err:%v\n", err)				}				f.errFileObj = fileobj			}			// 将日记等第除夜于ERROR的在偏向日记中再记实一遍			fmt.Fprintf(f.errFileObj, "[%s] [%s] [FileName:%s lineNum:%d:%s] %s\n", time.Now().Format("2006-01-02 15:04:05"), level, fileName, linenu, funcName, msg)		}	}}// Debug日记func (f *FileLogger) Debug(msg string, a ...inte***ce{ }) { 	f.outLog(DEBUG, msg, a...)}// Info日记func (f *FileLogger) Info(msg string, a ...inte***ce{ }) { 	f.outLog(INFO, msg, a...)}// Warning日记func (f *FileLogger) Warning(msg string, a ...inte***ce{ }) { 	f.outLog(WARNING, msg, a...)}// Error日记func (f *FileLogger) Error(msg string, a ...inte***ce{ }) { 	f.outLog(ERROR, msg, a...)}// Fatal日记func (f *FileLogger) Fatal(msg string, a ...inte***ce{ }) { 	f.outLog(FATAL, msg, a...)}

在mylogger包目次下成立mylogger.go文件,放包内共用的代码

# E:\GoProject\src\gitee.com\mylogger\mylogger.gopackage myloggerimport (	"errors"	"fmt"	"path"	"runtime"	"strings")// 设置日记级别type LogLevel uint16const (	UNKNOWN LogLevel = iota	DEBUG	TRACE	INFO	WARNING	ERROR	FATAL)// 分析日记等第
,将字符串分析成intfunc parseLogLevel(s string) (LogLevel, error) { 	s = strings.ToLower(s) // 将字符串全数转为小写	switch s { 	case "debug":		return DEBUG, nil	case "trace":		return TRACE, nil	case "info":		return INFO, nil	case "warning":		return WARNING, nil	case "error":		return ERROR, nil	case "fatal":		return FATAL, nil	default:		err := errors.New("有效日记等第")		return UNKNOWN, err	}}// 将日记等第分析成字符串func parseLogLevelStr(lv LogLevel) (s string) { 	s = strings.ToLower(s) // 将字符串全数转为小写	switch lv { 	case DEBUG:		return "DEBUG"	case TRACE:		return "TRACE"	case INFO:		return "INFO"	case WARNING:		return "WARNING"	case ERROR:		return "ERROR"	case FATAL:		return "FATAL"	default:		return "DEBUG"	}}// 掉落踪掉落踪代码行号func getinfo(n int) (fileName, funcName string, line int) { 	/*		runtime.Caller()前去四个参数:		pc: 记实了调用的函数消息,如函数名等		file: 调用的文件名		line: 行数		OK: 前去的bool值	*/	pc, file, line, ok := runtime.Caller(n)	if !ok { 		fmt.Printf("runtime.Caller() failed\n")		return	}	fileName = path.Base(file)	funcName = runtime.FuncForPC(pc).Name()	return fileName, funcName, line}

2 、调用日记库代码测试

需求寄看,导进mylogger包,是从$GOPATH路途最早的(即从src目次最早的绝对路途)

# E:\GoProject\src\gitee.com\LTP\loggingpackage mainimport (	"time"	mylogger "gitee.com/mylogger")func main() { 	id := 10	name := "小明"	flogger := mylogger.NewFileLog("info", "./", "app.log", 1024)	for { 		flogger.Warning("这是个Warning日记")		flogger.Error("这是个Error日记,id:%d name:%s", id, name)		time.Sleep(2 * time.Second)	}}

到此这篇关于Go言语 log日记库的文章就引见到这了,更多相干Go log日记库内容请搜刮完竣下载之前的文章或延续不雅不雅不雅不雅鉴赏上面的相干文章希看大年夜师往后多多支撑完竣下载!