当前位置: 首页 > news >正文

【Linux】Linux下的日志(日常级)

日志是日后工作中非常重要的一部分,现在写一份简单的日志项目可以帮助我们熟悉并理解原理。

目录

  • 设计思路:
  • 一些实现细节:
  • 代码:
  • 日志的使用方法:

设计思路:

图示是我们的最终目的。
在这里插入图片描述

  1. 设计一个类,这个类中存放着以上数据。
  2. 设计一个Log类,这个类中有一个Print函数进行按照指定格式(文件或显示器)输出,我们向这个成员函数中传参进行打印。

一些实现细节:

  • 获取时间:可以使用time函数获取时间戳,由localtime进行格式转换为我们指定的样式。
  • printf的格式输出:printf("%02d", 10);代表域宽为2,数字在右边,空余补0。
  • 可变参数的处理:

有很多的方法:
比如自己逐个提取或者利用现有的接口提取。
这并不是重点,会用即可。
可变参数的博客。

我们还是最好使用接口进行提取,避免看很多麻烦的操作,那就是在这里插入图片描述
与snprintf使用方法类似,可以直接将转换后的直接写入指定字符串中!

  • 关于封装:不同功能的函数可以在成员函数与非成员函数之间自由切换(根据对成员变量的需求…)
  • 宏中的可变参数:这个__VA_ARGS__链接包含了一些宏的用法。

代码:

#pragma once#include <iostream>
#include <string>
#include <cstring>
#include <unistd.h>
#include <time.h>
#include <stdlib.h>
#include <stdarg.h>
#include <fstream>
#include <pthread.h>namespace log_ns
{#define SCREE_TYPE 1
#define FILE_TYPE 2const char *gfilename = "log.txt";pthread_mutex_t gmutex = PTHREAD_MUTEX_INITIALIZER;enum{DEBUG = 1,INFO,WARNNING,ERROR,FATAL};std::string LevelTostrint(int level){switch (level){case DEBUG:return "DEBUG";break;case INFO:return "INFO";break;case WARNNING:return "WARNING";break;case ERROR:return "ERROR";break;case FATAL:return "FATAL";break;default:return "Unknow";}}class LogMessage{public:std::string _level;pid_t _id;std::string _filaname;int _filenumber;std::string _curr_time;std::string _logmsg;};std::string GetCurTime(){time_t timestamp = time(nullptr);tm *ptm = localtime(&timestamp);char buffer[128];snprintf(buffer, sizeof(buffer), "%d/%02d/%02d %02d:%02d:%02d",ptm->tm_year + 1900,ptm->tm_mon + 1,ptm->tm_mday,ptm->tm_hour,ptm->tm_min,ptm->tm_sec);return buffer;}class Log{public:Log(int type = SCREE_TYPE, std::string FILEName = gfilename): _type(type), _FILEName(gfilename){}~Log(){}void Print(int level, const char *filename, int filenumber, const char *msg, ...){LogMessage lmsg;lmsg._level = LevelTostrint(level);lmsg._id = getpid();lmsg._filaname = filename;lmsg._filenumber = filenumber;lmsg._curr_time = GetCurTime();// 处理可变参数va_list ap;va_start(ap, msg);char buffer[1024];vsnprintf(buffer, sizeof(buffer), msg, ap);lmsg._logmsg = buffer;va_end(ap);// 打印到指定文件pthread_mutex_lock(&gmutex);Flush(lmsg);pthread_mutex_unlock(&gmutex);}void Enable(int type){_type = type;}void FlushScree(const LogMessage &logMsg){printf("[%s][%d][%s][%d][%s] %s",logMsg._level.c_str(),logMsg._id,logMsg._filaname.c_str(),logMsg._filenumber,logMsg._curr_time.c_str(),logMsg._logmsg.c_str());}void FlushFILE(const LogMessage &logMsg){std::ofstream out(_FILEName.c_str(), std::fstream::app | std::fstream::out);if (!out.is_open()){perror("open fail");return;}char buffer[2048];snprintf(buffer, sizeof(buffer), "[%s][%d][%s][%d][%s] %s",logMsg._level.c_str(),logMsg._id,logMsg._filaname.c_str(),logMsg._filenumber,logMsg._curr_time.c_str(),logMsg._logmsg.c_str());out << buffer;out.close();}void Flush(const LogMessage &logMsg){switch (_type){case SCREE_TYPE:FlushScree(logMsg);break;case FILE_TYPE:FlushFILE(logMsg);break;}}private:int _type;std::string _FILEName;};Log lg;
#define LOG(LEVEL, format, ...)                                     \do                                                              \{                                                               \lg.Print(LEVEL, __FILE__, __LINE__, format, ##__VA_ARGS__); \} while (0)#define EnableScree()          \do                         \{                          \lg.Enable(SCREE_TYPE); \} while (0)#define EnableFILE()          \do                        \{                         \lg.Enable(FILE_TYPE); \} while (0)
}

