Golang自定义简单日志记录包

包含日志输出文件记录功能,终端打印功能,文件大小超限备份功能
github下载

main.go

package apelog

// DEBUG TRACE INFO WARN ERROR CRITICAL

type level uint16

const (
    DEBUG level= iota
    TRACE
    INFO
    WARN
    ERROR
    CRITICAL
    // 限制记录日志级别
    LEVEL_CONF = 0
    // 限制终端打印级别
    CSL_LEVEL = 0
    // 日志文件大小限制,超过限制进行切分
    MAXSIZE = 10 * 1024 * 1024
)

// level:0->DEBUG;1->TRACE... also: e.g:apelog.DEBUG...
func Apelog(level level, logFilePath string, logFileName string, msg string) {
    fileLogger := newFileLogger(level, logFilePath, logFileName)
    consoleLogger := newConsoleLogger(level)
    consoleLogger.console_info(level,msg)
    fileLogger.record_info(level, msg)
}

}

file_log.go

package apelog

import (
    "fmt"
    "os"
    "time"
)

// FileLogger往文件中记录日志的结构体
type fileLogger struct {
    level       level
    logFilePath string
    logFileName string
    logFile     *os.File
}

// NewFileLogger 生成文件日志结构体示例的构造函数
func newFileLogger(level level, logFilePath string, logFileName string) *fileLogger {
    flobj := &fileLogger{
        level:       level,
        logFilePath: logFilePath,
        logFileName: logFileName,
    }
    flobj.initFileLogger()
    return flobj
}

// 初始化文件日志的文件句柄
func (f *fileLogger) initFileLogger() {
    filepath := fmt.Sprintf("%s%s", f.logFilePath, f.logFileName)
    file, err := os.OpenFile(filepath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
    //defer file.Close()
    if err != nil {
        panic(fmt.Sprintf("open file:%s failed", filepath))
    }
    f.logFile = file
}

// 检查是否需要切分
func (f *fileLogger) checkSplit(file *os.File) bool {
    fileinfo, _ := file.Stat()
    filesize := fileinfo.Size()
    return filesize >= MAXSIZE
}

// 进行切分
func (f *fileLogger) splitLog(file *os.File) *os.File{
    filename := file.Name()
    now := time.Now()
    backupname := fmt.Sprintf("%s_%d_%s_%d.back", filename, now.Year(),now.Month(),now.Day())
    // 关闭原文件
    file.Close()
    // 备份
    os.Rename(filename, backupname)
    // 新建
    fileobj, err := os.OpenFile(filename, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
    if err != nil {
        panic(fmt.Sprintf("open file:%s failed", filename))
    }
    return fileobj
}

// 拼接日志信息并记录
func (f *fileLogger) record_info(level level, msg string) {
    if level < LEVEL_CONF {
        return
    }
    rec_time := time.Now().Format(" [2006-01-02 15:04:05] ")
    fileName, line, funcName := getCallerInfo(3)
    inf := fmt.Sprintf("%s [file:%s] [function:%s] [line:%d] %s", rec_time, fileName, funcName, line, msg)
    level_str := get_level_str(level)
    inf = fmt.Sprintf("[%s]%s", level_str, inf)
    if f.checkSplit(f.logFile){
        f.logFile = f.splitLog(f.logFile)
    }
    fmt.Fprintln(f.logFile, inf)
}

console.go

package apelog
// 往终端打印


import (
    "fmt"
    "os"
    "time"
)


type consoleLogger struct {
    level level
}

func newConsoleLogger(level level) *consoleLogger {
    cl := &consoleLogger{
        level:       level,
    }
    return cl
}

// 拼接日志信息并记录
func (c *consoleLogger) console_info(level level, msg string) {
    if level < CSL_LEVEL {
        return
    }
    rec_time := time.Now().Format(" [2006-01-02 15:04:05] ")
    fileName, line, funcName := getCallerInfo(3)

    inf := fmt.Sprintf("%s [file:%s] [function:%s] [line:%d] %s", rec_time, fileName, funcName, line, msg)
    level_str := get_level_str(level)
    inf = fmt.Sprintf("[%s]%s",level_str, inf)
    fmt.Fprintln(os.Stdout, inf)
}

utils.go

package apelog

import (
    "fmt"
    "path"
    "runtime"
)

// 公用工具函数

func getCallerInfo(skip int) (fileName string, line int, funcName string) {
    pc, file, line, ok := runtime.Caller(skip)
    if !ok {
        return
    }
    // 从file中剥离出文件名
    fileName = path.Base(file)
    //根据pc拿到函数名
    funcName = path.Base(runtime.FuncForPC(pc).Name())

    return fileName, line, funcName
}

//获取日志等级字符串
func get_level_str(level level) string {
    switch level {
    case DEBUG:
        return "DEBUG"
    case TRACE:
        return "TRACE"
    case INFO:
        return "INFO"
    case WARN:
        return "WARN"
    case ERROR:
        return "ERROR"
    case CRITICAL:
        return "CRITICAL"
    default:
        panic(fmt.Sprintf("logtype error:wrong num, required 1~5 but given %d", level))
    }
}

调用测试

package main

import (
    "fmt"
    "mylog2/apelog"
)


func main() {
    //for {
        userid:=1
        msg := fmt.Sprintf("id为%d的用户登录频繁",userid)
        apelog.Apelog(apelog.INFO,"./test1/","test.log",msg)
        //}
}
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容