理解底层— —Golang的log库,二开实现自定义Logger
理解底层— —Golang的log库,实现自定义Logger
1 分析实现思路
基于golang中自带的log库实现:对日志实现设置日志级别,每天生成一个文件,同时添加上前缀以及展示文件名等
- 日志级别,通过添加prefix:[INFO]、[DEBUG]等来实现
- 每天生成一个日志文件:写日志之前判断当前时间是否为新的一天
- 日志文件命名:获取每天的时间来实现命名,同时添加读写锁保证并发安全
- 获取调用日志文件代码行数及文件名:runtime.Caller获取函数调用栈
2 实战
2.1 server.go
package mainimport "myTest/inter/log_pro/logger"func main() {logger.SetFile("/Users/xsky/GolandProjects/MyTest/inter/log_pro/log/demo.log")logger.SetLevel(0)logger.Debug("hello %s", "ziyi")logger.Info("hello %s", "ziyi")
}
2.2 logger.go
package loggerimport ("log""os""runtime""strconv""strings""sync""time"
)//基于log库自定义实现logger
var (infoLogger *log.LoggerdebugLogger *log.LoggerlogOut *os.FilelogLevel intcurrentDay int //每天生成一个日志文件logFile stringfileLock sync.RWMutex //读写锁,保证同一时间只有一个协程重命名文件
)const (DebugLevel = iota //0InfoLevel //1
)func SetLevel(level int) {logLevel = level
}func init() {fileLock = sync.RWMutex{}
}func SetFile(file string) {var err errorlogOut, err = os.OpenFile(file, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0664)if err != nil {panic(err)} else {//初始化自定义的Logger(基于golang中的log库)//log.LstdFlags表示时间格式等//log.Llongfile表示文件名及调用代码的位置,log.Llongfile=》改为通过getCallTrace获取前缀currentDay = time.Now().YearDay()infoLogger = log.New(logOut, "[INFO] ", log.LstdFlags)debugLogger = log.New(logOut, "[DEBUG] ", log.LstdFlags)logFile = file}
}func checkIfDayChange() {fileLock.Lock()defer fileLock.Unlock()day := time.Now().YearDay()if day == currentDay {return} else {//关闭之前的文件,重命名,并生成新的文件logOut.Close()postFix := time.Now().Add(-24 * time.Hour).Format("20060102")err := os.Rename(logFile, logFile+"."+postFix)if err != nil {//TODO 重命名日志文件失败,根据自身情况做处理}logOut, err = os.OpenFile(logFile, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0664)if err != nil {//TODO 打开新的日志文件失败,根据自己业务需求做处理}infoLogger = log.New(logOut, "[INFO] ", log.LstdFlags)debugLogger = log.New(logOut, "[DEBUG] ", log.LstdFlags)currentDay = day}
}//golang中的any相当于interface{}空接口
func Debug(format string, v ...any) {if logLevel <= DebugLevel {checkIfDayChange()debugLogger.Printf(getPrefix()+format, v)}
}func Info(format string, v ...any) {if logLevel <= InfoLevel {checkIfDayChange()infoLogger.Printf(getPrefix()+format, v)}
}//获取函数调用栈关系:拿到调用Info或者Debug所在的文件名及代码行数(runtime包)
func getCallTrace() (string, int) {_, file, lineNo, ok := runtime.Caller(3)if ok {return file, lineNo} else {return "", 0}
}//获取调用Info、Debug代码所在行数,文件名只获取最后三级
func getPrefix() string {file, lineNo := getCallTrace()path := strings.Split(file, "/")if len(path) > 3 {file = strings.Join(path[len(path)-3:], "/")}return file + ":" + strconv.Itoa(lineNo) + " "
}
3 效果
运行server.go查看效果:

目录结构:

相关文章:
理解底层— —Golang的log库,二开实现自定义Logger
理解底层— —Golang的log库,实现自定义Logger 1 分析实现思路 基于golang中自带的log库实现:对日志实现设置日志级别,每天生成一个文件,同时添加上前缀以及展示文件名等 日志级别,通过添加prefix:[INFO]、…...
RabbitMQ---Spring AMQP
Spring AMQP 1. 简介 Spring有很多不同的项目,其中就有对AMQP的支持: Spring AMQP的页面:http://spring.io/projects/spring-amqp 注意这里一段描述: Spring-amqp是对AMQP协议的抽象实现,而spring-rabbit 是对协…...
C语言练习题解析:挑战与突破,开启编程新篇章!(2)
💓博客主页:江池俊的博客⏩收录专栏:C语言刷题专栏👉专栏推荐:✅C语言初阶之路 ✅C语言进阶之路💻代码仓库:江池俊的代码仓库🎉欢迎大家点赞👍评论📝收藏⭐ 文…...
sqlite3 加密访问
关于sqlite3 加密 一、相关加密用到的sqlcipher 1.1 sqlcipher 是一个数据库加密的开源库 sqlcipher开源地址 我这边是使用的docker镜像,镜像地址: https://hub.docker.com/r/pallocchi/sqlcipher 加密格式 docker run -v <workdir>:/sqlcip…...
clickhouse 系列1:clickhouse v21.7.5.29 源码编译
1.gcc10安装 安装依赖 yum update yum install -y gcc gcc-c++ yum install -y bzip2 下载gcc 源码包并解压 wget -P /data/base https://mirrors.aliyun.com/gnu/gcc/gcc-10.2.0/gcc-10.2.0.tar.gz cd /data/base && tar -xzvf /data/base/gcc-...
servlet初体验之环境搭建!!!
我们需要用到tomcat服务器,咩有下载的小伙伴看过来:如何正确下载tomcat???_明天更新的博客-CSDN博客 1. 创建普通的Java项目,并在项目中创建libs目录存放第三方的jar包。 建立普通项目 创建libs目录存放第三…...
宁芝 NIZ 键盘开机需要重新插拔 USB 线才能使用
宁芝 NIZ 键盘开机需要重新插拔 USB 线才能使用 问题描述 宁芝 NIZ 键盘开机后无法识别到键盘,需要重新插拔 USB 线才能使用。 解决方法 按住 Fn BackSpaceE 键 5 秒,键盘会切换模式, 状态灯闪 1 次为 USB 接口;状态灯闪 2 次为 PS / 2 …...
R编程教程_编程入门自学教程_菜鸟教程-免费教程分享
教程简介 R是用于统计分析、绘图的语言和操作环境。R是属于GNU系统的一个自由、免费、源代码开放的软件,它是一个用于统计计算和统计制图的优秀工具。R语言的核心是解释计算机语言,其允许分支和循环以及使用函数的模块化编程。 R语言允许与以Cÿ…...
[CMake教程] CMake列表 - list
目录 零、简介一、Reading二、Search三、Modification四、Ordering 零、简介 列表在CMake中大量使用。初始化列表语法如下: set(myList a b c) # Creates the list "a;b;c"归根结底,列表只是一个由分号分隔列表项的单个字符串,这…...
报错 - net::ERR_ABORTED 500 (Internal Server Error)
报错:net::ERR_ABORTED 500 (Internal Server Error) 根据提示找到对应文件 解决:检查代码,根据高亮颜色判断,发现箭头函数漏了一个>。 报错:Uncaught TypeError: Assignment to constant variable. 原因&#x…...
【Java Easypoi Apache poi】 Word导入与导出
引入依赖 <dependency><groupId>cn.afterturn</groupId><artifactId>easypoi-spring-boot-starter</artifactId> </dependency> <!-- 下面的版本需要对应上面依赖中的版本 否则可能会起冲突 --> <!-- 下面的依赖主要是为了使用A…...
Java稀疏数组
目录 1.稀疏数组 2.稀疏数组的使用 2.1 二维数组转换为稀疏数组 2.2 稀疏数组转换为二维数组 1.稀疏数组 稀疏数组(Sparse Array):当一个数组中的大部分元素为相同的值,可使用稀疏数组来保存该数组,可以将稀疏数组…...
内存管理框架 --- 基础知识
文章目录 一、内存管理1.1 内存管理的出现1.2 内存管理的用途1.2.1 虚拟内存和物理内存的定义1.2.1.1 什么是虚拟内存? 1.2.2 虚拟内存的划分:用户空间与内核空间 1.3 操作系统和MMU1.3.1 OS和MMU的关系1.3.2 虚拟地址到物理地址的映射流程 1.4 物理内存…...
React + Next.js 搭建项目(配有对比介绍一起食用)
文章标题 01 Next.js 是什么02 Next.js 搭建工具 create-next-app03 create-react-app 与 create-next-app 的区别04 快速构建 Next.js 项目05 App Router 与 Pages Router 的区别 01 Next.js 是什么 Next.js 是一个 React 框架,它允许你使用 React 框架建立超强的…...
【Java】Java基础
环境准备 安装JDK和JRE 下载JDK,可以在官网Java Downloads | Oracle 中国下载,但是这里需要注册才能够下载。在Index of java-local/jdk (huaweicloud.com)也可以下载到,但是版本比较老,关系不大,直接下载࿰…...
Spring-SpringBoot-SpringMVC-MyBatis常见面试题
文章目录 Spring篇springbean是安全的的?什么是AOP你们工作中有用过AOP吗spring中的事务是如何实现的spring中事务失效场景Spring的生命周期spring中的循坏依赖springMVC的执行流程springboot的启动原理常用注解MyBatis执行流程Mybatis是否支持延迟加载?Mybatis的一…...
15.MyCat数据库分片
MyCat 是一个开源的数据库中间件,主要用于将数据库操作请求路由和分发到后端的多个数据库节点。 1.Mycat环境搭建 在两个不同数据库中创建相同表 下载mycat https://github.com/MyCATApache/Mycat-Serverhttps://github.com/MyCATApache/Mycat-Server 将下…...
【Python】PySpark
前言 Apache Spark是用于大规模数据(large-scala data)处理的统一(unified)分析引擎。 简单来说,Spark是一款分布式的计算框架,用于调度成百上千的服务器集群,计算TB、PB乃至EB级别的海量数据…...
pycharm 打开Terminal时报错activate.ps1,因为在此系统上禁止运行脚本,并因此无法进入虚拟环境
pycharm 打开Terminal时报错activate.ps1,因为在此系统上禁止运行脚本,并因此无法进入虚拟环境 如下图所示: 网上说可以set_restrictFalse什么的,虽然也可但可能会降低电脑安全性,可以将下面的终端改为cmd.exe即可...
[C++][C#]yolox TensorRT C++ C#部署
YOLOX是一种新型的高性能探测器,由开发者Zheng Ge、Songtao Liu、Feng Wang、Zeming Li和Jian Sun在《YOLOX: Exceeding YOLO Series in 2021》首次提出。与YOLOV5和YOLOV8相比,YOLOX具有更高的性能和更好的平衡,在速度和精度方面都表现出优越…...
写作压力小了!盘点2026年倾心之选的的降AIGC平台
轻松降低论文AI率在2026年已不再是天方夜谭。以下是2026年最炸裂、实测效果显著的降AIGC平台神器,覆盖AI痕迹消除、文本改写润色、降重优化、学术合规检测四大核心场景,帮你稳妥搞定毕业论文。 一、全流程王者:一站式搞定论文全链路 这类工具…...
手把手教你用春联生成模型中文base:网页界面操作,无需代码生成专业春联
手把手教你用春联生成模型中文base:网页界面操作,无需代码生成专业春联 春节将至,贴春联是中国家庭的传统习俗。但你是否遇到过这样的困扰:想写一副原创春联却缺乏灵感,上网搜索又发现千篇一律?现在&#…...
Qwen2.5-72B-Instruct-GPTQ-Int4实战案例:新能源电池BMS日志分析与故障模式推演
Qwen2.5-72B-Instruct-GPTQ-Int4实战案例:新能源电池BMS日志分析与故障模式推演 1. 项目背景与模型介绍 新能源电池管理系统(BMS)是电动汽车和储能系统的核心组件,每天产生大量运行日志数据。传统分析方法依赖人工经验,效率低下且难以发现潜…...
gte-base-zh中文Embedding工业化:CI/CD流水线实现模型版本灰度发布
gte-base-zh中文Embedding工业化:CI/CD流水线实现模型版本灰度发布 1. 项目背景与价值 在人工智能工程化落地的过程中,模型部署和版本管理一直是技术团队面临的挑战。特别是对于文本嵌入模型如gte-base-zh,如何在生产环境中实现平滑的版本升…...
DeOldify API速率限制:令牌桶算法实现每用户每小时1000次调用
DeOldify API速率限制:令牌桶算法实现每用户每小时1000次调用 1. 为什么需要API速率限制 在构建基于DeOldify的图像上色服务时,我们面临一个重要的技术挑战:如何公平合理地分配计算资源。深度学习模型推理需要消耗大量的GPU计算资源&#x…...
Linux内核链表安全遍历:list_for_each_entry_safe 深度解析
1. 为什么需要安全的链表遍历 在Linux内核开发中,链表是最基础也是最常用的数据结构之一。内核开发者经常需要遍历链表来访问或操作其中的节点。但有一个场景特别棘手:当你需要在遍历过程中删除当前节点时,普通的遍历方法会导致链表断裂甚至系…...
从潍坊一中赛题看算法竞赛中的数据类型陷阱与优化策略
1. 数据类型陷阱:从潍坊一中T1赛题看数值溢出问题 第一次参加算法竞赛的同学,90%都会在数据类型上栽跟头。就拿潍坊一中T1"揽月湖"这道题来说,表面是简单的数学表达式计算,实则是数据类型选择的经典案例。题目要求计算3…...
深度学习基石:从卷积神经网络理解 Stable Yogi 的图像生成能力
深度学习基石:从卷积神经网络理解 Stable Yogi 的图像生成能力 你是不是也好奇,像 Stable Yogi 这样能“凭空”画出精美图片的模型,它的“眼睛”和“大脑”究竟是怎么工作的?为什么给它一段文字描述,它就能理解并生成…...
【模型手术室】第九篇:多模态微调 —— 让模型学会“看图说话”:从像素到行业认知的飞跃
专栏进度:09 / 10 (微调实战专题) 如果你使用的是 LLaVA、Qwen2-VL 或 DeepSeek-VL,它们原生具备识别猫狗和常识图片的能力。但如果你给它一张半导体无尘车间的传感器拓扑图,它大概率会胡言乱语。多模态微调的目标,就是建立“视觉…...
免费开源钥匙建模终极指南:快速生成3D打印钥匙模型
免费开源钥匙建模终极指南:快速生成3D打印钥匙模型 【免费下载链接】keygen OpenSCAD tools for generating physical keys 项目地址: https://gitcode.com/gh_mirrors/ke/keygen 在数字化制造时代,开源钥匙建模工具Keygen为技术爱好者和实践者提…...
