[7833] Implement levelup spells for non-hunter pets.
[getmangos.git] / src / shared / Log.cpp
blob97c2e7164cdcea123c646ecd308edf795d397fd5
1 /*
2 * Copyright (C) 2005-2009 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 Log::Log() :
40 raLogfile(NULL), logfile(NULL), gmLogfile(NULL), charLogfile(NULL),
41 dberLogfile(NULL), m_colored(false), m_includeTime(false), m_gmlog_per_account(false)
43 Initialize();
46 void Log::InitColors(const std::string& str)
48 if(str.empty())
50 m_colored = false;
51 return;
54 int color[4];
56 std::istringstream ss(str);
58 for(int i = 0; i < LogType_count; ++i)
60 ss >> color[i];
62 if(!ss)
63 return;
65 if(color[i] < 0 || color[i] >= Color_count)
66 return;
69 for(int i = 0; i < LogType_count; ++i)
70 m_colors[i] = Color(color[i]);
72 m_colored = true;
75 void Log::SetColor(bool stdout_stream, Color color)
77 #if PLATFORM == PLATFORM_WINDOWS
79 static WORD WinColorFG[Color_count] =
81 0, // BLACK
82 FOREGROUND_RED, // RED
83 FOREGROUND_GREEN, // GREEN
84 FOREGROUND_RED | FOREGROUND_GREEN, // BROWN
85 FOREGROUND_BLUE, // BLUE
86 FOREGROUND_RED | FOREGROUND_BLUE,// MAGENTA
87 FOREGROUND_GREEN | FOREGROUND_BLUE, // CYAN
88 FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE,// WHITE
89 // YELLOW
90 FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY,
91 // RED_BOLD
92 FOREGROUND_RED | FOREGROUND_INTENSITY,
93 // GREEN_BOLD
94 FOREGROUND_GREEN | FOREGROUND_INTENSITY,
95 FOREGROUND_BLUE | FOREGROUND_INTENSITY, // BLUE_BOLD
96 // MAGENTA_BOLD
97 FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY,
98 // CYAN_BOLD
99 FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY,
100 // WHITE_BOLD
101 FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY
104 HANDLE hConsole = GetStdHandle(stdout_stream ? STD_OUTPUT_HANDLE : STD_ERROR_HANDLE );
105 SetConsoleTextAttribute(hConsole, WinColorFG[color]);
106 #else
108 enum ANSITextAttr
110 TA_NORMAL=0,
111 TA_BOLD=1,
112 TA_BLINK=5,
113 TA_REVERSE=7
116 enum ANSIFgTextAttr
118 FG_BLACK=30, FG_RED, FG_GREEN, FG_BROWN, FG_BLUE,
119 FG_MAGENTA, FG_CYAN, FG_WHITE, FG_YELLOW
122 enum ANSIBgTextAttr
124 BG_BLACK=40, BG_RED, BG_GREEN, BG_BROWN, BG_BLUE,
125 BG_MAGENTA, BG_CYAN, BG_WHITE
128 static uint8 UnixColorFG[Color_count] =
130 FG_BLACK, // BLACK
131 FG_RED, // RED
132 FG_GREEN, // GREEN
133 FG_BROWN, // BROWN
134 FG_BLUE, // BLUE
135 FG_MAGENTA, // MAGENTA
136 FG_CYAN, // CYAN
137 FG_WHITE, // WHITE
138 FG_YELLOW, // YELLOW
139 FG_RED, // LRED
140 FG_GREEN, // LGREEN
141 FG_BLUE, // LBLUE
142 FG_MAGENTA, // LMAGENTA
143 FG_CYAN, // LCYAN
144 FG_WHITE // LWHITE
147 fprintf((stdout_stream? stdout : stderr), "\x1b[%d%sm",UnixColorFG[color],(color>=YELLOW&&color<Color_count ?";1":""));
148 #endif
151 void Log::ResetColor(bool stdout_stream)
153 #if PLATFORM == PLATFORM_WINDOWS
154 HANDLE hConsole = GetStdHandle(stdout_stream ? STD_OUTPUT_HANDLE : STD_ERROR_HANDLE );
155 SetConsoleTextAttribute(hConsole, FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED );
156 #else
157 fprintf(( stdout_stream ? stdout : stderr ), "\x1b[0m");
158 #endif
161 void Log::SetLogLevel(char *Level)
163 int32 NewLevel =atoi((char*)Level);
164 if ( NewLevel <0 )
165 NewLevel = 0;
166 m_logLevel = NewLevel;
168 printf( "LogLevel is %u\n",m_logLevel );
171 void Log::SetLogFileLevel(char *Level)
173 int32 NewLevel =atoi((char*)Level);
174 if ( NewLevel <0 )
175 NewLevel = 0;
176 m_logFileLevel = NewLevel;
178 printf( "LogFileLevel is %u\n",m_logFileLevel );
181 void Log::Initialize()
183 /// Common log files data
184 m_logsDir = sConfig.GetStringDefault("LogsDir","");
185 if(!m_logsDir.empty())
187 if((m_logsDir.at(m_logsDir.length()-1)!='/') && (m_logsDir.at(m_logsDir.length()-1)!='\\'))
188 m_logsDir.append("/");
191 m_logsTimestamp = "_" + GetTimestampStr();
193 /// Open specific log files
194 logfile = openLogFile("LogFile","LogTimestamp","w");
196 m_gmlog_per_account = sConfig.GetBoolDefault("GmLogPerAccount",false);
197 if(!m_gmlog_per_account)
198 gmLogfile = openLogFile("GMLogFile","GmLogTimestamp","a");
199 else
201 // GM log settings for per account case
202 m_gmlog_filename_format = sConfig.GetStringDefault("GMLogFile", "");
203 if(!m_gmlog_filename_format.empty())
205 bool m_gmlog_timestamp = sConfig.GetBoolDefault("GmLogTimestamp",false);
207 size_t dot_pos = m_gmlog_filename_format.find_last_of(".");
208 if(dot_pos!=m_gmlog_filename_format.npos)
210 if(m_gmlog_timestamp)
211 m_gmlog_filename_format.insert(dot_pos,m_logsTimestamp);
213 m_gmlog_filename_format.insert(dot_pos,"_#%u");
215 else
217 m_gmlog_filename_format += "_#%u";
219 if(m_gmlog_timestamp)
220 m_gmlog_filename_format += m_logsTimestamp;
223 m_gmlog_filename_format = m_logsDir + m_gmlog_filename_format;
227 charLogfile = openLogFile("CharLogFile","CharLogTimestamp","a");
229 dberLogfile = openLogFile("DBErrorLogFile",NULL,"a");
230 raLogfile = openLogFile("RaLogFile",NULL,"a");
232 // Main log file settings
233 m_includeTime = sConfig.GetBoolDefault("LogTime", false);
234 m_logLevel = sConfig.GetIntDefault("LogLevel", 0);
235 m_logFileLevel = sConfig.GetIntDefault("LogFileLevel", 0);
236 InitColors(sConfig.GetStringDefault("LogColors", ""));
238 m_logFilter = 0;
240 if(sConfig.GetBoolDefault("LogFilter_TransportMoves", true))
241 m_logFilter |= LOG_FILTER_TRANSPORT_MOVES;
242 if(sConfig.GetBoolDefault("LogFilter_CreatureMoves", true))
243 m_logFilter |= LOG_FILTER_CREATURE_MOVES;
244 if(sConfig.GetBoolDefault("LogFilter_VisibilityChanges", true))
245 m_logFilter |= LOG_FILTER_VISIBILITY_CHANGES;
246 if(sConfig.GetBoolDefault("LogFilter_AchievementUpdates", true))
247 m_logFilter |= LOG_FILTER_ACHIEVEMENT_UPDATES;
249 // Char log settings
250 m_charLog_Dump = sConfig.GetBoolDefault("CharLogDump", false);
253 FILE* Log::openLogFile(char const* configFileName,char const* configTimeStampFlag, char const* mode)
255 std::string logfn=sConfig.GetStringDefault(configFileName, "");
256 if(logfn.empty())
257 return NULL;
259 if(configTimeStampFlag && sConfig.GetBoolDefault(configTimeStampFlag,false))
261 size_t dot_pos = logfn.find_last_of(".");
262 if(dot_pos!=logfn.npos)
263 logfn.insert(dot_pos,m_logsTimestamp);
264 else
265 logfn += m_logsTimestamp;
268 return fopen((m_logsDir+logfn).c_str(), mode);
271 FILE* Log::openGmlogPerAccount(uint32 account)
273 if(m_gmlog_filename_format.empty())
274 return NULL;
276 char namebuf[MANGOS_PATH_MAX];
277 snprintf(namebuf,MANGOS_PATH_MAX,m_gmlog_filename_format.c_str(),account);
278 return fopen(namebuf, "a");
281 void Log::outTimestamp(FILE* file)
283 time_t t = time(NULL);
284 tm* aTm = localtime(&t);
285 // YYYY year
286 // MM month (2 digits 01-12)
287 // DD day (2 digits 01-31)
288 // HH hour (2 digits 00-23)
289 // MM minutes (2 digits 00-59)
290 // SS seconds (2 digits 00-59)
291 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);
294 void Log::outTime()
296 time_t t = time(NULL);
297 tm* aTm = localtime(&t);
298 // YYYY year
299 // MM month (2 digits 01-12)
300 // DD day (2 digits 01-31)
301 // HH hour (2 digits 00-23)
302 // MM minutes (2 digits 00-59)
303 // SS seconds (2 digits 00-59)
304 printf("%02d:%02d:%02d ",aTm->tm_hour,aTm->tm_min,aTm->tm_sec);
307 std::string Log::GetTimestampStr()
309 time_t t = time(NULL);
310 tm* aTm = localtime(&t);
311 // YYYY year
312 // MM month (2 digits 01-12)
313 // DD day (2 digits 01-31)
314 // HH hour (2 digits 00-23)
315 // MM minutes (2 digits 00-59)
316 // SS seconds (2 digits 00-59)
317 char buf[20];
318 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);
319 return std::string(buf);
322 void Log::outTitle( const char * str)
324 if( !str )
325 return;
327 if(m_colored)
328 SetColor(true,WHITE);
330 // not expected utf8 and then send as-is
331 printf( str );
333 if(m_colored)
334 ResetColor(true);
336 printf( "\n" );
337 if(logfile)
339 fprintf(logfile, str);
340 fprintf(logfile, "\n" );
341 fflush(logfile);
344 fflush(stdout);
347 void Log::outString()
349 if(m_includeTime)
350 outTime();
351 printf( "\n" );
352 if(logfile)
354 outTimestamp(logfile);
355 fprintf(logfile, "\n" );
356 fflush(logfile);
358 fflush(stdout);
361 void Log::outString( const char * str, ... )
363 if( !str )
364 return;
366 if(m_colored)
367 SetColor(true,m_colors[LogNormal]);
369 if(m_includeTime)
370 outTime();
372 UTF8PRINTF(stdout,str,);
374 if(m_colored)
375 ResetColor(true);
377 printf( "\n" );
378 if(logfile)
380 outTimestamp(logfile);
382 va_list ap;
383 va_start(ap, str);
384 vfprintf(logfile, str, ap);
385 fprintf(logfile, "\n" );
386 va_end(ap);
388 fflush(logfile);
390 fflush(stdout);
393 void Log::outError( const char * err, ... )
395 if( !err )
396 return;
398 if(m_colored)
399 SetColor(false,m_colors[LogError]);
401 if(m_includeTime)
402 outTime();
404 UTF8PRINTF(stderr,err,);
406 if(m_colored)
407 ResetColor(false);
409 fprintf( stderr, "\n" );
410 if(logfile)
412 outTimestamp(logfile);
413 fprintf(logfile, "ERROR:" );
415 va_list ap;
416 va_start(ap, err);
417 vfprintf(logfile, err, ap);
418 va_end(ap);
420 fprintf(logfile, "\n" );
421 fflush(logfile);
423 fflush(stderr);
426 void Log::outErrorDb( const char * err, ... )
428 if( !err )
429 return;
431 if(m_colored)
432 SetColor(false,m_colors[LogError]);
434 if(m_includeTime)
435 outTime();
437 UTF8PRINTF(stderr,err,);
439 if(m_colored)
440 ResetColor(false);
442 fprintf( stderr, "\n" );
444 if(logfile)
446 outTimestamp(logfile);
447 fprintf(logfile, "ERROR:" );
449 va_list ap;
450 va_start(ap, err);
451 vfprintf(logfile, err, ap);
452 va_end(ap);
454 fprintf(logfile, "\n" );
455 fflush(logfile);
458 if(dberLogfile)
460 outTimestamp(dberLogfile);
462 va_list ap;
463 va_start(ap, err);
464 vfprintf(dberLogfile, err, ap);
465 va_end(ap);
467 fprintf(dberLogfile, "\n" );
468 fflush(dberLogfile);
470 fflush(stderr);
473 void Log::outBasic( const char * str, ... )
475 if( !str )
476 return;
478 if( m_logLevel > 0 )
480 if(m_colored)
481 SetColor(true,m_colors[LogDetails]);
483 if(m_includeTime)
484 outTime();
486 UTF8PRINTF(stdout,str,);
488 if(m_colored)
489 ResetColor(true);
491 printf( "\n" );
494 if(logfile && m_logFileLevel > 0)
496 va_list ap;
497 outTimestamp(logfile);
498 va_start(ap, str);
499 vfprintf(logfile, str, ap);
500 fprintf(logfile, "\n" );
501 va_end(ap);
502 fflush(logfile);
504 fflush(stdout);
507 void Log::outDetail( const char * str, ... )
509 if( !str )
510 return;
512 if( m_logLevel > 1 )
515 if(m_colored)
516 SetColor(true,m_colors[LogDetails]);
518 if(m_includeTime)
519 outTime();
521 UTF8PRINTF(stdout,str,);
523 if(m_colored)
524 ResetColor(true);
526 printf( "\n" );
528 if(logfile && m_logFileLevel > 1)
530 va_list ap;
531 outTimestamp(logfile);
532 va_start(ap, str);
533 vfprintf(logfile, str, ap);
534 fprintf(logfile, "\n" );
535 va_end(ap);
536 fflush(logfile);
539 fflush(stdout);
542 void Log::outDebugInLine( const char * str, ... )
544 if( !str )
545 return;
546 if( m_logLevel > 2 )
548 if(m_colored)
549 SetColor(true,m_colors[LogDebug]);
551 UTF8PRINTF(stdout,str,);
553 if(m_colored)
554 ResetColor(true);
556 if(logfile && m_logFileLevel > 2)
558 va_list ap;
559 va_start(ap, str);
560 vfprintf(logfile, str, ap);
561 va_end(ap);
565 void Log::outDebug( const char * str, ... )
567 if( !str )
568 return;
569 if( m_logLevel > 2 )
571 if(m_colored)
572 SetColor(true,m_colors[LogDebug]);
574 if(m_includeTime)
575 outTime();
577 UTF8PRINTF(stdout,str,);
579 if(m_colored)
580 ResetColor(true);
582 printf( "\n" );
584 if(logfile && m_logFileLevel > 2)
586 outTimestamp(logfile);
588 va_list ap;
589 va_start(ap, str);
590 vfprintf(logfile, str, ap);
591 va_end(ap);
593 fprintf(logfile, "\n" );
594 fflush(logfile);
596 fflush(stdout);
599 void Log::outCommand( uint32 account, const char * str, ... )
601 if( !str )
602 return;
604 if( m_logLevel > 1 )
606 if(m_colored)
607 SetColor(true,m_colors[LogDetails]);
609 if(m_includeTime)
610 outTime();
612 UTF8PRINTF(stdout,str,);
614 if(m_colored)
615 ResetColor(true);
617 printf( "\n" );
619 if(logfile && m_logFileLevel > 1)
621 va_list ap;
622 outTimestamp(logfile);
623 va_start(ap, str);
624 vfprintf(logfile, str, ap);
625 fprintf(logfile, "\n" );
626 va_end(ap);
627 fflush(logfile);
630 if (m_gmlog_per_account)
632 if (FILE* per_file = openGmlogPerAccount (account))
634 va_list ap;
635 outTimestamp(per_file);
636 va_start(ap, str);
637 vfprintf(per_file, str, ap);
638 fprintf(per_file, "\n" );
639 va_end(ap);
640 fclose(per_file);
643 else if (gmLogfile)
645 va_list ap;
646 outTimestamp(gmLogfile);
647 va_start(ap, str);
648 vfprintf(gmLogfile, str, ap);
649 fprintf(gmLogfile, "\n" );
650 va_end(ap);
651 fflush(gmLogfile);
654 fflush(stdout);
657 void Log::outChar(const char * str, ... )
660 if (!str)
661 return;
663 if(charLogfile)
665 va_list ap;
666 outTimestamp(charLogfile);
667 va_start(ap, str);
668 vfprintf(charLogfile, str, ap);
669 fprintf(charLogfile, "\n" );
670 va_end(ap);
671 fflush(charLogfile);
675 void Log::outCharDump( const char * str, uint32 account_id, uint32 guid, const char * name )
677 if(charLogfile)
679 fprintf(charLogfile, "== START DUMP == (account: %u guid: %u name: %s )\n%s\n== END DUMP ==\n",account_id,guid,name,str );
680 fflush(charLogfile);
684 void Log::outMenu( const char * str, ... )
686 if( !str )
687 return;
689 SetColor(true,m_colors[LogNormal]);
691 if(m_includeTime)
692 outTime();
694 UTF8PRINTF(stdout,str,);
696 ResetColor(true);
698 if(logfile)
700 outTimestamp(logfile);
702 va_list ap;
703 va_start(ap, str);
704 vfprintf(logfile, str, ap);
705 va_end(ap);
707 fprintf(logfile, "\n" );
708 fflush(logfile);
710 fflush(stdout);
713 void Log::outRALog( const char * str, ... )
715 if( !str )
716 return;
717 va_list ap;
718 if (raLogfile)
720 outTimestamp(raLogfile);
721 va_start(ap, str);
722 vfprintf(raLogfile, str, ap);
723 fprintf(raLogfile, "\n" );
724 va_end(ap);
725 fflush(raLogfile);
727 fflush(stdout);
730 void outstring_log(const char * str, ...)
732 if( !str )
733 return;
735 char buf[256];
736 va_list ap;
737 va_start(ap, str);
738 vsnprintf(buf,256, str, ap);
739 va_end(ap);
741 MaNGOS::Singleton<Log>::Instance().outString(buf);
744 void detail_log(const char * str, ...)
746 if( !str )
747 return;
749 char buf[256];
750 va_list ap;
751 va_start(ap, str);
752 vsnprintf(buf,256, str, ap);
753 va_end(ap);
755 MaNGOS::Singleton<Log>::Instance().outDetail(buf);
758 void debug_log(const char * str, ...)
760 if( !str )
761 return;
763 char buf[256];
764 va_list ap;
765 va_start(ap, str);
766 vsnprintf(buf,256, str, ap);
767 va_end(ap);
769 MaNGOS::Singleton<Log>::Instance().outDebug(buf);
772 void error_log(const char * str, ...)
774 if( !str )
775 return;
777 char buf[256];
778 va_list ap;
779 va_start(ap, str);
780 vsnprintf(buf,256, str, ap);
781 va_end(ap);
783 MaNGOS::Singleton<Log>::Instance().outError(buf);
786 void error_db_log(const char * str, ...)
788 if( !str )
789 return;
791 char buf[256];
792 va_list ap;
793 va_start(ap, str);
794 vsnprintf(buf,256, str, ap);
795 va_end(ap);
797 MaNGOS::Singleton<Log>::Instance().outErrorDb(buf);