参考mudo logging写的win下logging

来源:互联网 发布:php接收get数据 编辑:程序博客网 时间:2024/06/07 21:55
#pragma once#include <boost/noncopyable.hpp>#include <boost/scoped_ptr.hpp>#include <boost/ptr_container/ptr_vector.hpp>#include <boost/thread.hpp>#include <boost/thread/mutex.hpp>class CountDownLatch : boost::noncopyable{public:explicit CountDownLatch(int count);void wait();void countDown();int getCount();private:boost::mutexm_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 <string>#include <boost/noncopyable.hpp>using namespace std;const int kSmallBuffer = 4000;const int kLargeBuffer = 4000*1000;template<int SIZE>class FixedBuffer : boost::noncopyable{public:FixedBuffer(): cur_(data_){setCookie(cookieStart);}~FixedBuffer(){setCookie(cookieEnd);}void append(const char*  buf, size_t len){if (static_cast<size_t>(avail()) > len){memcpy(cur_, buf, len);cur_ += len;}}const char* data() const { return data_; }int length() const { return static_cast<int>(cur_ - data_); }// write to data_ directlychar* current() { return cur_; }int avail() const { return static_cast<int>(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 <boost/date_time/posix_time/posix_time.hpp> #include "boost/date_time/gregorian/gregorian.hpp"#include "boost/atomic/atomic.hpp"#include <queue>#include <string>#include <boost/bind.hpp>#include <boost/noncopyable.hpp>#include <boost/scoped_ptr.hpp>#include <boost/ptr_container/ptr_vector.hpp>#include <boost/thread.hpp>#include <boost/thread/mutex.hpp>#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();voidWriteWithFunLine(LoggingEnum eLoggingEnum, char* fun, int line, char* msg, ...);voidWriteMsg(LoggingEnum eLoggingEnum, char* fun, int line, char* msg);private:intCreateLogFile(LoggingEnum aLoggingEnum);voidWrite(LoggingEnum eLoggingEnum, char* msg, int msgLen);void threadFunc();private:bool running_;FILE*m_File[LOG_END];typedef boost::posix_time::ptime PTIME;std::stringm_AppPreStr;typedef FixedBuffer<kLargeBuffer> Buffer;typedef boost::ptr_vector<Buffer> BufferVector;typedef BufferVector::auto_type BufferPtr;BufferPtr currentBuffer_;BufferPtr nextBuffer_;BufferVector buffers_;boost::threadm_Thread;boost::mutexm_Mutex;boost::condition_variable m_ConditionVar;CountDownLatch latch_;};

#include "Logging.h"#include <iomanip>#include <sstream>#include <fcntl.h>#include <io.h>#include <Windows.h>#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_WINDOWSGLogColor 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_END; ++i){m_File[i] = NULL;}n32Res = CreateLogFile(LOG_INFO);if (n32Res != 0){printf("Createfile(i) failed", 0);}lock.unlock();running_ = true;m_Thread = boost::thread(&Logging::threadFunc, this);latch_.wait();}void Logging::WriteWithFunLine(LoggingEnum eLoggingEnum, char* fun, int line, char* msg, ...){if (eLoggingEnum < LOG_INFO || eLoggingEnum > 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 < 4; ++i){if (NULL != m_File[i]){fclose(m_File[i]);}}}int Logging::CreateLogFile(LoggingEnum aLoggingEnum){string strPre;switch (aLoggingEnum){case LOG_DBBUG:strPre = "DBBUG";break;case LOG_INFO:strPre = "INFO";break;case LOG_WARNNING:strPre = "WARNNING";break;case LOG_ERROR:strPre = "ERROR";break;}char str[128];sprintf(str, "./Log/%s-%s-%d-%s", m_AppPreStr.c_str(), strPre.c_str() ,boost::this_thread::get_id(), boost::posix_time::to_iso_string(boost::posix_time::microsec_clock::local_time()).c_str());string fileName(str);fileName += ".log";int fd = open(fileName.c_str(), O_WRONLY | O_CREAT | O_EXCL, 0664);if (fd == -1){printf("%s create(%d) file error\n", __FUNCTION__, aLoggingEnum);return -1;}m_File[aLoggingEnum] = fdopen(fd, "a");if (NULL == m_File[aLoggingEnum]){printf("%s open file(%d) failed\n", __FUNCTION__, aLoggingEnum);return -1;}return 0;}void Logging::threadFunc(){assert(running_ == true);latch_.countDown();BufferPtr newBuffer1(new Buffer);BufferPtr newBuffer2(new Buffer);newBuffer1->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 < buffersToWrite.size(); ++i){fwrite(buffersToWrite[i].data(), buffersToWrite[i].length(), 1, stderr);fflush(stderr);fwrite(buffersToWrite[i].data(), 1, buffersToWrite[i].length(), m_File[0]);fflush(m_File[0]);}if (buffersToWrite.size() > 2){// drop non-bzero-ed buffers, avoid trashingbuffersToWrite.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的锁 应该如何加。
0 0
原创粉丝点击