Refer to Mudo logging written by win under logging

Source: Internet
Author: User
Tags mutex setcookie sprintf

#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 ();p rivate: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);p Rivate:intcreatelogfile (loggingenum Aloggingenum); Voidwrite (Loggingenum eloggingenum, char* msg, int msglen); void ThreadFunc ();p rivate:bool running_; File*m_file[log_end];typedef boost::p OSIx_time::p time ptime;std::stringm_appprestr;typedef fixedbuffer<klargebuffer> buffer;typedef boost::p tr_ 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:retur n 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) {CAs E 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 (+); Boost::mutex::scoped_lock lock (M_mutex); char szapppath[256] = "";:: GetModuleFileNameA (0, Szapppath, 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::p osix_time::microsec_clock::local_time () sprintf (tmp, "%s.%d%s:%d", Boost::p osix_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 = Curpo S + 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::p tr_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 (NUL L! = 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::p osix_time::to_iso_string (boost::p osix_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 (+); 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::p tr_container::move (NewBuffer1); Bufferstowrite.swap (Buffers_); if (!nextbuffer_) {nextbuffer_ = boost::p tr_container::move (NewBuffer2);}} ASSERT (!bufferstowrite.empty ()), if (Bufferstowrite.size () >) {bufferstowrite.erase (Bufferstowrite.begin () +2, Bufferstowrite.end ());} for (size_t i = 0; i < bufferstowrite.size (); ++i) {fwrite (Bufferstowrite[i].data (), Bufferstowrite[i].length (), 1, STD ERR); 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 ();}} 
For the time being, if you write multiple log levels, logging locks should be added.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.