Linux-实现小型日志系统

目录

 一.日志

二.实现任意个数元素求和        

三.编写一个日志函数

        1.设置日志等级        

        2.设置日志时间

        3.设置日志的打印格式

        4.将日志的内容输出到文件             


 一.日志

                日志等级,日志时间,日志内容,文件的名称和行号

                日志等级:

                        Info:常规消息

                        Warning:报警消息

                        Error:错误,可能需要立即处理

                        Fatal:致命的

                        Debug:调试

二.实现任意个数元素求和        

                使用可变参数要使用若干个宏定义,这些宏定义在:        

//使用可变参数时一定要有一个具体的参数
int Sum(int n, ...)
{//用来提取可变参数的一个个参数,其实本质上就是一个char*类型的指针变量va_list s;//只向可变参数的首地址,内部封装了s = &n + 1;va_start(s, n);//实现求和int sum = 0;while(n){//根据类型提取参数va_arg(s, int);n--;}//s = NULL;va_end(s);return  sum;
}

        主函数调用:      

        此时我们传入的可变参数都是相同的类型的,如果传入不同的类型的话,就要像printf一样做获取的字符串处理。 

三.编写一个日志函数

        1.设置日志等级        
#define Info    0
#define DeBug   1
#define Warning 2
#define Error   3
#define Fatal   4//实现日志函数
void logmessage(int level, char* formatr, ...)
{}
        2.设置日志时间

                a.Linux中获取时间戳的函数                     

                b.Linux中转换时间戳的函数

                会将得到的时间戳转换为以下形式:               因为年和月都是从0开始计的所以在打印的时候,需要加1900和1。

