這是一個基於線程安全行的日誌記錄解決方案,我在某個時候製作了。它使用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