标签:color os art for cti io
#pragma once
#include
#include
#include
#include
#include
class CountDownLatch : boost::noncopyable
{
public:
explicit CountDownLatch(int count);
void wait();
void countDown();
int getCount();
private:
boost::mutex m_Mutex;
boost::condition_variable m_ConditionVar;
int count_;
};
#include "stdafx.h"
#include "CountDownLatch.h"
CountDownLatch::CountDownLatch(int count)
: count_(count)
{
}
void CountDownLatch::wait()
{
boost::mutex::scoped_lock lock(m_Mutex);
while (count_ > 0) {
m_ConditionVar.wait(lock);
}
}
void CountDownLatch::countDown()
{
boost::mutex::scoped_lock lock(m_Mutex);
--count_;
if (count_ == 0) {
m_ConditionVar.notify_all();
}
}
int CountDownLatch::getCount()
{
boost::mutex::scoped_lock lock(m_Mutex);
return count_;
}
#pragma once
#include
#include
using namespace std;
const int kSmallBuffer = 4000;
const int kLargeBuffer = 4000*1000;
template
class FixedBuffer : boost::noncopyable
{
public:
FixedBuffer()
: cur_(data_)
{
setCookie(cookieStart);
}
~FixedBuffer()
{
setCookie(cookieEnd);
}
void append(const char* buf, size_t len)
{
if (static_cast(avail()) > len)
{
memcpy(cur_, buf, len);
cur_ += len;
}
}
const char* data() const { return data_; }
int length() const { return static_cast(cur_ - data_); }
// write to data_ directly
char* current() { return cur_; }
int avail() const { return static_cast(end() - cur_); }
void add(size_t len) { cur_ += len; }
void reset() { cur_ = data_; }
void bzero() { memset(data_, 0, sizeof(data_)); }
void setCookie(void (*cookie)()) { cookie_ = cookie; }
string asString() const { return string(data_, length()); }
private:
const char* end() const { return data_ + sizeof data_; }
// Must be outline function for cookies.
static void cookieStart();
static void cookieEnd();
void (*cookie_)();
char data_[SIZE];
char* cur_;
};
#pragma once
#include
#include "boost/date_time/gregorian/gregorian.hpp"
#include "boost/atomic/atomic.hpp"
#include
#include
#include
#include
#include
#include
#include
#include
#include "FixedBuffer.h"
#include "CountDownLatch.h"
enum LoggingEnum{
LOG_INFO,
LOG_DBBUG,
LOG_ERROR,
LOG_WARNNING,
LOG_END
};
enum GLogColor {
COLOR_DEFAULT,
COLOR_RED,
COLOR_GREEN,
COLOR_YELLOW
};
class Logging
{
public:
Logging();
~Logging();
void WriteWithFunLine(LoggingEnum eLoggingEnum, char* fun, int line, char* msg, ...);
void WriteMsg(LoggingEnum eLoggingEnum, char* fun, int line, char* msg);
private:
int CreateLogFile(LoggingEnum aLoggingEnum);
void Write(LoggingEnum eLoggingEnum, char* msg, int msgLen);
void threadFunc();
private:
bool running_;
FILE* m_File[LOG_END];
typedef boost::posix_time::ptime PTIME;
std::string m_AppPreStr;
typedef FixedBuffer Buffer;
typedef boost::ptr_vector BufferVector;
typedef BufferVector::auto_type BufferPtr;
BufferPtr currentBuffer_;
BufferPtr nextBuffer_;
BufferVector buffers_;
boost::thread m_Thread;
boost::mutex m_Mutex;
boost::condition_variable m_ConditionVar;
CountDownLatch latch_;
};
#include "Logging.h"
#include
#include
#include
#include
#include
#include "SSActive.h"
Logging g_Logging;
string LOGPreStr[LOG_END] = {"LOG_INFO", "LOG_DBBUG", "LOG_ERROR", "LOG_WARNNING"};
#ifdef _WINDOWS
// Returns the character attribute for the given color.
WORD GetColorAttribute(GLogColor color) {
switch (color) {
case COLOR_RED: return FOREGROUND_RED;
case COLOR_GREEN: return FOREGROUND_GREEN;
case COLOR_YELLOW: return FOREGROUND_RED | FOREGROUND_GREEN;
default: return 0;
}
}
#else
// Returns the ANSI color code for the given color.
const char* GetAnsiColorCode(GLogColor color) {
switch (color) {
case COLOR_RED: return "1";
case COLOR_GREEN: return "2";
case COLOR_YELLOW: return "3";
case COLOR_DEFAULT: return "";
};
return NULL; // stop warning about return type.
}
#endif // OS_WINDOWS
GLogColor GLogColorVec[LOG_END] = {COLOR_GREEN, COLOR_DEFAULT, COLOR_RED, COLOR_YELLOW};
Logging::Logging():latch_(1){
currentBuffer_.reset(new Buffer);
currentBuffer_->bzero();
nextBuffer_.reset(new Buffer);
nextBuffer_->bzero();
buffers_.reserve(16);
boost::mutex::scoped_lock lock(m_Mutex);
char szAppPath[256] = "";
::GetModuleFileNameA(0, szAppPath, 256);
m_AppPreStr = szAppPath;
m_AppPreStr = m_AppPreStr.substr(m_AppPreStr.rfind("\\") + 1);
m_AppPreStr = m_AppPreStr.substr(0, m_AppPreStr.size()-4);
int n32Res = 0;
for (int i = LOG_INFO; i LOG_WARNNING){
eLoggingEnum = eLoggingEnum;
}
char tmp[1024] = {0};
PTIME nowTime = boost::posix_time::microsec_clock::local_time();
sprintf(tmp, "%s.%d %s:%d ", boost::posix_time::to_iso_string(nowTime).c_str(), boost::this_thread::get_id(), fun, line);
int curPos = strlen(tmp);
va_list pArg = NULL;
va_start(pArg, msg);
vsprintf(tmp+curPos, msg, pArg);
va_end(pArg);
curPos = strlen(tmp);
char end[] = "\n";
sprintf(tmp + curPos, "%s", end);
int totlen = curPos + 1;
boost::mutex::scoped_lock lock(m_Mutex);
if (currentBuffer_->avail() > totlen)
{
currentBuffer_->append(tmp, totlen);
}
else
{
buffers_.push_back(currentBuffer_.release());
if (nextBuffer_)
{
currentBuffer_ = boost::ptr_container::move(nextBuffer_);
}
else
{
currentBuffer_.reset(new Buffer); // Rarely happens
}
currentBuffer_->append(tmp, totlen);
m_ConditionVar.notify_all();
}
}
Logging::~Logging(){
running_ = false;
m_ConditionVar.notify_all();
m_Thread.join();
for (INT32 i = 0; i bzero();
newBuffer2->bzero();
BufferVector buffersToWrite;
buffersToWrite.reserve(16);
while (running_)
{
assert(newBuffer1 && newBuffer1->length() == 0);
assert(newBuffer2 && newBuffer2->length() == 0);
assert(buffersToWrite.empty());
{
boost::mutex::scoped_lock lock(m_Mutex);
if (buffers_.empty()) // unusual usage!
{
m_ConditionVar.wait(lock);
}
buffers_.push_back(currentBuffer_.release());
currentBuffer_ = boost::ptr_container::move(newBuffer1);
buffersToWrite.swap(buffers_);
if (!nextBuffer_)
{
nextBuffer_ = boost::ptr_container::move(newBuffer2);
}
}
assert(!buffersToWrite.empty());
if (buffersToWrite.size() > 25)
{
buffersToWrite.erase(buffersToWrite.begin()+2, buffersToWrite.end());
}
for (size_t i = 0; i 2)
{
// drop non-bzero-ed buffers, avoid trashing
buffersToWrite.resize(2);
}
if (!newBuffer1)
{
assert(!buffersToWrite.empty());
newBuffer1 = buffersToWrite.pop_back();
newBuffer1->reset();
}
if (!newBuffer2)
{
assert(!buffersToWrite.empty());
newBuffer2 = buffersToWrite.pop_back();
newBuffer2->reset();
}
buffersToWrite.clear();
}
}
暂时还没想清楚,如果写多个日志等级,logging的锁 应该如何加。参考mudo logging写的win下logging,搜素材,soscw.com
参考mudo logging写的win下logging
标签:color os art for cti io
原文地址:http://blog.csdn.net/boyxiaolong/article/details/37719487