golang实现单例日志对象

原文地址:golang实现单例日志对象 – 无敌牛

欢迎参观我的个人博客:无敌牛 – 技术/著作/典籍/分享等

介绍

golang有很多日志包,通过设置和修改都能实现日志轮转和自定义日志格式。例如:log、zap、golog、slog、log4go 等等。

本次给出的示例使用 logrus 和 lumberjack 两个库实现日志轮转和自定义日志格式。

代码

总共涉及到4个文件:

  • go.mod 模块命名;
  • tlog.go 包含主函数,用来测试;
  • tlog1.go 实现了单例模式返回日志对象;
  • tlog2.go 用来测试在别的代码文件中的使用。

go.mod

module tlogrus

tlog.go

package main

import ("time")

func main() {
    // 获取日志记录器的单例实例
    log := GetLogger("")

    // 使用日志记录器记录不同级别的日志
    log.Debug("This is a debug message.")
    log.Info("This is an info message.")
    log.Warn("This is a warning message.")
    time.Sleep(time.Second)
    log.Error("This is an error message.")

    
    Test()

    // 下边这行输出将导致程序退出
    log.Fatal("This is a fatal message.") 
}

tlog1.go

package main

import (
    "os"
    "bytes"
    "runtime"
    "fmt"
    "strings"
    "time"
    "path/filepath"
    "github.com/sirupsen/logrus"
    "github.com/natefinch/lumberjack"
)

// Logger 单例模式的 logger 结构体
var logger  *logrus.Logger = nil

// 自定义格式化结构
type CustomFormatter struct{}

// 自定义格式化结构成员函数,用于格式化日志输出的内容
func (f *CustomFormatter) Format(entry * logrus.Entry)([]byte, error) {
    // 申请日志缓冲空间
    b := &bytes.Buffer{}

    // 1、初始化日期输出格式
    timestamp := entry.Time.Format(time.DateTime)
    // 2、日志级别格式化
    level := strings.ToUpper(entry.Level.String())
    fmt.Fprintf(b, "%s %s ", timestamp, level)

    // 3、获取进程号
    fmt.Fprintf(b, "pid=%d ",os.Getpid())
    
    // 4、获取运行时程序调用的相关信息  调用文件 和 所在行号
    _, file, line, ok := runtime.Caller(6)
    if !ok {
        // 没获取到,给出默认值
        file = "???"
        line = 0 
    }
    fmt.Fprintf(b, "%s:%d : ", filepath.Base(file), line)

    // 5、获取调用函数信息
    if pc, ok := entry.Data["caller"]; ok {
        funcName := runtime.FuncForPC(pc.(uintptr)).Name()
        fmt.Fprintf(b, "%s ", funcName )
    }
    fmt.Fprintf(b, "%s\n", entry.Message)    
    return b.Bytes(), nil
}

// GetLogger 创建或返回日志记录器的唯一实例
func GetLogger(logFileName string) *logrus.Logger {
    if logger != nil {
        return logger
    }

    // 1、创建 logger 对象
    logger = logrus.New()
    // 2、使用 lumberjack 进行日志轮转, 并添加到 logrus.Out
    logger.Out = &lumberjack.Logger{
        Filename:   func (logFileName string) string { if logFileName == "" { return "logs/tlogrus.log" ; } else { return logFileName ;} }  (logFileName) ,
        MaxSize:    1,         // MB
        MaxBackups: 3,
        MaxAge:     28,        // days
        Compress:   true,
    }
    // 3、设置日志格式为 自定义的格式
    logger.SetFormatter(&CustomFormatter{})
    // 4、设置日志级别 Debug
    logger.SetLevel(logrus.DebugLevel)

    return logger
}

tlog2.go

package main

import ("time")

func Test() {

    llog := GetLogger("xxxx.log")
    for { 
        llog.Debug("This is a debug message.=====")
        llog.Info("This is an info message.")
        llog.Warn("This is a warning message.")
        llog.Error("This is an error message.")
        time.Sleep(time.Microsecond)
    }
}

