/* * Copyright (C) 2005-2008 MaNGOS * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "Common.h" #include "Log.h" #include "Policies/SingletonImp.h" #include "Config/ConfigEnv.h" #include "Util.h" #include INSTANTIATE_SINGLETON_1( Log ); enum LogType { LogNormal = 0, LogDetails, LogDebug, LogError }; const int LogType_count = int(LogError) +1; void Log::InitColors(std::string str) { if(str.empty()) { m_colored = false; return; } int color[4]; std::istringstream ss(str); for(int i = 0; i < LogType_count; ++i) { ss >> color[i]; if(!ss) return; if(color[i] < 0 || color[i] >= Color_count) return; } for(int i = 0; i < LogType_count; ++i) m_colors[i] = Color(color[i]); m_colored = true; } void Log::SetColor(bool stdout_stream, Color color) { #if PLATFORM == PLATFORM_WINDOWS static WORD WinColorFG[Color_count] = { 0, // BLACK FOREGROUND_RED, // RED FOREGROUND_GREEN, // GREEN FOREGROUND_RED | FOREGROUND_GREEN, // BROWN FOREGROUND_BLUE, // BLUE FOREGROUND_RED | FOREGROUND_BLUE,// MAGENTA FOREGROUND_GREEN | FOREGROUND_BLUE, // CYAN FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE,// WHITE // YELLOW FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY, // RED_BOLD FOREGROUND_RED | FOREGROUND_INTENSITY, // GREEN_BOLD FOREGROUND_GREEN | FOREGROUND_INTENSITY, FOREGROUND_BLUE | FOREGROUND_INTENSITY, // BLUE_BOLD // MAGENTA_BOLD FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY, // CYAN_BOLD FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY, // WHITE_BOLD FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY }; HANDLE hConsole = GetStdHandle(stdout_stream ? STD_OUTPUT_HANDLE : STD_ERROR_HANDLE ); SetConsoleTextAttribute(hConsole, WinColorFG[color]); #else enum ANSITextAttr { TA_NORMAL=0, TA_BOLD=1, TA_BLINK=5, TA_REVERSE=7 }; enum ANSIFgTextAttr { FG_BLACK=30, FG_RED, FG_GREEN, FG_BROWN, FG_BLUE, FG_MAGENTA, FG_CYAN, FG_WHITE, FG_YELLOW }; enum ANSIBgTextAttr { BG_BLACK=40, BG_RED, BG_GREEN, BG_BROWN, BG_BLUE, BG_MAGENTA, BG_CYAN, BG_WHITE }; static uint8 UnixColorFG[Color_count] = { FG_BLACK, // BLACK FG_RED, // RED FG_GREEN, // GREEN FG_BROWN, // BROWN FG_BLUE, // BLUE FG_MAGENTA, // MAGENTA FG_CYAN, // CYAN FG_WHITE, // WHITE FG_YELLOW, // YELLOW FG_RED, // LRED FG_GREEN, // LGREEN FG_BLUE, // LBLUE FG_MAGENTA, // LMAGENTA FG_CYAN, // LCYAN FG_WHITE // LWHITE }; fprintf((stdout_stream? stdout : stderr), "\x1b[%d%sm",UnixColorFG[color],(color>=YELLOW&&colortm_year+1900,aTm->tm_mon+1,aTm->tm_mday,aTm->tm_hour,aTm->tm_min,aTm->tm_sec); } void Log::outTime() { time_t t = time(NULL); tm* aTm = localtime(&t); // YYYY year // MM month (2 digits 01-12) // DD day (2 digits 01-31) // HH hour (2 digits 00-23) // MM minutes (2 digits 00-59) // SS seconds (2 digits 00-59) printf("%02d:%02d:%02d ",aTm->tm_hour,aTm->tm_min,aTm->tm_sec); } std::string Log::GetTimestampStr() { time_t t = time(NULL); tm* aTm = localtime(&t); // YYYY year // MM month (2 digits 01-12) // DD day (2 digits 01-31) // HH hour (2 digits 00-23) // MM minutes (2 digits 00-59) // SS seconds (2 digits 00-59) char buf[20]; snprintf(buf,20,"%04d-%02d-%02d_%02d-%02d-%02d",aTm->tm_year+1900,aTm->tm_mon+1,aTm->tm_mday,aTm->tm_hour,aTm->tm_min,aTm->tm_sec); return std::string(buf); } void Log::outTitle( const char * str) { if( !str ) return; if(m_colored) SetColor(true,WHITE); // not expected utf8 and then send as-is printf( str ); if(m_colored) ResetColor(true); printf( "\n" ); if(logfile) { fprintf(logfile, str); fprintf(logfile, "\n" ); fflush(logfile); } fflush(stdout); } void Log::outString() { if(m_includeTime) outTime(); printf( "\n" ); if(logfile) { outTimestamp(logfile); fprintf(logfile, "\n" ); fflush(logfile); } fflush(stdout); } void Log::outString( const char * str, ... ) { if( !str ) return; if(m_colored) SetColor(true,m_colors[LogNormal]); if(m_includeTime) outTime(); UTF8PRINTF(stdout,str,); if(m_colored) ResetColor(true); printf( "\n" ); if(logfile) { outTimestamp(logfile); va_list ap; va_start(ap, str); vfprintf(logfile, str, ap); fprintf(logfile, "\n" ); va_end(ap); fflush(logfile); } fflush(stdout); } void Log::outError( const char * err, ... ) { if( !err ) return; if(m_colored) SetColor(false,m_colors[LogError]); if(m_includeTime) outTime(); UTF8PRINTF(stderr,err,); if(m_colored) ResetColor(false); fprintf( stderr, "\n" ); if(logfile) { outTimestamp(logfile); fprintf(logfile, "ERROR:" ); va_list ap; va_start(ap, err); vfprintf(logfile, err, ap); va_end(ap); fprintf(logfile, "\n" ); fflush(logfile); } fflush(stderr); } void Log::outErrorDb( const char * err, ... ) { if( !err ) return; if(m_colored) SetColor(false,m_colors[LogError]); if(m_includeTime) outTime(); UTF8PRINTF(stderr,err,); if(m_colored) ResetColor(false); fprintf( stderr, "\n" ); if(logfile) { outTimestamp(logfile); fprintf(logfile, "ERROR:" ); va_list ap; va_start(ap, err); vfprintf(logfile, err, ap); va_end(ap); fprintf(logfile, "\n" ); fflush(logfile); } if(dberLogfile) { outTimestamp(dberLogfile); va_list ap; va_start(ap, err); vfprintf(dberLogfile, err, ap); va_end(ap); fprintf(dberLogfile, "\n" ); fflush(dberLogfile); } fflush(stderr); } void Log::outBasic( const char * str, ... ) { if( !str ) return; if( m_logLevel > 0 ) { if(m_colored) SetColor(true,m_colors[LogDetails]); if(m_includeTime) outTime(); UTF8PRINTF(stdout,str,); if(m_colored) ResetColor(true); printf( "\n" ); } if(logfile && m_logFileLevel > 0) { va_list ap; outTimestamp(logfile); va_start(ap, str); vfprintf(logfile, str, ap); fprintf(logfile, "\n" ); va_end(ap); fflush(logfile); } fflush(stdout); } void Log::outDetail( const char * str, ... ) { if( !str ) return; if( m_logLevel > 1 ) { if(m_colored) SetColor(true,m_colors[LogDetails]); if(m_includeTime) outTime(); UTF8PRINTF(stdout,str,); if(m_colored) ResetColor(true); printf( "\n" ); } if(logfile && m_logFileLevel > 1) { va_list ap; outTimestamp(logfile); va_start(ap, str); vfprintf(logfile, str, ap); fprintf(logfile, "\n" ); va_end(ap); fflush(logfile); } fflush(stdout); } void Log::outDebugInLine( const char * str, ... ) { if( !str ) return; if( m_logLevel > 2 ) { if(m_colored) SetColor(true,m_colors[LogDebug]); UTF8PRINTF(stdout,str,); if(m_colored) ResetColor(true); } if(logfile && m_logFileLevel > 2) { va_list ap; va_start(ap, str); vfprintf(logfile, str, ap); va_end(ap); } } void Log::outDebug( const char * str, ... ) { if( !str ) return; if( m_logLevel > 2 ) { if(m_colored) SetColor(true,m_colors[LogDebug]); if(m_includeTime) outTime(); UTF8PRINTF(stdout,str,); if(m_colored) ResetColor(true); printf( "\n" ); } if(logfile && m_logFileLevel > 2) { outTimestamp(logfile); va_list ap; va_start(ap, str); vfprintf(logfile, str, ap); va_end(ap); fprintf(logfile, "\n" ); fflush(logfile); } fflush(stdout); } void Log::outCommand( const char * str, ... ) { if( !str ) return; if( m_logLevel > 1 ) { if(m_colored) SetColor(true,m_colors[LogDetails]); if(m_includeTime) outTime(); UTF8PRINTF(stdout,str,); if(m_colored) ResetColor(true); printf( "\n" ); } if(logfile && m_logFileLevel > 1) { va_list ap; outTimestamp(logfile); va_start(ap, str); vfprintf(logfile, str, ap); fprintf(logfile, "\n" ); va_end(ap); fflush(logfile); } if(gmLogfile) { va_list ap; outTimestamp(gmLogfile); va_start(ap, str); vfprintf(gmLogfile, str, ap); fprintf(gmLogfile, "\n" ); va_end(ap); fflush(gmLogfile); } fflush(stdout); } void Log::outChar(const char * str, ... ) { if (!str) return; if(charLogfile) { va_list ap; outTimestamp(charLogfile); va_start(ap, str); vfprintf(charLogfile, str, ap); fprintf(charLogfile, "\n" ); va_end(ap); fflush(charLogfile); } } void Log::outCharDump( const char * str, uint32 account_id, uint32 guid, const char * name ) { if(charLogfile) { fprintf(charLogfile, "== START DUMP == (account: %u guid: %u name: %s )\n%s\n== END DUMP ==\n",account_id,guid,name,str ); fflush(charLogfile); } } void Log::outMenu( const char * str, ... ) { if( !str ) return; SetColor(true,m_colors[LogNormal]); if(m_includeTime) outTime(); UTF8PRINTF(stdout,str,); ResetColor(true); if(logfile) { outTimestamp(logfile); va_list ap; va_start(ap, str); vfprintf(logfile, str, ap); va_end(ap); fprintf(logfile, "\n" ); fflush(logfile); } fflush(stdout); } void Log::outRALog( const char * str, ... ) { if( !str ) return; va_list ap; if (raLogfile) { outTimestamp(raLogfile); va_start(ap, str); vfprintf(raLogfile, str, ap); fprintf(raLogfile, "\n" ); va_end(ap); fflush(raLogfile); } fflush(stdout); } void outstring_log(const char * str, ...) { if( !str ) return; char buf[256]; va_list ap; va_start(ap, str); vsnprintf(buf,256, str, ap); va_end(ap); MaNGOS::Singleton::Instance().outString(buf); } void detail_log(const char * str, ...) { if( !str ) return; char buf[256]; va_list ap; va_start(ap, str); vsnprintf(buf,256, str, ap); va_end(ap); MaNGOS::Singleton::Instance().outDetail(buf); } void debug_log(const char * str, ...) { if( !str ) return; char buf[256]; va_list ap; va_start(ap, str); vsnprintf(buf,256, str, ap); va_end(ap); MaNGOS::Singleton::Instance().outDebug(buf); } void error_log(const char * str, ...) { if( !str ) return; char buf[256]; va_list ap; va_start(ap, str); vsnprintf(buf,256, str, ap); va_end(ap); MaNGOS::Singleton::Instance().outError(buf); } void error_db_log(const char * str, ...) { if( !str ) return; char buf[256]; va_list ap; va_start(ap, str); vsnprintf(buf,256, str, ap); va_end(ap); MaNGOS::Singleton::Instance().outErrorDb(buf); }