Merge branch 'master' into 303
[getmangos.git] / src / shared / Log.cpp
blob3f9677123bb790c6d4f263db215adc44c46a48d6
1 /*
2 * Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 #include "Common.h"
20 #include "Log.h"
21 #include "Policies/SingletonImp.h"
22 #include "Config/ConfigEnv.h"
23 #include "Util.h"
25 #include <stdarg.h>
27 INSTANTIATE_SINGLETON_1( Log );
29 enum LogType
31 LogNormal = 0,
32 LogDetails,
33 LogDebug,
34 LogError
37 const int LogType_count = int(LogError) +1;
39 void Log::InitColors(std::string str)
41 if(str.empty())
43 m_colored = false;
44 return;
47 int color[4];
49 std::istringstream ss(str);
51 for(int i = 0; i < LogType_count; ++i)
53 ss >> color[i];
55 if(!ss)
56 return;
58 if(color[i] < 0 || color[i] >= Color_count)
59 return;
62 for(int i = 0; i < LogType_count; ++i)
63 m_colors[i] = Color(color[i]);
65 m_colored = true;
68 void Log::SetColor(bool stdout_stream, Color color)
70 #if PLATFORM == PLATFORM_WINDOWS
72 static WORD WinColorFG[Color_count] =
74 0, // BLACK
75 FOREGROUND_RED, // RED
76 FOREGROUND_GREEN, // GREEN
77 FOREGROUND_RED | FOREGROUND_GREEN, // BROWN
78 FOREGROUND_BLUE, // BLUE
79 FOREGROUND_RED | FOREGROUND_BLUE,// MAGENTA
80 FOREGROUND_GREEN | FOREGROUND_BLUE, // CYAN
81 FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE,// WHITE
82 // YELLOW
83 FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY,
84 // RED_BOLD
85 FOREGROUND_RED | FOREGROUND_INTENSITY,
86 // GREEN_BOLD
87 FOREGROUND_GREEN | FOREGROUND_INTENSITY,
88 FOREGROUND_BLUE | FOREGROUND_INTENSITY, // BLUE_BOLD
89 // MAGENTA_BOLD
90 FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY,
91 // CYAN_BOLD
92 FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY,
93 // WHITE_BOLD
94 FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY
97 HANDLE hConsole = GetStdHandle(stdout_stream ? STD_OUTPUT_HANDLE : STD_ERROR_HANDLE );
98 SetConsoleTextAttribute(hConsole, WinColorFG[color]);
99 #else
101 enum ANSITextAttr
103 TA_NORMAL=0,
104 TA_BOLD=1,
105 TA_BLINK=5,
106 TA_REVERSE=7
109 enum ANSIFgTextAttr
111 FG_BLACK=30, FG_RED, FG_GREEN, FG_BROWN, FG_BLUE,
112 FG_MAGENTA, FG_CYAN, FG_WHITE, FG_YELLOW
115 enum ANSIBgTextAttr
117 BG_BLACK=40, BG_RED, BG_GREEN, BG_BROWN, BG_BLUE,
118 BG_MAGENTA, BG_CYAN, BG_WHITE
121 static uint8 UnixColorFG[Color_count] =
123 FG_BLACK, // BLACK
124 FG_RED, // RED
125 FG_GREEN, // GREEN
126 FG_BROWN, // BROWN
127 FG_BLUE, // BLUE
128 FG_MAGENTA, // MAGENTA
129 FG_CYAN, // CYAN
130 FG_WHITE, // WHITE
131 FG_YELLOW, // YELLOW
132 FG_RED, // LRED
133 FG_GREEN, // LGREEN
134 FG_BLUE, // LBLUE
135 FG_MAGENTA, // LMAGENTA
136 FG_CYAN, // LCYAN
137 FG_WHITE // LWHITE
140 fprintf((stdout_stream? stdout : stderr), "\x1b[%d%sm",UnixColorFG[color],(color>=YELLOW&&color<Color_count ?";1":""));
141 #endif
144 void Log::ResetColor(bool stdout_stream)
146 #if PLATFORM == PLATFORM_WINDOWS
147 HANDLE hConsole = GetStdHandle(stdout_stream ? STD_OUTPUT_HANDLE : STD_ERROR_HANDLE );
148 SetConsoleTextAttribute(hConsole, FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED );
149 #else
150 fprintf(( stdout_stream ? stdout : stderr ), "\x1b[0m");
151 #endif
154 void Log::SetLogLevel(char *Level)
156 int32 NewLevel =atoi((char*)Level);
157 if ( NewLevel <0 )
158 NewLevel = 0;
159 m_logLevel = NewLevel;
161 printf( "LogLevel is %u\n",m_logLevel );
164 void Log::SetLogFileLevel(char *Level)
166 int32 NewLevel =atoi((char*)Level);
167 if ( NewLevel <0 )
168 NewLevel = 0;
169 m_logFileLevel = NewLevel;
171 printf( "LogFileLevel is %u\n",m_logFileLevel );
174 void Log::Initialize()
176 std::string logsDir = sConfig.GetStringDefault("LogsDir","");
178 if(!logsDir.empty())
180 if((logsDir.at(logsDir.length()-1)!='/') && (logsDir.at(logsDir.length()-1)!='\\'))
181 logsDir.append("/");
184 std::string logfn=sConfig.GetStringDefault("LogFile", "");
185 if(!logfn.empty())
187 if(sConfig.GetBoolDefault("LogTimestamp",false))
189 std::string logTimestamp = GetTimestampStr();
190 logTimestamp.insert(0,"_");
191 size_t dot_pos = logfn.find_last_of(".");
192 if(dot_pos!=logfn.npos)
193 logfn.insert(dot_pos,logTimestamp);
194 else
195 logfn += logTimestamp;
198 logfile = fopen((logsDir+logfn).c_str(), "w");
201 std::string gmlogname = sConfig.GetStringDefault("GMLogFile", "");
202 if(!gmlogname.empty())
204 if(sConfig.GetBoolDefault("GmLogTimestamp",false))
206 std::string gmLogTimestamp = GetTimestampStr();
207 gmLogTimestamp.insert(0,"_");
208 size_t dot_pos = gmlogname.find_last_of(".");
209 if(dot_pos!=gmlogname.npos)
210 gmlogname.insert(dot_pos,gmLogTimestamp);
211 else
212 gmlogname += gmLogTimestamp;
214 gmLogfile = fopen((logsDir+gmlogname).c_str(), "a");
217 std::string charlogname = sConfig.GetStringDefault("CharLogFile", "");
218 if(!charlogname.empty())
220 if(sConfig.GetBoolDefault("CharLogTimestamp",false))
222 std::string charLogTimestamp = GetTimestampStr();
223 charLogTimestamp.insert(0,"_");
224 size_t dot_pos = charlogname.find_last_of(".");
225 if(dot_pos!=charlogname.npos)
226 charlogname.insert(dot_pos,charLogTimestamp);
227 else
228 charlogname += charLogTimestamp;
230 charLogfile = fopen((logsDir+charlogname).c_str(), "a");
233 std::string dberlogname = sConfig.GetStringDefault("DBErrorLogFile", "");
234 if(!dberlogname.empty())
236 dberLogfile = fopen((logsDir+dberlogname).c_str(), "a");
238 std::string ralogname = sConfig.GetStringDefault("RaLogFile", "");
239 if(!ralogname.empty())
241 raLogfile = fopen((logsDir+ralogname).c_str(), "a");
243 m_includeTime = sConfig.GetBoolDefault("LogTime", false);
244 m_logLevel = sConfig.GetIntDefault("LogLevel", 0);
245 m_logFileLevel = sConfig.GetIntDefault("LogFileLevel", 0);
246 InitColors(sConfig.GetStringDefault("LogColors", ""));
248 m_logFilter = 0;
250 if(sConfig.GetBoolDefault("LogFilter_TransportMoves", true))
251 m_logFilter |= LOG_FILTER_TRANSPORT_MOVES;
252 if(sConfig.GetBoolDefault("LogFilter_CreatureMoves", true))
253 m_logFilter |= LOG_FILTER_CREATURE_MOVES;
254 if(sConfig.GetBoolDefault("LogFilter_VisibilityChanges", true))
255 m_logFilter |= LOG_FILTER_VISIBILITY_CHANGES;
257 m_charLog_Dump = sConfig.GetBoolDefault("CharLogDump", false);
260 void Log::outTimestamp(FILE* file)
262 time_t t = time(NULL);
263 tm* aTm = localtime(&t);
264 // YYYY year
265 // MM month (2 digits 01-12)
266 // DD day (2 digits 01-31)
267 // HH hour (2 digits 00-23)
268 // MM minutes (2 digits 00-59)
269 // SS seconds (2 digits 00-59)
270 fprintf(file,"%-4d-%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);
273 void Log::outTime()
275 time_t t = time(NULL);
276 tm* aTm = localtime(&t);
277 // YYYY year
278 // MM month (2 digits 01-12)
279 // DD day (2 digits 01-31)
280 // HH hour (2 digits 00-23)
281 // MM minutes (2 digits 00-59)
282 // SS seconds (2 digits 00-59)
283 printf("%02d:%02d:%02d ",aTm->tm_hour,aTm->tm_min,aTm->tm_sec);
286 std::string Log::GetTimestampStr()
288 time_t t = time(NULL);
289 tm* aTm = localtime(&t);
290 // YYYY year
291 // MM month (2 digits 01-12)
292 // DD day (2 digits 01-31)
293 // HH hour (2 digits 00-23)
294 // MM minutes (2 digits 00-59)
295 // SS seconds (2 digits 00-59)
296 char buf[20];
297 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);
298 return std::string(buf);
301 void Log::outTitle( const char * str)
303 if( !str )
304 return;
306 if(m_colored)
307 SetColor(true,WHITE);
309 // not expected utf8 and then send as-is
310 printf( str );
312 if(m_colored)
313 ResetColor(true);
315 printf( "\n" );
316 if(logfile)
318 fprintf(logfile, str);
319 fprintf(logfile, "\n" );
320 fflush(logfile);
323 fflush(stdout);
326 void Log::outString()
328 if(m_includeTime)
329 outTime();
330 printf( "\n" );
331 if(logfile)
333 outTimestamp(logfile);
334 fprintf(logfile, "\n" );
335 fflush(logfile);
337 fflush(stdout);
340 void Log::outString( const char * str, ... )
342 if( !str )
343 return;
345 if(m_colored)
346 SetColor(true,m_colors[LogNormal]);
348 if(m_includeTime)
349 outTime();
351 UTF8PRINTF(stdout,str,);
353 if(m_colored)
354 ResetColor(true);
356 printf( "\n" );
357 if(logfile)
359 outTimestamp(logfile);
361 va_list ap;
362 va_start(ap, str);
363 vfprintf(logfile, str, ap);
364 fprintf(logfile, "\n" );
365 va_end(ap);
367 fflush(logfile);
369 fflush(stdout);
372 void Log::outError( const char * err, ... )
374 if( !err )
375 return;
377 if(m_colored)
378 SetColor(false,m_colors[LogError]);
380 if(m_includeTime)
381 outTime();
383 UTF8PRINTF(stderr,err,);
385 if(m_colored)
386 ResetColor(false);
388 fprintf( stderr, "\n" );
389 if(logfile)
391 outTimestamp(logfile);
392 fprintf(logfile, "ERROR:" );
394 va_list ap;
395 va_start(ap, err);
396 vfprintf(logfile, err, ap);
397 va_end(ap);
399 fprintf(logfile, "\n" );
400 fflush(logfile);
402 fflush(stderr);
405 void Log::outErrorDb( const char * err, ... )
407 if( !err )
408 return;
410 if(m_colored)
411 SetColor(false,m_colors[LogError]);
413 if(m_includeTime)
414 outTime();
416 UTF8PRINTF(stderr,err,);
418 if(m_colored)
419 ResetColor(false);
421 fprintf( stderr, "\n" );
423 if(logfile)
425 outTimestamp(logfile);
426 fprintf(logfile, "ERROR:" );
428 va_list ap;
429 va_start(ap, err);
430 vfprintf(logfile, err, ap);
431 va_end(ap);
433 fprintf(logfile, "\n" );
434 fflush(logfile);
437 if(dberLogfile)
439 outTimestamp(dberLogfile);
441 va_list ap;
442 va_start(ap, err);
443 vfprintf(dberLogfile, err, ap);
444 va_end(ap);
446 fprintf(dberLogfile, "\n" );
447 fflush(dberLogfile);
449 fflush(stderr);
452 void Log::outBasic( const char * str, ... )
454 if( !str )
455 return;
457 if( m_logLevel > 0 )
459 if(m_colored)
460 SetColor(true,m_colors[LogDetails]);
462 if(m_includeTime)
463 outTime();
465 UTF8PRINTF(stdout,str,);
467 if(m_colored)
468 ResetColor(true);
470 printf( "\n" );
473 if(logfile && m_logFileLevel > 0)
475 va_list ap;
476 outTimestamp(logfile);
477 va_start(ap, str);
478 vfprintf(logfile, str, ap);
479 fprintf(logfile, "\n" );
480 va_end(ap);
481 fflush(logfile);
483 fflush(stdout);
486 void Log::outDetail( const char * str, ... )
488 if( !str )
489 return;
491 if( m_logLevel > 1 )
494 if(m_colored)
495 SetColor(true,m_colors[LogDetails]);
497 if(m_includeTime)
498 outTime();
500 UTF8PRINTF(stdout,str,);
502 if(m_colored)
503 ResetColor(true);
505 printf( "\n" );
507 if(logfile && m_logFileLevel > 1)
509 va_list ap;
510 outTimestamp(logfile);
511 va_start(ap, str);
512 vfprintf(logfile, str, ap);
513 fprintf(logfile, "\n" );
514 va_end(ap);
515 fflush(logfile);
518 fflush(stdout);
521 void Log::outDebugInLine( const char * str, ... )
523 if( !str )
524 return;
525 if( m_logLevel > 2 )
527 if(m_colored)
528 SetColor(true,m_colors[LogDebug]);
530 UTF8PRINTF(stdout,str,);
532 if(m_colored)
533 ResetColor(true);
535 if(logfile && m_logFileLevel > 2)
537 va_list ap;
538 va_start(ap, str);
539 vfprintf(logfile, str, ap);
540 va_end(ap);
544 void Log::outDebug( const char * str, ... )
546 if( !str )
547 return;
548 if( m_logLevel > 2 )
550 if(m_colored)
551 SetColor(true,m_colors[LogDebug]);
553 if(m_includeTime)
554 outTime();
556 UTF8PRINTF(stdout,str,);
558 if(m_colored)
559 ResetColor(true);
561 printf( "\n" );
563 if(logfile && m_logFileLevel > 2)
565 outTimestamp(logfile);
567 va_list ap;
568 va_start(ap, str);
569 vfprintf(logfile, str, ap);
570 va_end(ap);
572 fprintf(logfile, "\n" );
573 fflush(logfile);
575 fflush(stdout);
578 void Log::outCommand( const char * str, ... )
580 if( !str )
581 return;
583 if( m_logLevel > 1 )
585 if(m_colored)
586 SetColor(true,m_colors[LogDetails]);
588 if(m_includeTime)
589 outTime();
591 UTF8PRINTF(stdout,str,);
593 if(m_colored)
594 ResetColor(true);
596 printf( "\n" );
598 if(logfile && m_logFileLevel > 1)
600 va_list ap;
601 outTimestamp(logfile);
602 va_start(ap, str);
603 vfprintf(logfile, str, ap);
604 fprintf(logfile, "\n" );
605 va_end(ap);
606 fflush(logfile);
608 if(gmLogfile)
610 va_list ap;
611 outTimestamp(gmLogfile);
612 va_start(ap, str);
613 vfprintf(gmLogfile, str, ap);
614 fprintf(gmLogfile, "\n" );
615 va_end(ap);
616 fflush(gmLogfile);
618 fflush(stdout);
621 void Log::outChar(const char * str, ... )
624 if (!str)
625 return;
627 if(charLogfile)
629 va_list ap;
630 outTimestamp(charLogfile);
631 va_start(ap, str);
632 vfprintf(charLogfile, str, ap);
633 fprintf(charLogfile, "\n" );
634 va_end(ap);
635 fflush(charLogfile);
639 void Log::outCharDump( const char * str, uint32 account_id, uint32 guid, const char * name )
641 if(charLogfile)
643 fprintf(charLogfile, "== START DUMP == (account: %u guid: %u name: %s )\n%s\n== END DUMP ==\n",account_id,guid,name,str );
644 fflush(charLogfile);
648 void Log::outMenu( const char * str, ... )
650 if( !str )
651 return;
653 SetColor(true,m_colors[LogNormal]);
655 if(m_includeTime)
656 outTime();
658 UTF8PRINTF(stdout,str,);
660 ResetColor(true);
662 if(logfile)
664 outTimestamp(logfile);
666 va_list ap;
667 va_start(ap, str);
668 vfprintf(logfile, str, ap);
669 va_end(ap);
671 fprintf(logfile, "\n" );
672 fflush(logfile);
674 fflush(stdout);
677 void Log::outRALog( const char * str, ... )
679 if( !str )
680 return;
681 va_list ap;
682 if (raLogfile)
684 outTimestamp(raLogfile);
685 va_start(ap, str);
686 vfprintf(raLogfile, str, ap);
687 fprintf(raLogfile, "\n" );
688 va_end(ap);
689 fflush(raLogfile);
691 fflush(stdout);
694 void outstring_log(const char * str, ...)
696 if( !str )
697 return;
699 char buf[256];
700 va_list ap;
701 va_start(ap, str);
702 vsnprintf(buf,256, str, ap);
703 va_end(ap);
705 MaNGOS::Singleton<Log>::Instance().outString(buf);
708 void detail_log(const char * str, ...)
710 if( !str )
711 return;
713 char buf[256];
714 va_list ap;
715 va_start(ap, str);
716 vsnprintf(buf,256, str, ap);
717 va_end(ap);
719 MaNGOS::Singleton<Log>::Instance().outDetail(buf);
722 void debug_log(const char * str, ...)
724 if( !str )
725 return;
727 char buf[256];
728 va_list ap;
729 va_start(ap, str);
730 vsnprintf(buf,256, str, ap);
731 va_end(ap);
733 MaNGOS::Singleton<Log>::Instance().outDebug(buf);
736 void error_log(const char * str, ...)
738 if( !str )
739 return;
741 char buf[256];
742 va_list ap;
743 va_start(ap, str);
744 vsnprintf(buf,256, str, ap);
745 va_end(ap);
747 MaNGOS::Singleton<Log>::Instance().outError(buf);
750 void error_db_log(const char * str, ...)
752 if( !str )
753 return;
755 char buf[256];
756 va_list ap;
757 va_start(ap, str);
758 vsnprintf(buf,256, str, ap);
759 va_end(ap);
761 MaNGOS::Singleton<Log>::Instance().outErrorDb(buf);