根据上一次的测试,有缓存的日志类性能会更好。用到了time.h类函数,所以在linux下就要改动一下了,windows环境下写的。
思路采用(参照muduo库的日志,不过认为他线程不安全,和没用缓存,就改造了下)
1.有一个总的缓存,logboss,为一个恶汉模式的单例类,指针对象为智能指针,析构函数讲缓存写入文件。
2.有一个logger类,作为临时缓存,析构函数,将里面的缓存写入总缓存(在总缓存写入的时候加锁)。如果缓存超过一定限度,就将前面的缓存写入文件先。
代码语言:javascript复制 void LogBoss::append( const char* data, int len )
{
std::unique_lock<std::mutex> l(mutex_);
if( buffer_.avail() > len ){
buffer_.append(data,len);
}else{
//write log file
writeLogFile();
buffer_.reset();
buffer_.append(data,len);
}
}
3.logger类中,有一个logstream类对象,支持各种基本类型的<<输入,然后将输入转化为字符串放入到这个对象里面缓存数组里。
4.使用一个SourceFile类,只是用来方便的获取文件名。
5.使用一个FixedBuffer类,方便对字符串数组的操作,append(),fflush()之类。
通过这样的宏定义:
代码语言:javascript复制#define LOG_TRACE cyc::Logger(__FILE__, __LINE__, cyc::Logger::TRACE, __FUNCTION__).stream()
#define LOG_DEBUG cyc::Logger(__FILE__, __LINE__, cyc::Logger::DEBUG, __FUNCTION__).stream()
代码语言:javascript复制class Logger
{
public:
enum LogLevel
{
TRACE,
DEBUG,
INFO,
WARN,
ERROR,
FATAL,
NUM_LOG_LEVELS,
};
Logger(SourceFile file, int line, LogLevel level, const char* func);
~Logger(void);
LogStream& stream(){ return stream_;}
private:
LogStream stream_;
};
调用方式为:(通过构造一个匿名Logger类对象,通过调用stream()返回一个Logstream对象来使用。
代码语言:javascript复制LOG_TRACE << "hello " << " " __FILE__ << " " << __FUNCTION__ << " " << __LINE__ ;
LOG_TRACE << "hello2 " << " " __FILE__ << " " << __FUNCTION__ << " " << __LINE__ ;
opeartor<< 将传入的参数都添加到临时变量的缓存中,缓存是LogStream的成员变量。最后在析构函数中,通过LogBoss的静态公开的方法,获取LogBoss指针,然后将临时变量的缓存加入到总缓存。
代码语言:javascript复制Logger::~Logger(void)
{
// add "n"
stream_ << "n";
//output to logboss
LogBoss::getInstance()->append(stream_.buffer().data(),stream_.buffer().length());
}
上代码了:
总过5个文件Logger.h,Logger.cpp,LogStream.h,LogStream.cpp,main.cpp
main.cpp
代码语言:javascript复制#include <iostream>
#include "Logger.h"
#include <future>
#include <thread>
#include <mutex>
#include <memory>
#include <fstream>
using namespace std;
void fun1(){
for(int i = 0; i <100;i ){
cout <<"thread : "<< this_thread::get_id() << " i = " << i << endl;
{
LOG_TRACE << i;
}
}
}
void fun2(){
for(int i = 0; i <100;i ){
cout <<"thread : "<< this_thread::get_id() << " i = " << i << endl;
{
LOG_TRACE << i;
}
}
}
void fun3(){
for(int i = 0; i <100;i ){
cout <<"thread : "<< this_thread::get_id() << " i = " << i << endl;
{
LOG_TRACE << i;
}
}
}
void getfilename(char * filename,size_t len)
{
time_t t = time(NULL);
tm st;
localtime_s(&st,&t);
//will fill '