Simplifies the glog, only retains the function of writing log files, only to rewrite the Linux version, the win version is not rewritten, you can use
Log (INFO) << output logs
Log_if (info,condition) << output logs are also available
You can also call the Log Class Logger::getinstance () directly. Error and other ways to write a log
Call Initlogging (Argv[0],info, "./log/test") when initializing;
The first parameter is the path, the second parameter is the lowest log level, and the third parameter represents the prefix and folder of the log file
FileHelper.h
#ifndef Filehelper_h_
#define Filehelper_h_
#include <string>
#include <vector>
#include <fstream>
#include <stdio.h>
#ifdef _WIN32
#include <direct.h>
#include <io.h>
#else
#include <stdarg.h>
#include <sys/stat.h>
#endif
Namespace FrameWork {
#ifdef _WIN32
#define ACCESS _access
#define MKDIR (a) _mkdir ((a))
#else
#define Access Access
#define MKDIR (a) MKDIR ((a), 0755)
#endif
Class Filehelper {
Public
static bool Save (const std::string filename, std::string& content)
{
FILE *file = fopen (Filename.c_str (), "WB");
if (file = = NULL)
return false;
Fwrite (Content.c_str (), sizeof (char), content.size (), file);
fclose (file);
return true;
}
Used to open binary file
static bool Open (const std::string filename, std::string& content)
{
FILE *file = fopen (Filename.c_str (), "RB");
if (file = = NULL)
return false;
fseek (file, 0, seek_end);
int len = ftell (file);
rewind (file);
content.clear ();
Char *buffer = new Char[len];
fread (buffer, sizeof (char), Len, file);
content.assign (buffer, Len);
Delete []buffer;
//int nread;
//content.clear ();
//char buffer[80];
//while (!feof (file)) {
// nread = fread (buffer,sizeof (char), sizeof (buffer), file);
// if (nread > 0) {
// content.append (buffer);
&NBSP;&NBSP;//&NBSP}
//}
fclose (file);
return true;
}
Used to open text file
static bool Open (const std::string file_name, std::vector<std::string>& lines)
{
Std::ifstream file (File_name.c_str (), std::ios::in);
if (!file)
{
return false;
}
Lines.clear ();
Char Buffer[buffer_size];
while (file.getline (buffer, buffer_size, ' \ n '))
{
Lines.push_back (buffer);
}
return true;
}
static bool Createdir (const char *pszdir)
{
size_t i = 0;
size_t IRet;
size_t Ilen = strlen (Pszdir);
char* Buf=new char[ilen+1];
strncpy (buf,pszdir,ilen+1);
for (i = 0;i < Ilen;i + +) {
if (pszdir[i] = = ' \ ' | | pszdir[i] = = '/') {
Buf[i] = ' the ';
If it does not exist, create
IRet = ACCESS (buf,0);
if (iRet!= 0) {
IRet = MKDIR (BUF);
if (iRet!= 0) {
Delete[] BUF;
return false;
}
}
Support Linux, replace all \
Buf[i] = '/';
}
}
Delete[] BUF;
return true;
}
Private
enum {buffer_size = 3000};
};
}/* Namespace FrameWork * *
#endif/* Filehelper_h_ * *
[/code]
Logger.cpp
Copy Code code as follows:
#include "Logger.h"
#include <cstring>
#include <time.h>
#include <cstdarg>
#include <cstdlib>
#include <assert.h>
#include "FileHelper.h"
#include "Mutex.h"
Namespace FrameWork {
Mutex Logmessage::mutex;
static char _defaltfolder[]= "/var/tmp/";
static Char _appname[maxfilepathlen];
static Char _appfolder[maxfilepathlen];
static Char _destfolder[maxfilepathlen];
static Char _destprefix[maxfilepathlen];
static LogLevel _destlevel;
Static Char _levelinfos[][16]={
"Debug", "Info", "Warn", "Error", "Fatal"
};
const int buffer_size = 8196;
static Char _gbuffer[buffer_size];
void Combine_folder (char** destpath, char* basefolder,char* relativefolder)
{
int lenb = strlen (Basefolder);
int lenr = strlen (Relativefolder);
char* pret = (char*) malloc ((lenb+lenr+1) *sizeof (char));
int pos=lenb-1;
memset (pret,0,lenb+lenr+1);
while (pos>0 && (basefolder[pos]!= '/'))
pos--;
strncpy (*destpath,basefolder,pos+1);
if (relativefolder[0] = = ' \ ' | | relativefolder[0] = = '/') {
strncpy (*DESTPATH+POS+1,RELATIVEFOLDER+1,LENR-1);
}else{
strncpy (*DESTPATH+POS+1,RELATIVEFOLDER,LENR);
}
}
static void Initpaths (const char* filename,const char* Destfolder)
{
memset (_appname,0,maxfilepathlen);
memset (_appfolder,0,maxfilepathlen);
memset (_destfolder,0,maxfilepathlen);
memset (_destprefix,0,maxfilepathlen);
strcpy (_appname,filename);
int len = strlen (filename), lend;
int pos = Len-1,posd,start;
while (POS >0 && Filename[pos]!= Pathsplitchar)
pos--;
strncpy (_appfolder,filename,pos+1);
Lend = strlen (Destfolder);
Posd = lend-1;
if (Destfolder[lend-1]!= Pathsplitchar) {
Has prefix
while (Posd >0 && destfolder[posd]!= Pathsplitchar)
posd--;
}
if (destfolder[0] = = '. ' && destfolder[1] = = Pathsplitchar) {
strncpy (_destfolder,filename,pos+1);
start = 2;
} else{
pos = 8;
strcpy (_destfolder,_defaltfolder);
if (Destfolder[0]!= Pathsplitchar) {
start = 0;
}else{
start = 1;
}
}
strncpy (_destfolder+pos+1,destfolder+start,posd-start+1);
strncpy (_destprefix,filename,pos+1);
strncpy (_destprefix+pos+1,destfolder+start,lend-start);
}
void initlogging (const char* filename,loglevel minlevel,const char* destfolder)
{
Initpaths (Filename,destfolder);
_destlevel = MinLevel;
}
static string getlocaldate (void)
{
time_t t = time (0);
TM *ld;
Char tmp[64] = "";
Ld=localtime (&t);
Strftime (tmp,sizeof (TMP), "%y-%m-%d", LD);
return string (TMP);
}
static string Getcurtime (void)
{
time_t t = time (0);
TM *ld;
Char tmp[64] = "";
Ld=localtime (&t);
Strftime (tmp,sizeof (TMP), "%y-%m-%d%h:%m:%s", LD);
return string (TMP);
}
Logger::logger (loglevel Level,char * Folder,char * prefix)
: Level (Level)
{
std::string path;
Path.append (prefix);
Path.append (Getlocaldate ());
Path.append (". Log");
Filehelper::createdir (folder);
Logprefix.append (prefix);
LogPath = path;
Logfile.open (Path.c_str (), ios::app|ios::out);
logfile<< "Log file created at:" <<getcurtime () <<endl;
}
Logger::~logger () {
Logfile.close ();
}
#define IMPLEMENT_LOG_FUNC1 (CNAME,FNAME,LV) \
void Cname::fname (String msg) {\
If (level <= LV) {\
Writermutexlock Lock (&mutex); \
logfile<< "[" <<getcurtime (). C_STR () << "[" #lv] "<<msg.c_str () <<endl;\
Logfile.flush (); \
}\
}
#define PRINT_ARGS_TO_BUFFER (FMT,BUF) \
{\
memset (buf,0,sizeof (buf)); \
Va_list argp;\
Va_start (ARGP,FMT);
vsprintf (BUF,FMT,ARGP);
Va_end (ARGP);
}
#define IMPLEMENT_LOG_FUNC2 (CNAME,FNAME,LV) \
void Cname::fname (const char* format,...) {\
If (level <= LV) {\
Writermutexlock Lock (&mutex); \
Print_args_to_buffer (Format,_gbuffer) \
logfile<< "[" <<getcurtime (). C_STR () << "] [" #lv] "<<_gbuffer<<endl;\
Logfile.flush (); \
}\
}
#define IMPLEMENT_LOG_FUNC (CNAME,FNAME,LV) \
IMPLEMENT_LOG_FUNC1 (CNAME,FNAME,LV) \
IMPLEMENT_LOG_FUNC2 (CNAME,FNAME,LV)
Implement_log_func (Logger,debug,debug)
Implement_log_func (Logger,info,info)
Implement_log_func (Logger,warn,warn)
Implement_log_func (Logger,error,error)
Implement_log_func (Logger,fatal,fatal)
logger& logger::getinstance () {
Static Logger _logger (_destlevel,_destfolder,_destprefix);
return _logger;
}
void Logger::log (loglevel lv, string msg) {
If (level <= LV) {
Writermutexlock Lock (&mutex);
logfile<< "[" <<getcurtime (). C_STR () << "[" <<_levelInfos[lv+1]<<] "<<msg.c_ STR () <<endl;
Logfile.flush ();
}
}
void Logger::log (loglevel lv, const char* format,...) {
If (level <= LV) {
Writermutexlock Lock (&mutex);
Print_args_to_buffer (Format,_gbuffer)
logfile<< "[" <<getcurtime (). C_STR () << "[" <<_levelInfos[lv+1]<<] "<<_gbuffer <<endl;
Logfile.flush ();
}
}
void Logger::log (const char* file, int line, loglevel lv, string msg) {
If (level <= LV) {
Writermutexlock Lock (&mutex);
logfile<< "[" <<getcurtime (). C_STR () << "[" <<_levelInfos[lv+1]<< "] [" <<file << "[" <<line<< "]" <<msg.c_str ();
Logfile.flush ();
}
}
logger* Logger::getinstanceptr () {
return &getinstance ();
}
void Logger::log (const char* file, int line, loglevel LV, const char* format,...) {
If (level <= LV) {
Writermutexlock Lock (&mutex);
Print_args_to_buffer (Format,_gbuffer)
logfile<< "[" <<getcurtime (). C_STR () << "[" <<_levelInfos[lv+1]<< "] [" <<file << "[" <<line<< "]" <<_gBuffer;
Logfile.flush ();
}
}
Logmessage::logmessage (const char* file, int line, loglevel LV) {
Logger = Logger::getinstanceptr ();
Mutex. Lock ();
Logger->log (FILE,LINE,LV, "");
}
Logmessage::~logmessage () {
Logger->stream () <<endl;
Logger->stream (). Flush ();
Mutex. Unlock ();
}
}/* Namespace FrameWork * *
Logger.h
Copy Code code as follows:
#ifndef Logger_h_
#define Logger_h_
#include "ILogger.h"
#include "Mutex.h"
#include <fstream>
#include <string>
const int Maxfilepathlen = 1024;
const char Pathsplitchar = '/';
Namespace FrameWork {
Enum loglevel{
<summary>
Debugging
</summary>
DEBUG =-1,
<summary>
Normal log
</summary>
INFO = 0,
<summary>
Warning
</summary>
WARN,
<summary>
Error
</summary>
ERROR,
<summary>
Collapse
</summary>
FATAL,
<summary>
Error level exceeded
</summary>
Off
};
Class ILogger {
Public
//
Virtual ~ilogger () {}
#define ABSTRACT_LOG_FUNC (name) \
virtual void name (string msg) = 0; \
virtual void name (const char* FMT,...) = 0;
Abstract_log_func (Debug)
Abstract_log_func (Info)
Abstract_log_func (Warn)
Abstract_log_func (Error)
Abstract_log_func (Fatal)
#undef Abstract_log_func
#define ABSTRACT_LOG_FUNC_X (name) \
virtual void name (loglevel lv,string msg) = 0; \
virtual void name (loglevel lv,const char* fmt,...) =0;\
virtual void name (const char* file,int line,loglevel lv,string msg) =0;\
virtual void name (const char* file,int line,loglevel lv,const char* fmt,...) = 0;
Abstract_log_func_x (LOG)
#undef log_func_x
};
Class Logger:public ILogger {
Std::string LogPath;
Std::string Logprefix;
Std::fstream LogFile;
LogLevel level;
Mutex mutex;
Logger (loglevel Level,char * folder,char * prefix);
Public
Static logger& getinstance ();
Static logger* getinstanceptr ();
Virtual ~logger ();
Inline FStream & Stream () {return logFile;}
#define DECLARE_LOG_FUNC (name) \
virtual void name (string msg); \
virtual void name (const char* FMT,...);
#define DECLARE_LOG_FUNC_X (name) \
virtual void name (LogLevel lv,string msg); \
virtual void name (loglevel lv,const char* fmt,...); \
virtual void name (const char* file,int line,loglevel lv,string msg); \
virtual void name (const char* file,int line,loglevel lv,const char* fmt,...);
Declare_log_func (Debug)
Declare_log_func (Info)
Declare_log_func (Warn)
Declare_log_func (Error)
Declare_log_func (Fatal)
Declare_log_func_x (LOG)
#undef declare_log_func_x
#undef Declare_log_func
};
Class LogMessage {
logger* Logger;
static mutex mutex;
Public
LogMessage (const char* file, int line,loglevel LV);
ostream& Stream () {return Logger->stream ();}
Virtual ~logmessage ();
};
void initlogging (const char* filename,loglevel minlevel,const char* destfolder);
void Closelogging ();
#define LOG (Level) LogMessage (__file__, __line__,level). Stream ()
#define LOG_IF (severity, condition) \
! (condition)? (void) 0:log (severity)
#define LOG_ASSERT (condition) \
Log_if (FATAL,!) ( Condition) << "Assert failed:" #condition
#define CHECK (condition) \
Log_if (FATAL,!) ( condition)) \
<< Check failed: "#condition"
}/* Namespace FrameWork * *
#endif/* Logger_h_ * *
Main.cpp
Copy Code code as follows:
#include <iostream>
#include "Logger.h"
using namespace Std;
using namespace FrameWork;
int main (int argc,char* argv[]) {
Initlogging (Argv[0],info, "./log/test");
cout << "!!! Hello World!!! "<< Endl; Prints!!! Hello World!!!
LOG (Info) << "info test";
LOG (WARN) << "WARN TEST%d" <<20;
LOG (Error) << "error test%d%s" <<20<< "Nihao";
Logger::getinstance (). Error ("Error test common");
Logger::getinstance (). Fatal ("Fatal test common%d", 100);
Logger::getinstance (). info ("Info test normal%d%s", M, "Zhongguoren");
return 0;
}
Mutex.h
Copy Code code as follows:
#ifndef Mutex_h_
#define Mutex_h_
#include <pthread.h>
#include <stdlib.h>
Namespace FrameWork {
typedef pthread_mutex_t MUTEXTYPE;
Class Mutex {
Public
Create A Mutex This is isn't held by anybody. This constructor is
Typically used for mutexes allocated on the heap or the stack.
Below for a recommendation for constructing global Mutex
Objects.
inline Mutex ();
destructor
inline ~mutex ();
inline void Lock (); //block if needed until free then acquire exclusively
inline void Unlock (); //Release a lock acquired via lock ()
inline bool Trylock ();//If free, lock () and return True. else return false
//Note this to systems that don ' t support Read-write locks, this may
//is implemen Ted as synonyms to Lock () and Unlock () . I can use
//this for efficiency, but don ' t use them anyplace Where being able
//to do shared reads are necessary to avoid deadlock.
inline void ReaderLock (); //block until free or shared then acquire a share
inline void Reader Unlock (); Release a read share the This Mutex
inline void WriterLock () {Lock ();} //Acquire a exclusive lock
inline void Writerunlock () {Unlock ();}//Release a lock From WriterLock ()
TODO (Hamaji): Doing nothing, implement correctly.
inline void Assertheld () {}
Private
Mutextype mutex_;
We want to do sure that the compiler sets Is_safe_ to True only
When we tell it to, and never makes assumptions is_safe_ is
Always true. Volatile is the most reliable way.
volatile bool Is_safe_;
inline void Setissafe () {is_safe_ = true;}
Catch the error of writing Mutex when intending mutexlock.
Mutex (mutex*/*ignored*/) {}
Disallow "evil" constructors
Mutex (const mutex&);
void operator= (const mutex&);
};
#define SAFE_PTHREAD (Fncall) do {/* run Fncall if Is_safe_ is true * *
if (Is_safe_ && fncall (&mutex_)!= 0) abort (); \
} while (0)
Mutex::mutex () {
Setissafe ();
if (Is_safe_ && pthread_mutex_init (&mutex_, NULL)!= 0) abort ();
}
Mutex::~mutex () {safe_pthread (Pthread_mutex_destroy);}
void Mutex::lock () {safe_pthread (pthread_mutex_lock);}
void Mutex::unlock () {safe_pthread (pthread_mutex_unlock);}
BOOL Mutex::trylock () {return is_safe_?
Pthread_mutex_trylock (&mutex_) = = 0:true; }
void Mutex::readerlock () {Lock ();}
void Mutex::readerunlock () {Unlock ();}
Class Mutexlock {
Public
Explicit Mutexlock (Mutex *mu): Mu_ (mu) {mu_->lock ();}
~mutexlock () {Mu_->unlock ();}
Private
Mutex * Const mu_;
Disallow "evil" constructors
Mutexlock (const mutexlock&);
void operator= (const mutexlock&);
};
Readermutexlock and Writermutexlock do the same, for Rwlocks
Class Readermutexlock {
Public
Explicit Readermutexlock (Mutex *mu): Mu_ (mu) {mu_->readerlock ();}
~readermutexlock () {Mu_->readerunlock ();}
Private
Mutex * Const mu_;
Disallow "evil" constructors
Readermutexlock (const readermutexlock&);
void operator= (const readermutexlock&);
};
Class Writermutexlock {
Public
Explicit Writermutexlock (Mutex *mu): Mu_ (mu) {mu_->writerlock ();}
~writermutexlock () {Mu_->writerunlock ();}
Private
Mutex * Const mu_;
Disallow "evil" constructors
Writermutexlock (const writermutexlock&);
void operator= (const writermutexlock&);
};
}/* Namespace FrameWork * *
#endif/* Mutex_h_ * *