测试

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/929630.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

git回退到某个版本git checkout和git reset命令的区别

文章目录 1. git checkout <commit>2. git reset --hard <commit>两者的区别总结推荐使用场景* 在使用 Git 回退到某个版本时&#xff0c; git checkout <commit> 和 git reset --hard <commit> 是两种常见的方式&#xff0c;但它们的用途和影响有很…

Spring Boot + MySQL 多线程查询与联表查询性能对比分析

Spring Boot MySQL: 多线程查询与联表查询性能对比分析 背景 在现代 Web 应用开发中&#xff0c;数据库性能是影响系统响应时间和用户体验的关键因素之一。随着业务需求的不断增长&#xff0c;单表查询和联表查询的效率问题日益凸显。特别是在 Spring Boot 项目中&#xff0…

人工智能学习用的电脑安装cuda、torch、conda等软件,版本的选择以及多版本切换

接触人工智能的学习三个月了&#xff0c;每天与各种安装包作斗争&#xff0c;缺少依赖包、版本高了、版本低了、不兼容了、系统做一半从头再来了。。。这些都是常态。三个月把单位几台电脑折腾了不下几十次安装&#xff0c;是时候总结一下踩过的坑和积累的经验了。 以一个典型的…

Vue工程化开发中各文件的作用

1.main.js文件 main.js文件的主要作用&#xff1a;导入App.vue&#xff0c;基于App.vue创建结构渲染index.html。

本地运行打包好的dist

首先输入打包命令 每个人设置不一样 一般人 是npm run build如果不知道可以去package.json里去看。 打包好文件如下 命令行输入 :npm i -g http-server 进入到dist目录下输入 命令cmd 输入 http-server 成功

华为HCIE-Datacom认证笔试+实验考试介绍

华为HCIE数通认证考试是面向那些希望成为数通网络领域专家的人员&#xff0c;考试通常两部分&#xff1a;笔试和实验考试。 考试科目&#xff1a; HCIE-Datacom笔试考试内容&#xff1a; HCIE-Datacom V1.0考试覆盖数据通信领域路由交换高阶技术、企业网络架构全景、园区网络…

【组件封装】uniapp vue3 封装一个完整的Tabs(标签页)组件教程,功能由简到杂实现讲解。

文章目录 前言一、简单版Tabs代码实现&#xff1a; 二、下划线带动画的TabsAPI回顾&#xff1a;代码实现&#xff1a; 三、内容区域滑动切换切换动画代码实现&#xff1a;&#xff08;2&#xff09;禁用手势滑动切换&#xff08;3&#xff09;内容区域换为插槽 四、标签栏可滚动…

相对路径和绝对路径与链接标签

一.相对路径 相对路径&#xff1a;以引用文件所在位置为参考基础&#xff0c;而建立出的目录路径。 即图片相对于你写的html页面的位置 相对路径分类符号说明同一级路径图片与html文件处于同一级&#xff0c;如<img src"baidu.gif">下一级路径/图片位于html…

【Java】Switch语句、循环语句(for、while、do...while)

Switch语句&#xff1a;针对某个表达式的值进行判断&#xff0c;从而决定执行哪一段代码 语法格式&#xff1a; switch(表达式){ case 目标值1: 执行语句1 break; case 目标值2: …

P3916 图的遍历(Tarjan缩点和反向建边)

P3916 图的遍历 - 洛谷 | 计算机科学教育新生态 写法一&#xff1a;Tarjan 思路&#xff1a;先运用Tarjan算法得到每个连通块中最大的编号&#xff0c;然后对每个连通块进行缩点重新建图&#xff0c;进行dfs&#xff0c;得到缩点后的连通块能够达到的最大编号。 Code: conste…

2024年认证杯SPSSPRO杯数学建模D题(第一阶段)AI绘画带来的挑战解题全过程文档及程序

