1.造轮子的过程
代码托管在GitHub:https://github.com/zhangint/LogModule
在开发过程中,已经有现成的日志组件了,可以直接使用,但在平时自己开发的一些工具时,并不能直接使用公司现有的日志库。所以就开始自己造轮子,并集成到自己的代码库中去,方便以后复用,提高开发效率。
在开发过程中,复用了很多以前的代码,如模板队列等,所以有自己的代码库是很重要的一件事,可以极大的提高开发效率,这也是避免造轮子的过程。
2.简单说明
由于该组件实现比较简单,只实现了文本日志,如数据库日志,网络日志等均未实现,但可以在现有模块进行扩展。 就在这个地方对结构进行下说明,在网络代理组件中,并未叙述内部实现的机制,因为比较繁琐,但有内部机制的详细说明。
该日志组件为异步输出,内部有专门的输出线程进行输出处理,内部默认的日志级别有:
#define LOG_EXIT 0 //致命错误,程序即将退出
#define LOG_ERROR 1 //错误
#define LOG_WARNING 2 //程序状态警告
#define LOG_INFO 3 //相关信息输出
#define LOG_DEBUG 4 //调试状态
日志类型和日志文件一一对应,如计费日志,运行日志等,同时支持多个文件输出
内部采用了循环队列的方式,减少缓冲的重复分配和释放
3.内部结构说明
1.CLog:提供对外接口:
.日志模块初始化 init
/// log_level 内部日志等级
/// log_name 每种type对应的日志名(可以是路径)
///
void init(int log_level, std::vector<std::string> log_name);
2.写日志文本数据
///@brief:写日志信息
///@param: log_type -1 表示直接输出终端 , 0,1,2,3为log_name对应下的日志文件名
/// -2,-3等向下扩展,如网络日志,数据库日志等
void write_log(int log_type, int log_level, const char* buf, ...);
3.写数据日志,会将数据转化成16进制
///@brief:写数据信息,会写 16进制数据和ascii数据 用于对数据检测和调试状态下
///@param:buf数据缓冲区
/// len缓冲区长度
void write_data(int log_type, int log_level, const char* buf, int len);
4.CLogOutput 日志的具体实现
5.CMutex 互斥锁
6.CQueueAlloc 缓冲队列
7.CPubTools 积累的公共库函数
8.CThread 现成基类
9.CProCusQueue 预分配对列,采用了生产者消费者模型
4.测试用例
/*
*@brief:安全队列测试模板,由于操作系统为线程时间片的配置等因素,在进行密集投递数据时,
* 建议将队列大小设置成较大
*/
#include <iostream>
#include <sys/time.h>
#include <pthread.h>
#include <vector>
#include "Log.h"
#define LOG_RUN 0 //运行日志
#define LOG_COUNT 1 //计费日志
#define LOG_TEST 2 //错误状态日志
int main(void)
{
std::vector<std::string> namevec;
namevec.push_back("run.txt");
namevec.push_back("../run/count.txt");
namevec.push_back("error.txt");
CLog::instance()->init(LOG_DEBUG, namevec);
CLog* m_log = CLog::instance();
std::string str = "hello, this is a test.";
while (1)
{
m_log->write_log(LOG_RUN, LOG_INFO, "hello %d", 5);
m_log->write_log(LOG_COUNT, LOG_INFO, "hehe");
m_log->write_log(LOG_TEST, LOG_INFO, str.c_str());
char data[] = "00000000111111112222222233333333444444445555555566666666";
m_log->write_data(LOG_RUN, LOG_INFO, data, sizeof(data));
usleep(100);
//m_log->write_data(LOG_COUNT, LOG_INFO, "hehe");
//m_log->write_data(LOG_TEST, LOG_INFO, str.c_str());
}
while (1)
{
sleep(1);
}
return 0;
}