void logmessage(int level, char* formatr, ...)
{//获取时间戳time_t t = 0;time(&t);//转换时间戳struct tm* ctime = NULL;ctime = localtime(&t);//打印获取到的时间printf("%d-%d-%d %d:%d:%d\n", ctime->tm_year + 1900, ctime->tm_mon + 1, ctime->tm_mday, ctime->tm_hour, ctime->tm_min, ctime->tm_sec);}
        3.设置日志的打印格式

                默认部分 + 自定义部分

                

#define Info            0
#define DeBug           1
#define Warning         2
#define Error           3
#define Fatal           4
#define Log_buffer_SIZE 1024string levelToString(int level)
{switch(level){case Info    : return "Info"    ;case DeBug   : return "DeBug"   ;case Warning : return "Warning" ;case Error   : return "Error"   ;case Fatal   : return "Fatal"   ;default:return "None";}
}//实现日志函数
void logmessage(int level, char* format, ...)
{//获取日志的等级string level_str;level_str = levelToString(level);//获取时间戳time_t t = 0;time(&t);//转换时间戳struct tm* ctime = NULL;ctime = localtime(&t);// //打印获取到的时间// printf("%d-%d-%d %d:%d:%d\n"//                     , ctime->tm_year + 1900, ctime->tm_mon + 1, ctime->tm_mday//                     , ctime->tm_hour, ctime->tm_min, ctime->tm_sec);//整合日志的默认部分char leftbuffer[Log_buffer_SIZE];snprintf(leftbuffer, sizeof(leftbuffer), "[%s][%d-%d-%d %d:%d:%d] : " ,level_str.c_str(), ctime->tm_year + 1900, ctime->tm_mon + 1, ctime->tm_mday, ctime->tm_hour, ctime->tm_min, ctime->tm_sec);//整合自定义部分va_list s;va_start(s, format);char rightbuffer[Log_buffer_SIZE];vsnprintf(rightbuffer, sizeof(rightbuffer), format, s);va_end(s);//整合默认部分和自定义部分char logtxt[Log_buffer_SIZE * 2];snprintf(logtxt, sizeof(logtxt), "%s%s\n", leftbuffer, rightbuffer);printf("%s", logtxt);
}
        4.将日志的内容输出到文件             
#include <time.h>
#include <string>
#include <stdio.h>
#include <stdarg.h>
#include <iostream>
#include <cstdio>
#include <cerrno>
#include <cstring>
#include <fcntl.h>
#include <unistd.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>using namespace std;#define Info 0
#define DeBug 1
#define Warning 2
#define Error 3
#define Fatal 4
#define Log_buffer_SIZE 1024string levelToString(int level)
{switch (level){case Info:return "Info";case DeBug:return "DeBug";case Warning:return "Warning";case Error:return "Error";case Fatal:return "Fatal";default:return "None";}
}#define Screen 1
#define Onefile 2
#define Classfile 3#define LogFile "log.txt"// 实现日志函数
class Log
{
public:Log(){printMethod = Screen;path = "./Log/";}void Enable(int method){printMethod = method;}void printLog(int level, const string& logtxt){switch (printMethod){case Screen:cout << logtxt.c_str() << endl;break;case Onefile:printOneFile(LogFile, logtxt);break;case Classfile:printClassFile(level, logtxt);break;default:break;}}void printOneFile(const string &logname, const string &logtxt){string _logname = path;_logname += logname;int fd = open(_logname.c_str(), O_WRONLY | O_CREAT | O_APPEND, 0666); // "log.txt"if (fd < 0)return;write(fd, logtxt.c_str(), logtxt.size());close(fd);}void printClassFile(int level, const string &logtxt){string filename = LogFile;filename += ".";filename += levelToString(level); // "log.txt.Debug/Warning/Fatal"printOneFile(filename, logtxt);}~Log(){}//处理日志等级string levelToString(int level){switch (level){case Info:return "Info";case DeBug:return "DeBug";case Warning:return "Warning";case Error:return "Error";case Fatal:return "Fatal";default:return "None";}}//实现日志方法void operator()(int level, char *format, ...){// 获取日志的等级string level_str;level_str = levelToString(level);// 获取时间戳time_t t = 0;time(&t);// 转换时间戳struct tm *ctime = NULL;ctime = localtime(&t);// 整合日志的默认部分char leftbuffer[Log_buffer_SIZE];snprintf(leftbuffer, sizeof(leftbuffer), "[%s][%d-%d-%d %d:%d:%d] : ", level_str.c_str(), ctime->tm_year + 1900, ctime->tm_mon + 1, ctime->tm_mday, ctime->tm_hour, ctime->tm_min, ctime->tm_sec);// 整合自定义部分va_list s;va_start(s, format);char rightbuffer[Log_buffer_SIZE];vsnprintf(rightbuffer, sizeof(rightbuffer), format, s);va_end(s);// 整合默认部分和自定义部分char logtxt[Log_buffer_SIZE * 2];snprintf(logtxt, sizeof(logtxt), "%s%s\n", leftbuffer, rightbuffer);// printf("%s", logtxt);printLog(level, logtxt);}private:int printMethod;string path;
};

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

UEFI下Windows10和Ubuntu22.04双系统安装图解

目录 简介制作U盘启动盘并从U盘启动电脑安装系统安装Windows系统安装Ubuntu 附录双系统时间不一致 简介 传统 Legacy BIOS主板下的操作系统安装可参考本人博客 U盘系统盘制作与系统安装&#xff08;详细图解&#xff09; &#xff0c;本文介绍UEFI主板下的双系统安装&#xff…

关于mysql高版本使用groupby导致的报错

在开发时&#xff0c;遇到mysql版本在5.7.X及以上版本时使用group by 语句会报以下的错误 Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column business_typ…

代码混淆技术探究与工具选择

引言 在软件开发中&#xff0c;保护程序代码的安全性是至关重要的一环。代码混淆&#xff08;Obfuscated code&#xff09;作为一种常见的保护手段&#xff0c;通过将代码转换成难以理解的形式来提升应用被逆向破解的难度。本文将介绍代码混淆的概念、方法以及常见的代码混淆工…

[Linux] Bash脚本多函数应该如何执行?使用eval提高脚本编写效率!

在工作过程中经常会编写一些测试脚本&#xff0c;有些脚本里有多个函数&#xff0c;要通过用户输入执行对应的函数&#xff0c;如这样&#xff1a; 这也太麻烦了吧 执行如下&#xff1a; 这样在函数多的情况下需要写很多判断&#xff0c;效率低下。 我们可以使用eval命令来进行…

『PyTorch学习笔记』如何快速下载huggingface模型/数据—全方法总结

如何快速下载huggingface模型/数据—全方法总结 文章目录 一. 如何快速下载huggingface大模型1.1. IDM(Windows)下载安装连接1.2. 推荐 huggingface 镜像站1.3. 管理huggingface_hub cache-system(缓存系统) 二. 参考文献 一. 如何快速下载huggingface大模型 推荐 huggingface…

MySQL-宋红康-(课P12-P13)-SQL分类和SQL的语言规则规范

b站课程&#xff1a; 12-SQL概述与SQL分类_哔哩哔哩_bilibili &#x1f436;7. SQL SQL&#xff1a;Structure Query Language结构化查询语言&#xff0c;它是使用关系模型的数据库应用语言&#xff0c;由IBM上世纪70年代开发出来。后由美国国家标准局&#xff08;ANSI&#…

java多线程(二)线程池

目录 java线程池 线程池应用场景&#xff1a; 如何创建线程池&#xff1a; 有什么区别&#xff1a; 不同线程池对应的应用场景 案例 输出结果 java线程池 Java线程池是一种预先创建一定数量的线程&#xff0c;并将任务提交给这些线程执行的机制。线程池可以避免频繁创建…

C++新经典模板与泛型编程:将trait类模板用作模板参数

将trait类模板用作模板参数 template<typename T> struct SumFixedTraits;template<> struct SumFixedTraits<char> {using sumT int;static sumT initValue() {return 0;} };template<> struct SumFixedTraits<int> {using sumT __int64;sta…

CCF刷题记录 -- 202305-2:矩阵运算 --python解法

2023.12.7 主要算法 矩阵置换矩阵相乘 满分注意点 运算顺序&#xff0c;利用了矩阵运算法则中的&#xff08;A*B&#xff09;*c A*(B*C) # 矩阵置换 def zhihuan(a):b[]for i in range(d):c []for j in range(n):c.append(a[j][i])b.append(c)return b# 矩阵相乘 def ju_zh…

高级多层次搭建企业级大数据项目, 成就全能型大数据开发实战经验思想

随着大数据技术的快速发展&#xff0c;企业越来越重视构建高效、可靠的大数据项目。本文将重点介绍如何高级多层次地搭建企业级大数据项目&#xff0c;并分享成为全能型大数据开发者的实战经验与思想。通过学习和应用这些技术&#xff0c;我们可以提升大数据项目的质量和效果。…

探索Vue小程序框架的底层原理

最近晚上有时间复盘之前研究小程序框架的相关内容&#xff0c;总结文章记录一下。 本篇文章主要介绍百度19年开源的Mars小程序开发框架&#xff0c;和Taro、mpvue、uniapp类似&#xff0c;都是编译型小程序框架&#xff0c;都是通过将 Vue 或 React 源码直接编译为小程序源码&a…

数据库字段名和sql关键字冲突报错解决方法

1、修改实体类字段映射。注解里加反引号 2、sql字段上加反引号 3、问题解决