2024年认证杯SPSSPRO杯数学建模 D题 AI绘画带来的挑战 原题再现&#xff1a; 2023 年开年&#xff0c;ChatGPT 作为一款聊天型AI工具&#xff0c;成为了超越疫情的热门词条&#xff1b;而在AI的另一个分支——绘图领域&#xff0c;一款名为Midjourney&#xff08;MJ&#xff…

同为科技(TOWE)柔性定制化PDU插座

随着科技的进步&#xff0c;越来越多的精密电子设备&#xff0c;成为工作生活密不可分的工具。 电子电气设备的用电环境也变得更为复杂&#xff0c;所以安全稳定的供电是电子电气设备的生命线。 插座插排作为电子电气设备最后十米范围内供配电最终核心部分&#xff0c;便捷、安…

GPS模块/SATES-ST91Z8LR:电路搭建;直接用电脑的USB转串口进行通讯;模组上报定位数据转换地图识别的坐标手动查询地图位置

从事嵌入式单片机的工作算是符合我个人兴趣爱好的,当面对一个新的芯片我即想把芯片尽快搞懂完成项目赚钱,也想着能够把自己遇到的坑和注意事项记录下来,即方便自己后面查阅也可以分享给大家,这是一种冲动,但是这个或许并不是原厂希望的,尽管这样有可能会牺牲一些时间也有哪天原…

设计模式阅读笔记

参考&#xff1a;设计模式目录&#xff1a;22种设计模式 设计模式是什么&#xff1f; 设计模式是软件设计中常见问题的典型解决方案。 它们就像能根据需求进行调整的预制蓝图&#xff0c; 可用于解决代码中反复出现的设计问题。 设计模式与方法或库的使用方式不同&#xff0c…

详尽的oracle sql函数

1&#xff0c;CHR 输入整数&#xff0c;返回对应字符。 用法&#xff1a;select chr(65),chr(78) from dual; 2&#xff0c;ASCII 输入字符&#xff0c;返回对应ASCII码。 用法&#xff1a;select ascii(A),ascii(B) from dual; 3&#xff0c;CONCAT 输入两个字符串&#xff0c…

C++小碗菜之二:软件单元测试

“没有测试的代码重构不能称之为重构&#xff0c;它仅仅是垃圾代码的到处移动” ——Corey Haines 目录 前言 什么是单元测试&#xff1f; 单元测试的组成 单元测试的命名 单元测试的独立性 Google Test 单元测试的环境配置与使用 1. Ubuntu下安装 Google Test 2. 编写…

Go 1.19.4 HTTP编程-Day 20

1. HTTP协议 1.1 基本介绍 HTTP协议又称超文本传输协议&#xff0c;属于应用层协议&#xff0c;在传输层使用TCP协议。HTTP协议属是无状态的&#xff0c;对事务处理没有记忆能力&#xff0c;如果需要保存状态需要引用其他技术&#xff0c;如Cookie。HTTP协议属是无连接的&…

【SpringBoot】使用IDEA创建SpringBoot项目

1、使用SpringBoot脚手架创建 我们使用SpringBoot的脚手架Spring Initializr创建&#xff0c;如图所示&#xff1a; 2、选择SpringBoot版本 最开始做项目时候&#xff0c;组长说创建一个 springboot 2.5.4 的项目&#xff0c;mysql使用 5.6.X &#xff0c;maven使用是3.6.X…

使用Oracle通过gateway连接MSSQL

环境概述 某医院的his系统Oracle数据库要和体检系统进行数据通讯&#xff0c;需要从Oracle能查到sqlserver的数据。本次通过Oracle gateway来解决此问题。 HIS服务器&#xff1a;windows server 2016数据库oracle11.2.0.4&#xff0c;假设IP是192.168.100.9 体检服务器&…

leetcode 之 二分查找(java)(2)

文章目录 74、搜索二维矩阵33、搜素旋转排序数组 74、搜索二维矩阵 题目描述&#xff1a; 给你一个满足下述两条属性的 m x n 整数矩阵&#xff1a; 每行中的整数从左到右按非严格递增顺序排列。每行的第一个整数大于前一行的最后一个整数。 给你一个整数 target &#xff…