整体来说并不是很难,但是这里的一些知识点对于有些同学过于偏僻,导致了整个处理过程有点无措。

日志的使用方法:

我们定义了宏,就避免了一些繁琐的步骤,比如创建一个对象再去调用。

另外,我们的宏也提供了改变输出文件的,使用也更方便。

#include "Log.hpp"using namespace log_ns;int main()
{EnableScree();LOG(DEBUG, "hello world%d\n", 666);EnableFILE();LOG(DEBUG, "hello world%d\n", 666);LOG(DEBUG, "hello world%d\n", 666);LOG(DEBUG, "hello world%d\n", 666);return 0;
}

当然,创建对象去调用Print也是可以的。

完~

相关文章:

【Linux】Linux下的日志(日常级)

日志是日后工作中非常重要的一部分&#xff0c;现在写一份简单的日志项目可以帮助我们熟悉并理解原理。 目录 设计思路&#xff1a;一些实现细节&#xff1a;代码&#xff1a;日志的使用方法&#xff1a; 设计思路&#xff1a; 图示是我们的最终目的。 设计一个类&#xff0…...

手把手教你如何在Linux上轻松安装Python,告别编程入门难题

导语&#xff1a; Python作为当下最热门的编程语言之一&#xff0c;受到了越来越多人的喜爱。对于Linux用户来说&#xff0c;掌握如何在Linux上安装Python至关重要。今天&#xff0c;就让我带领大家一步步在Linux上安装Python&#xff0c;让你轻松迈入编程世界&#xff01; 一…...

XSS-labs靶场(超详解)1-20关——附原码

