这是一个基于线程安全行的日志记录解决方案,我在某个时候制作了。它使用boost mutex来保证线程安全。这是略超过必要的复杂,因为你可以在输出政策塞(它应该去的文件,标准错误,或别的地方?):
logger.h:
#ifndef LOGGER_20080723_H_
#define LOGGER_20080723_H_
#include <boost/thread/mutex.hpp>
#include <iostream>
#include <cassert>
#include <sstream>
#include <ctime>
#include <ostream>
namespace logger {
namespace detail {
template<class Ch, class Tr, class A>
class no_output {
private:
struct null_buffer {
template<class T>
null_buffer &operator<<(const T &) {
return *this;
}
};
public:
typedef null_buffer stream_buffer;
public:
void operator()(const stream_buffer &) {
}
};
template<class Ch, class Tr, class A>
class output_to_clog {
public:
typedef std::basic_ostringstream<Ch, Tr, A> stream_buffer;
public:
void operator()(const stream_buffer &s) {
static boost::mutex mutex;
boost::mutex::scoped_lock lock(mutex);
std::clog << now() << ": " << s.str() << std::endl;
}
private:
static std::string now() {
char buf[64];
const time_t tm = time(0);
strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", localtime(&tm));
return buf;
}
};
template<template <class Ch, class Tr, class A> class OutputPolicy, class Ch = char, class Tr = std::char_traits<Ch>, class A = std::allocator<Ch> >
class logger {
typedef OutputPolicy<Ch, Tr, A> output_policy;
public:
~logger() {
output_policy()(m_SS);
}
public:
template<class T>
logger &operator<<(const T &x) {
m_SS << x;
return *this;
}
private:
typename output_policy::stream_buffer m_SS;
};
}
class log : public detail::logger<detail::output_to_clog> {
};
}
#endif
用法如下:
logger::log() << "this is a test" << 1234 << "testing";
注缺乏'\n'
和std::endl
因为它是隐含的。内容被缓冲,然后使用模板指定策略以原子方式输出。这个实现也会在行的前面添加一个时间戳,因为它用于记录目的。 no_output
策略非常可选,这是我在禁用日志记录时使用的策略。
你如何想像创建线程本地缓冲区 “上钩” 到'标准:: cerr'会减少线程本地缓冲区“外部”的缓冲区,然后将全部行写入'std :: cerr'?缓冲区是一个缓冲区。 'std :: ostringstream'是一个典型的通用方法。 – 2010-12-15 03:46:49
你有没有机会寻找一个线程安全日志库? – yasouser 2010-12-15 03:47:27
我最近了解到了log4cpp项目(http://log4cpp.sourceforge.net/)。不确定它是否提供你正在寻找的东西!?!?也许值得检查一下。 – yasouser 2010-12-15 04:01:19