Go语言(十四)日志项目
时间:2022-07-25
本文章向大家介绍Go语言(十四)日志项目,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
日志项目
日志库需求分析
- 日志库产生的背景
- 程序运行是个黑盒
- 日志是程序之外的表现
- 通过日志,可以知道程序的健康状态
- 日志打印的级别
- Debug:日志最详细,对程序的影响比较大
- Trace: 用来追踪问题
- Info: 比较重要的信息,比如访问日志
- Warn:警告日志,表明程序存在问题
- Error: 错误日志,运行程序时发生的错误
- Fatal: 严重错误日志
- 日志存储的位置
- 直接输出到控制台
- 打印到文件里
- 直接打印到网络中,比如kafka
- 为什么使用接口
- 定义日志库的标准或者规范
- 易于扩展
- 利于程序维护
- 日志库的设计
- 打印各个level的日志
- 设置级别
- 构造函数
日志库接口设计
log_base.go 基类
package xlog
import (
"fmt"
"os"
"path/filepath"
"time"
)
type LogData struct {
timeStr string
levelStr string
module string
filename string
funcName string
lineNo int
data string
}
type XLogBase struct {
level int
module string
}
func (l *XLogBase) writeLog(file *os.File,logData *LogData) {
fmt.Fprintf(file,"%s %s %s (%s:%s:%d) %sn",
logData.timeStr, logData.levelStr, logData.module,
logData.filename, logData.funcName, logData.lineNo, logData.data)
}
func (l *XLogBase) formatLogger(level int, module, format string, args ...interface{}) *LogData {
now := time.Now()
timeStr := now.Format("2006-01-02 15:04:05.000")
levelStr := getLevelStr(level)
filename, funcName, lineNo := GetLineInfo(3)
filename = filepath.Base(filename)
data := fmt.Sprintf(format, args...)
//fmt.Printf("%s %s %s (%s:%s:%d) %sn",timeStr,leveStr,module,filename,funcName,lineNo,data)
return &LogData{
timeStr: timeStr,
levelStr: levelStr,
module: module,
filename: filename,
funcName: funcName,
lineNo: lineNo,
data: data,
}
}
log.go
package xlog
type XLog interface {
Init() error //文件初始化
LogDebug(format string, args ...interface{})
LogTrace(format string, args ...interface{})
LogInfo(format string, args ...interface{})
LogWarn(format string, args ...interface{})
LogError(format string, args ...interface{})
LogFatal(format string, args ...interface{})
Close()
SetLevel(level int)
}
func NewXLog(logType, level int, filename, module string) XLog {
//定义接口
var logger XLog
switch logType {
case XLogTypeFile:
logger = NewXFile(level,filename, module)
case XLogTypeConsole:
logger = NewXConsole(level, module)
default:
logger = NewXFile(level,filename, module)
}
return logger
}
level.go
package xlog
const (
XLogLevelDebug = iota
XLogLevelTrace
XLogLevelInfo
XLogLevelWarn
XLogLevelError
XLogLevelFatal
)
const (
XLogTypeFile = iota
XLogTypeConsole
)
func getLevelStr(level int) string {
switch level {
case XLogLevelDebug:
return "DEBUG"
case XLogLevelTrace:
return "TRACE"
case XLogLevelInfo:
return "INFO"
case XLogLevelWarn:
return "WARN"
case XLogLevelError:
return "ERROR"
case XLogLevelFatal:
return "FATAL"
default:
return "UNKNOWN"
}
}
tool.go: 获取程序运行所在行以及函数名
package xlog
import "runtime"
func GetLineInfo(skip int) (filename, funcName string, lineNo int) {
pc, file, line, ok := runtime.Caller(skip)
if ok {
fun := runtime.FuncForPC(pc)
funcName = fun.Name()
}
filename = file
lineNo = line
return
}
文件日志库开发
package xlog
import (
"os"
)
type XFile struct {
*XLogBase
filename string
file *os.File
}
func (c *XFile) Init() (err error) {
c.file,err = os.OpenFile(c.filename, os.O_APPEND|os.O_CREATE|os.O_WRONLY,0755)
if err != nil {
return
}
return
}
func NewXFile(level int, filename, module string) XLog {
logger := &XFile{
filename: filename,
}
logger.XLogBase = &XLogBase{
module: module,
level: level,
}
return logger
}
func (c *XFile) LogDebug(format string, args ...interface{}) {
if c.level > XLogLevelDebug {
return
}
logData := c.formatLogger(XLogLevelDebug, c.module, format, args...)
c.writeLog(c.file,logData)
}
func (c *XFile) LogTrace(format string, args ...interface{}) {
if c.level > XLogLevelTrace {
return
}
logData := c.formatLogger(XLogLevelTrace, c.module, format, args...)
c.writeLog(c.file,logData)
}
func (c *XFile) LogInfo(format string, args ...interface{}) {
if c.level > XLogLevelInfo {
return
}
logData := c.formatLogger(XLogLevelInfo, c.module, format, args...)
c.writeLog(c.file,logData)
}
func (c *XFile) LogWarn(format string, args ...interface{}) {
if c.level > XLogLevelWarn {
return
}
logData := c.formatLogger(XLogLevelWarn, c.module, format, args...)
c.writeLog(c.file,logData)
}
func (c *XFile) LogError(format string, args ...interface{}) {
if c.level > XLogLevelError {
return
}
logData := c.formatLogger(XLogLevelError, c.module, format, args...)
c.writeLog(c.file,logData)
}
func (c *XFile) LogFatal(format string, args ...interface{}) {
if c.level > XLogLevelFatal {
return
}
logData := c.formatLogger(XLogLevelFatal, c.module, format, args...)
c.writeLog(c.file,logData)
}
func (c *XFile) SetLevel(level int) {
c.level = level
}
func (c *XFile)Close() {
if c.file != nil {
c.file.Close()
}
}
Console日志开发
package xlog
import (
"os"
)
type XConsole struct {
*XLogBase //指针实现
}
func NewXConsole(level int, module string) XLog {
logger := &XConsole{}
//初始化指针,防止panic
logger.XLogBase = &XLogBase{
level: level,
module: module,
}
return logger
}
//不需要初始化文件写入
func (c *XConsole)Init() error {
return nil
}
func (c *XConsole) LogDebug(format string, args ...interface{}) {
if c.level > XLogLevelDebug {
return
}
logData := c.formatLogger(XLogLevelDebug, c.module, format, args...)
c.writeLog(os.Stdout,logData)
}
func (c *XConsole) LogTrace(format string, args ...interface{}) {
if c.level > XLogLevelTrace {
return
}
logData := c.formatLogger(XLogLevelTrace, c.module, format, args...)
c.writeLog(os.Stdout,logData)
}
func (c *XConsole) LogInfo(format string, args ...interface{}) {
if c.level > XLogLevelInfo {
return
}
logData := c.formatLogger(XLogLevelInfo, c.module, format, args...)
c.writeLog(os.Stdout,logData)
}
func (c *XConsole) LogWarn(format string, args ...interface{}) {
if c.level > XLogLevelWarn {
return
}
logData := c.formatLogger(XLogLevelWarn, c.module, format, args...)
c.writeLog(os.Stdout,logData)
}
func (c *XConsole) LogError(format string, args ...interface{}) {
if c.level > XLogLevelError {
return
}
logData := c.formatLogger(XLogLevelError, c.module, format, args...)
c.writeLog(os.Stdout,logData)
}
func (c *XConsole) LogFatal(format string, args ...interface{}) {
if c.level > XLogLevelFatal {
return
}
logData := c.formatLogger(XLogLevelFatal, c.module, format, args...)
c.writeLog(os.Stdout,logData)
}
func (c *XConsole) SetLevel(level int) {
c.level = level
}
func (c *XConsole) Close() {}
日志使用以及测试
xlog_example/main.go
package main
import (
"flag"
"fmt"
_"fmt"
"oldBoy/day9/xlog"
)
func logic(logger xlog.XLog) {
logger.LogDebug("dads1,user_id:%d,username:%s",12331,"sadsaf")
logger.LogTrace("dads2")
logger.LogInfo("dads3")
logger.LogWarn("dads4")
logger.LogError("sss")
logger.LogFatal("sss")
}
/*
func testGetLine() {
//skip =2 深度为2的调用位置,也就是main下的22行
filename,funcName,lineNo := xlog.GetLineInfo(2)
fmt.Printf("filename=%s,funcname=%s,linenum=%dn",filename,funcName,lineNo)
}
*/
func main() {
//testGetLine()
var logTypeStr string
flag.StringVar(&logTypeStr,"type","file","please input a logger type")
flag.Parse()
var logType int
if (logTypeStr == "file") {
logType = xlog.XLogTypeFile
}else {
logType = xlog.XLogTypeConsole
}
logger := xlog.NewXLog(logType,xlog.XLogLevelDebug,"./xlog.log","xlog_example")
err := logger.Init()
if err != nil {
fmt.Printf("init error:%vn",err)
return
}
logic(logger)
}
备注
- 缺少的功能:
- 异步写盘
- 日志切分
- 域名资讯:四声域名BHHS.com被BHHS公司收购
- ruby学习笔记(1)--初识语法
- 无法启用数据库中的 Service Broker,因为已存在启用的具有相同 ID 的 Service Broker。
- Centos7.2下针对LDAP的完整部署记录
- .NET Core 已经实现了PHP JIT,现在PHP是.NET上的一门开发语言
- 温故而知新:设计模式之适配器模式(Adapter)
- .NET Core RC2/RTM 明确了时间表
- kvm虚拟化关闭虚拟网卡virbr0的方法
- NET开发学习项目资源(2)
- Linux下selinux简单梳理
- 一段oracle中的“复杂”分组统计sql
- 通过Chocolatey软件包管理器安装.NET Core
- rsync同步时,删除目标目录比源目录多余文件的方法(--delete)
- 近期一枚“大文娱”dawenyu.com域名以小六位价格易主
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Android开发实现的几何图形工具类GeometryUtil完整实例
- Android自定义View倒计时圆
- Android开发实现的IntentUtil跳转多功能工具类
- Android端“被挤下线”功能的单点登录实现
- Android轻松实现多语言的方法示例
- Android开发实现去除bitmap无用白色边框的方法示例
- Android开发实现的内存管理工具类
- Android日期和时间选择器实现代码
- Android开发实现ImageView加载摄像头拍摄的大图功能
- Android开发实现的Intent跳转工具类实例
- Android开发中的文件操作工具类FileUtil完整实例
- Android开发中超好用的正则表达式工具类RegexUtil完整实例
- Android ijkplayer的使用方法解析
- Android开发实现查询远程服务器的工具类QueryUtils完整实例
- 解决android studio 3.0 加载项目过慢问题–maven仓库选择