level1 原码 <!DOCTYPE html><!--STATUS OK--><html> <head> <meta http-equiv"content-type" content"text/html;charsetutf-8"> <script> window.alert function() { confirm("完成的不错&#xff0…...

【网络安全】LockBit病毒入侵揭秘:如何防范与应对

文章目录 前言 主要特征攻击手段演进历程主要威胁防范与对策 如何入门学习网络安全【黑客】 【----帮助网安学习&#xff0c;以下所有学习资料文末免费领取&#xff01;----】 大纲学习教程面试刷题 资料领取 前言 在数字时代&#xff0c;随着科技的飞速发展&#xff0c;网络…...

《开源大模型食用指南》适合中国宝宝的部署教程,基于Linux环境快速部署开源大模型

本项目是一个围绕开源大模型、针对国内初学者、基于 AutoDL 平台的中国宝宝专属大模型教程&#xff0c;针对各类开源大模型提供包括环境配置、本地部署、高效微调等技能在内的全流程指导&#xff0c;简化开源大模型的部署、使用和应用流程&#xff0c;让更多的普通学生、研究者…...

体验教程:通义灵码陪你备战求职季

本场景将带大家体验在技术面试准备场景下&#xff0c;如何通过使用阿里云通义灵码实现高效的编程算法题练习 、代码优化、技术知识查询等工作&#xff0c;帮助开发者提升实战能力&#xff0c;更加从容地应对面试挑战。主要包括&#xff1a; 1、模拟题练习&#xff1a;精心挑选…...

(070)爬楼梯

思路&#xff1a;一次爬一个或者一次爬两个楼梯,终止条件&#xff0c;即是当n1或n2时&#xff0c;完成操作&#xff0c;当n>2时&#xff0c;总方法就等于一次爬一个楼梯的方法数加上一次爬两个楼梯的方法数。 解法一&#xff1a;递归解法 if(n 1)return 1;if(n 2)return 2…...

el-table 表格序号列前端实现递增,切换分页不从头开始

<el-table-column type"index" width"55" label"序号" :index"hIndex"> </el-table-column> 分页 <el-pagination size-change"handleSizeChange" current-change"handleCurrentChange"> <…...

NSSCTF-Web题目27(Nginx漏洞、php伪协议、php解析绕过)

目录 [HNCTF 2022 WEEK2]easy_include 1、题目 2、知识点 3、思路 [NSSRound#8 Basic]MyDoor 4、题目 5、知识点 6、思路 [HNCTF 2022 WEEK2]easy_include 1、题目 2、知识点 nginx日志漏洞执行系统命令 3、思路 打开题目&#xff0c;出现源码 题目要我们上传一个fi…...

分割损失:Dice vs. IoU

NSDT工具推荐&#xff1a; Three.js AI纹理开发包 - YOLO合成数据生成器 - GLTF/GLB在线编辑 - 3D模型格式在线转换 - 可编程3D场景编辑器 - REVIT导出3D模型插件 - 3D模型语义搜索引擎 - Three.js虚拟轴心开发包 - 3D模型在线减面 - STL模型在线切割 对于医学影像分割&#xf…...

SpringBoot整合Juint,ssm框架

目录 SpringBoot整合Juint 1.导入相关的依赖 2.创建测试类&#xff0c;使用注解SpringBootTest SpringBoot整合ssm框架 1.使用脚手架创建Spring项目 2.修改pom.xml 我先修改了SpringBoot的版本&#xff0c;修改为2.3.10.RELEASE&#xff0c;因为SpringBoot版本太高会出现…...

基于supervisor制作基于环境变量配置的redis

背景&#xff1a; redis 的镜像很多很多&#xff0c;但都需要直接修改配置文件&#xff0c;不符合我们公司当前环境变量解决一切容易配置的思路。 材料&#xff1a; 1、CentOS-Base.repo [base] nameCentOS-$releasever enabled1 failovermethodpriority baseurlhttp://mirr…...

动态规划part01 509. 斐波那契数 70. 爬楼梯 746. 使用最小花费爬楼梯

509. 斐波那契数 斐波那契数 &#xff08;通常用 F(n) 表示&#xff09;形成的序列称为 斐波那契数列 。该数列由 0 和 1 开始&#xff0c;后面的每一项数字都是前面两项数字的和。也就是&#xff1a; F(0) 0&#xff0c;F(1) 1 F(n) F(n - 1) F(n - 2)&#xff0c;其中 …...

CSS实现图片边框酷炫效果

一、前言 我们在浏览一些网页时&#xff0c;经常会看到一些好看酷炫的元素边框效果&#xff08;如下图&#xff09;&#xff0c;那么这些效果是怎么实现的呢&#xff1f;我们知道&#xff0c;一般的边框&#xff0c;要么是实线&#xff0c;要么是虚线&#xff08;点状&#xf…...

遇到 MySQL 死锁问题如何解决?

终于来到死锁检查线程的第三步&#xff0c;可以解决死锁了。 作者&#xff1a;操盛春&#xff0c;爱可生技术专家&#xff0c;公众号『一树一溪』作者&#xff0c;专注于研究 MySQL 和 OceanBase 源码。 爱可生开源社区出品&#xff0c;原创内容未经授权不得随意使用&#xff0…...

Pyinstaller打包OSError: could not get source code【终极解决】

pyinstaller 打包的时候&#xff0c;发现只要是torch.jit.script装饰的函数&#xff0c;会报以下错误&#xff1a; Traceback (most recent call last):File "torch/_sources.py", line 25, in get_source_lines_and_fileFile "inspect.py", line 1123, i…...

【计算机毕业设计】707高校宿舍管理系统

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…...

从C++看C#托管内存与非托管内存

进程的内存 一个exe文件&#xff0c;在没有运行时&#xff0c;其磁盘存储空间格式为函数代码段全局变量段。加载为内存后&#xff0c;其进程内存模式增加为函数代码段全局变量段函数调用栈堆区。我们重点讨论堆区。 托管堆与非托管堆 C# int a10这种代码申请的内存空间位于函…...

Linux进程间通信--IPC之无名管道

进程间通信&#xff08;IPC&#xff0c;InterProcess Communication&#xff09;是指在不同进程之间传播或交换信息。 IPC的方式通常有管道&#xff08;包括无名管道和命名管道&#xff09;、消息队列、信号量、共享存储、Socket、Streams支持不同主机上的两个进程的IPC。...

Oracle19c数据库system密码锁定

一、在oracle 19c数据库中&#xff0c;cdb中system用户被锁定&#xff0c;locked 二、所在的pdb中的system用户状态是正常的&#xff0c;但不可用&#xff0c;连接的时候提示账号已锁定 三、解决 在cdb中将system用户解锁。 alter user system account unlock;...

java之hashCode() 方法和 equals(Object obj) 方法之间的关系

1、 hashCode() 方法和 equals(Object obj) 在Java中&#xff0c;hashCode() 方法和 equals(Object obj) 方法之间的关系是紧密相连的&#xff0c;特别是在使用基于哈希的集合&#xff08;如 HashSet、HashMap、HashTable 等&#xff09;时。这两个方法共同决定了对象在哈希表…...

首届「中国可观测日」圆满落幕

首届中国可观测日&#xff08;Observability Day&#xff09;在上海圆满落幕&#xff0c;为监控观测领域带来了一场技术盛宴。作为技术交流的重要平台&#xff0c;此次活动不仅促进了观测云与亚马逊云科技之间的深化合作&#xff0c;更标志着双方共同推动行业发展的重要里程碑。…...

[Docker][Docker NetWork][下]详细讲解

目录 1.网络管理命令1.docker network creatre2.docker network inspect3.docker network connect4.docker network disconnect5.docker network prune6.docker network rm7.docker network ls 2.docker bridge 详解0.基本概念1.默认 bridge2.自定义 bridge3.DNS解析4.端口暴露…...

安卓系统在未来如何更好地解决隐私保护与数据安全的问题?

安卓系统可以通过以下方式更好地解决隐私保护与数据安全的问题&#xff1a; 强化权限控制&#xff1a;安卓系统可以进一步加强对应用程序权限的管理&#xff0c;确保用户能够清楚地知道应用程序需要哪些权限&#xff0c;并给予用户更多的控制权&#xff0c;例如允许用户选择性地…...

MySQL innodb单表上限一般多少

参考&#xff1a;https://www.zhihu.com/question/351797203/answer/3137174084 1.MySQL innodb单表上限为啥都说是2k万条 2.GaussDB for MySQL 为啥可以突破单表2k万的限制 要讨论这两个问题&#xff0c;得先明确性下实际的DB部署环境 表是索引数据是放在磁盘上的&#xf…...

更小、更安全、更透明:Google发布的Gemma推动负责任AI的进步

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…...

基于Django框架的医疗耗材管理系统的设计实现-计算机毕设定制-附项目源码(可白嫖)48999

摘 要 在目前的形势下&#xff0c;科技力量已成为我国的主要竞争力。而在科学技术领域&#xff0c;计算机的使用逐渐达到成熟&#xff0c;无论是从国家到企业再到家庭&#xff0c;计算机都发挥着其不可替代的作用&#xff0c;可以说计算机的可用领域遍及生活、工作的各个方面。…...

物联网协议篇(1):modbus tcp和modbusRTU的区别是什么?

Modbus TCP和Modbus RTU是Modbus协议中的两种主要变体,它们在多个方面存在显著的区别。以下是它们之间的主要区别: 1. 物理层和数据传输方式 Modbus TCP (TCP/IP): 使用以太网作为物理层,通过TCP/IP协议进行通信。数据以数据包的形式在TCP连接上传输,具有较高的通信速度和…...

JVM系列 | 对象的消亡——HotSpot的设计细节

HotSpot 的细节实现 文章目录 HotSpot 的细节实现OopMap 与 根节点枚举根节点类型及说明HotSpot中的实现 OopMap 与 安全点安全点介绍如何保证程序在安全点上&#xff1f; 安全区域记忆集与卡表记忆集卡表 写屏障并发的可达性分析&#xff08;与用户线程&#xff09;并发可达性…...

vue 运行或打包过程报错 JavaScript heap out of memory(内存溢出)

安装 increase-memory-limit npm install increase-memory-limit 运行increase-memory-limit ./node_modules/.bin/increase-memory-limit 运行后会报以下错误&#xff1a; "node --max-old-space-size10240" 不是内部或外部命令&#xff0c;也不是可运行的程序…...

暴雪网易2023后不代理了/seo外包费用

查看自己的ip和采用什么方式上网(网通/电信)http://www.whatchina.com/html/sip.asp本文转自 xcf007 51CTO博客&#xff0c;原文链接&#xff1a;http://blog.51cto.com/xcf007/161180&#xff0c;如需转载请自行联系原作者...

品牌自适应网站建设/开发一个网站的步骤流程

/** JDK1.5后出现的特性,自动装箱和自动拆箱* 自动装箱: 基本数据类型,直接变成对象* 自动拆箱: 对象中的数据变回基本数据类型* 方便使用* 自动装箱和拆箱弊端,可能出现空指针异常*/ public class IntegerDemo_2 {public static void main(String[] args) {function…...

asp.net做的小网站/上海seo网站推广公司

原标题&#xff1a;安卓电视/盒子很卡很慢原因及解决方法安卓电视以及机顶盒跟手机一样&#xff0c;在使用时间久了就会出现一些卡顿的现象&#xff0c;今天小编帮大家总结了一些导致安卓电视、盒子卡顿的原因&#xff0c;并且根据这些原因提出解决的办法&#xff0c;总有一个解…...

深圳网站建设推广平台/黑龙江新闻头条最新消息

数据类型介绍MySQL 数据类型分类整型浮点型字符类型(char与varchar)日期类型枚举与集合具体数据类型见这篇博客MySQL表操作中的约束primary key 主键约束 非空唯一unique key 唯一约束not null 非空约束foreign key 外键约束创建表的的语法CREATE TABLE[IF NOT EXISTS] tbl_nam…...

莱州网站建设公司/电商网站对比

问题提出&#xff1a;M&#xff08;如10亿&#xff09;个int整数&#xff0c;只有其中N个数重复出现过&#xff0c;读取到内存中并将重复的整数删除。 问题分析&#xff1a;我们肯定会先想到在计算机内存中开辟M个int整型数据数组&#xff0c;来one bye one读取M个int类型数组&…...

网站快照前显示中文怎么做的/seo黑帽教学网

很多文章Provider和Consumer的连接服务器地址brokeUrl都写成"tcp://192.168.1.139:61616" 并没有交代为啥是61616&#xff0c;而且我做实验换成别的端口就无法服务器 经过一番研究原来这个端口号可以在activemq.xml配置文件中修改&#xff1a; 参考文章&#xff1a; …...