[9250] Fixed my typo in 9246_01_characters_character.sql
[getmangos.git] / src / shared / Log.cpp
blob9d9988ddcff41110f6ce9df3e8540af40b562ddd
1 /*
2 * Copyright (C) 2005-2010 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"
24 #include "ByteBuffer.h"
26 #include <stdarg.h>
28 INSTANTIATE_SINGLETON_1( Log );
30 enum LogType
32 LogNormal = 0,
33 LogDetails,
34 LogDebug,
35 LogError
38 const int LogType_count = int(LogError) +1;
40 Log::Log() :
41 raLogfile(NULL), logfile(NULL), gmLogfile(NULL), charLogfile(NULL),
42 dberLogfile(NULL), m_colored(false), m_includeTime(false), m_gmlog_per_account(false)
44 Initialize();
47 void Log::InitColors(const std::string& str)
49 if(str.empty())
51 m_colored = false;
52 return;
55 int color[4];
57 std::istringstream ss(str);
59 for(int i = 0; i < LogType_count; ++i)
61 ss >> color[i];
63 if(!ss)
64 return;
66 if(color[i] < 0 || color[i] >= Color_count)
67 return;
70 for(int i = 0; i < LogType_count; ++i)
71 m_colors[i] = Color(color[i]);
73 m_colored = true;
76 void Log::SetColor(bool stdout_stream, Color color)
78 #if PLATFORM == PLATFORM_WINDOWS
80 static WORD WinColorFG[Color_count] =
82 0, // BLACK
83 FOREGROUND_RED, // RED
84 FOREGROUND_GREEN, // GREEN
85 FOREGROUND_RED | FOREGROUND_GREEN, // BROWN
86 FOREGROUND_BLUE, // BLUE
87 FOREGROUND_RED | FOREGROUND_BLUE,// MAGENTA
88 FOREGROUND_GREEN | FOREGROUND_BLUE, // CYAN
89 FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE,// WHITE
90 // YELLOW
91 FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY,
92 // RED_BOLD
93 FOREGROUND_RED | FOREGROUND_INTENSITY,
94 // GREEN_BOLD
95 FOREGROUND_GREEN | FOREGROUND_INTENSITY,
96 FOREGROUND_BLUE | FOREGROUND_INTENSITY, // BLUE_BOLD
97 // MAGENTA_BOLD
98 FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY,
99 // CYAN_BOLD
100 FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY,
101 // WHITE_BOLD
102 FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY
105 HANDLE hConsole = GetStdHandle(stdout_stream ? STD_OUTPUT_HANDLE : STD_ERROR_HANDLE );
106 SetConsoleTextAttribute(hConsole, WinColorFG[color]);
107 #else
109 enum ANSITextAttr
111 TA_NORMAL=0,
112 TA_BOLD=1,
113 TA_BLINK=5,
114 TA_REVERSE=7
117 enum ANSIFgTextAttr
119 FG_BLACK=30, FG_RED, FG_GREEN, FG_BROWN, FG_BLUE,
120 FG_MAGENTA, FG_CYAN, FG_WHITE, FG_YELLOW
123 enum ANSIBgTextAttr
125 BG_BLACK=40, BG_RED, BG_GREEN, BG_BROWN, BG_BLUE,
126 BG_MAGENTA, BG_CYAN, BG_WHITE
129 static uint8 UnixColorFG[Color_count] =
131 FG_BLACK, // BLACK
132 FG_RED, // RED
133 FG_GREEN, // GREEN
134 FG_BROWN, // BROWN
135 FG_BLUE, // BLUE
136 FG_MAGENTA, // MAGENTA
137 FG_CYAN, // CYAN
138 FG_WHITE, // WHITE
139 FG_YELLOW, // YELLOW
140 FG_RED, // LRED
141 FG_GREEN, // LGREEN
142 FG_BLUE, // LBLUE
143 FG_MAGENTA, // LMAGENTA
144 FG_CYAN, // LCYAN
145 FG_WHITE // LWHITE
148 fprintf((stdout_stream? stdout : stderr), "\x1b[%d%sm",UnixColorFG[color],(color>=YELLOW&&color<Color_count ?";1":""));
149 #endif
152 void Log::ResetColor(bool stdout_stream)
154 #if PLATFORM == PLATFORM_WINDOWS
155 HANDLE hConsole = GetStdHandle(stdout_stream ? STD_OUTPUT_HANDLE : STD_ERROR_HANDLE );
156 SetConsoleTextAttribute(hConsole, FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED );
157 #else
158 fprintf(( stdout_stream ? stdout : stderr ), "\x1b[0m");
159 #endif
162 void Log::SetLogLevel(char *Level)
164 int32 NewLevel =atoi((char*)Level);
165 if ( NewLevel <0 )
166 NewLevel = 0;
167 m_logLevel = NewLevel;
169 printf( "LogLevel is %u\n",m_logLevel );
172 void Log::SetLogFileLevel(char *Level)
174 int32 NewLevel =atoi((char*)Level);
175 if ( NewLevel <0 )
176 NewLevel = 0;
177 m_logFileLevel = NewLevel;
179 printf( "LogFileLevel is %u\n",m_logFileLevel );
182 void Log::Initialize()
184 /// Common log files data
185 m_logsDir = sConfig.GetStringDefault("LogsDir","");
186 if(!m_logsDir.empty())
188 if((m_logsDir.at(m_logsDir.length()-1)!='/') && (m_logsDir.at(m_logsDir.length()-1)!='\\'))
189 m_logsDir.append("/");
192 m_logsTimestamp = "_" + GetTimestampStr();
194 /// Open specific log files
195 logfile = openLogFile("LogFile","LogTimestamp","w");
197 m_gmlog_per_account = sConfig.GetBoolDefault("GmLogPerAccount",false);
198 if(!m_gmlog_per_account)
199 gmLogfile = openLogFile("GMLogFile","GmLogTimestamp","a");
200 else
202 // GM log settings for per account case
203 m_gmlog_filename_format = sConfig.GetStringDefault("GMLogFile", "");
204 if(!m_gmlog_filename_format.empty())
206 bool m_gmlog_timestamp = sConfig.GetBoolDefault("GmLogTimestamp",false);
208 size_t dot_pos = m_gmlog_filename_format.find_last_of(".");
209 if(dot_pos!=m_gmlog_filename_format.npos)
211 if(m_gmlog_timestamp)
212 m_gmlog_filename_format.insert(dot_pos,m_logsTimestamp);
214 m_gmlog_filename_format.insert(dot_pos,"_#%u");
216 else
218 m_gmlog_filename_format += "_#%u";
220 if(m_gmlog_timestamp)
221 m_gmlog_filename_format += m_logsTimestamp;
224 m_gmlog_filename_format = m_logsDir + m_gmlog_filename_format;
228 charLogfile = openLogFile("CharLogFile","CharLogTimestamp","a");
229 dberLogfile = openLogFile("DBErrorLogFile",NULL,"a");
230 raLogfile = openLogFile("RaLogFile",NULL,"a");
231 worldLogfile = openLogFile("WorldLogFile","WorldLogTimestamp","a");
233 // Main log file settings
234 m_includeTime = sConfig.GetBoolDefault("LogTime", false);
235 m_logLevel = sConfig.GetIntDefault("LogLevel", 0);
236 m_logFileLevel = sConfig.GetIntDefault("LogFileLevel", 0);
237 InitColors(sConfig.GetStringDefault("LogColors", ""));
239 m_logFilter = 0;
241 if(sConfig.GetBoolDefault("LogFilter_TransportMoves", true))
242 m_logFilter |= LOG_FILTER_TRANSPORT_MOVES;
243 if(sConfig.GetBoolDefault("LogFilter_CreatureMoves", true))
244 m_logFilter |= LOG_FILTER_CREATURE_MOVES;
245 if(sConfig.GetBoolDefault("LogFilter_VisibilityChanges", true))
246 m_logFilter |= LOG_FILTER_VISIBILITY_CHANGES;
247 if(sConfig.GetBoolDefault("LogFilter_AchievementUpdates", true))
248 m_logFilter |= LOG_FILTER_ACHIEVEMENT_UPDATES;
250 // Char log settings
251 m_charLog_Dump = sConfig.GetBoolDefault("CharLogDump", false);
254 FILE* Log::openLogFile(char const* configFileName,char const* configTimeStampFlag, char const* mode)
256 std::string logfn=sConfig.GetStringDefault(configFileName, "");
257 if(logfn.empty())
258 return NULL;
260 if(configTimeStampFlag && sConfig.GetBoolDefault(configTimeStampFlag,false))
262 size_t dot_pos = logfn.find_last_of(".");
263 if(dot_pos!=logfn.npos)
264 logfn.insert(dot_pos,m_logsTimestamp);
265 else
266 logfn += m_logsTimestamp;
269 return fopen((m_logsDir+logfn).c_str(), mode);
272 FILE* Log::openGmlogPerAccount(uint32 account)
274 if(m_gmlog_filename_format.empty())
275 return NULL;
277 char namebuf[MANGOS_PATH_MAX];
278 snprintf(namebuf,MANGOS_PATH_MAX,m_gmlog_filename_format.c_str(),account);
279 return fopen(namebuf, "a");
282 void Log::outTimestamp(FILE* file)
284 time_t t = time(NULL);
285 tm* aTm = localtime(&t);
286 // YYYY year
287 // MM month (2 digits 01-12)
288 // DD day (2 digits 01-31)
289 // HH hour (2 digits 00-23)
290 // MM minutes (2 digits 00-59)
291 // SS seconds (2 digits 00-59)
292 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);
295 void Log::outTime()
297 time_t t = time(NULL);
298 tm* aTm = localtime(&t);
299 // YYYY year
300 // MM month (2 digits 01-12)
301 // DD day (2 digits 01-31)
302 // HH hour (2 digits 00-23)
303 // MM minutes (2 digits 00-59)
304 // SS seconds (2 digits 00-59)
305 printf("%02d:%02d:%02d ",aTm->tm_hour,aTm->tm_min,aTm->tm_sec);
308 std::string Log::GetTimestampStr()
310 time_t t = time(NULL);
311 tm* aTm = localtime(&t);
312 // YYYY year
313 // MM month (2 digits 01-12)
314 // DD day (2 digits 01-31)
315 // HH hour (2 digits 00-23)
316 // MM minutes (2 digits 00-59)
317 // SS seconds (2 digits 00-59)
318 char buf[20];
319 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);
320 return std::string(buf);
323 void Log::outTitle( const char * str)
325 if( !str )
326 return;
328 if(m_colored)
329 SetColor(true,WHITE);
331 // not expected utf8 and then send as-is
332 printf("%s", str);
334 if(m_colored)
335 ResetColor(true);
337 printf("\n");
338 if(logfile)
340 fprintf(logfile, "%s", str);
341 fprintf(logfile, "\n" );
342 fflush(logfile);
345 fflush(stdout);
348 void Log::outString()
350 if(m_includeTime)
351 outTime();
352 printf( "\n" );
353 if(logfile)
355 outTimestamp(logfile);
356 fprintf(logfile, "\n" );
357 fflush(logfile);
359 fflush(stdout);
362 void Log::outString( const char * str, ... )
364 if( !str )
365 return;
367 if(m_colored)
368 SetColor(true,m_colors[LogNormal]);
370 if(m_includeTime)
371 outTime();
373 va_list ap;
375 va_start(ap, str);
376 vutf8printf(stdout, str, &ap);
377 va_end(ap);
379 if(m_colored)
380 ResetColor(true);
382 printf( "\n" );
383 if(logfile)
385 outTimestamp(logfile);
387 va_start(ap, str);
388 vfprintf(logfile, str, ap);
389 fprintf(logfile, "\n" );
390 va_end(ap);
392 fflush(logfile);
394 fflush(stdout);
397 void Log::outError( const char * err, ... )
399 if( !err )
400 return;
402 if(m_colored)
403 SetColor(false,m_colors[LogError]);
405 if(m_includeTime)
406 outTime();
408 va_list ap;
410 va_start(ap, err);
411 vutf8printf(stderr, err, &ap);
412 va_end(ap);
414 if(m_colored)
415 ResetColor(false);
417 fprintf( stderr, "\n" );
418 if(logfile)
420 outTimestamp(logfile);
421 fprintf(logfile, "ERROR:" );
423 va_start(ap, err);
424 vfprintf(logfile, err, ap);
425 va_end(ap);
427 fprintf(logfile, "\n" );
428 fflush(logfile);
430 fflush(stderr);
433 void Log::outErrorDb( const char * err, ... )
435 if( !err )
436 return;
438 if(m_colored)
439 SetColor(false,m_colors[LogError]);
441 if(m_includeTime)
442 outTime();
444 va_list ap;
446 va_start(ap, err);
447 vutf8printf(stderr, err, &ap);
448 va_end(ap);
450 if(m_colored)
451 ResetColor(false);
453 fprintf( stderr, "\n" );
455 if(logfile)
457 outTimestamp(logfile);
458 fprintf(logfile, "ERROR:" );
460 va_start(ap, err);
461 vfprintf(logfile, err, ap);
462 va_end(ap);
464 fprintf(logfile, "\n" );
465 fflush(logfile);
468 if(dberLogfile)
470 outTimestamp(dberLogfile);
472 va_list ap;
473 va_start(ap, err);
474 vfprintf(dberLogfile, err, ap);
475 va_end(ap);
477 fprintf(dberLogfile, "\n" );
478 fflush(dberLogfile);
480 fflush(stderr);
483 void Log::outBasic( const char * str, ... )
485 if( !str )
486 return;
488 if( m_logLevel > 0 )
490 if(m_colored)
491 SetColor(true,m_colors[LogDetails]);
493 if(m_includeTime)
494 outTime();
496 va_list ap;
497 va_start(ap, str);
498 vutf8printf(stdout, str, &ap);
499 va_end(ap);
501 if(m_colored)
502 ResetColor(true);
504 printf( "\n" );
507 if(logfile && m_logFileLevel > 0)
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);
517 fflush(stdout);
520 void Log::outDetail( const char * str, ... )
522 if( !str )
523 return;
525 if( m_logLevel > 1 )
528 if(m_colored)
529 SetColor(true,m_colors[LogDetails]);
531 if(m_includeTime)
532 outTime();
534 va_list ap;
535 va_start(ap, str);
536 vutf8printf(stdout, str, &ap);
537 va_end(ap);
539 if(m_colored)
540 ResetColor(true);
542 printf( "\n" );
544 if(logfile && m_logFileLevel > 1)
546 outTimestamp(logfile);
548 va_list ap;
549 va_start(ap, str);
550 vfprintf(logfile, str, ap);
551 va_end(ap);
553 fprintf(logfile, "\n" );
554 fflush(logfile);
557 fflush(stdout);
560 void Log::outDebugInLine( const char * str, ... )
562 if( !str )
563 return;
564 if( m_logLevel > 2 )
566 if(m_colored)
567 SetColor(true,m_colors[LogDebug]);
569 va_list ap;
570 va_start(ap, str);
571 vutf8printf(stdout, str, &ap);
572 va_end(ap);
574 if(m_colored)
575 ResetColor(true);
577 if(logfile && m_logFileLevel > 2)
579 va_list ap;
580 va_start(ap, str);
581 vfprintf(logfile, str, ap);
582 va_end(ap);
586 void Log::outDebug( const char * str, ... )
588 if( !str )
589 return;
590 if( m_logLevel > 2 )
592 if(m_colored)
593 SetColor(true,m_colors[LogDebug]);
595 if(m_includeTime)
596 outTime();
598 va_list ap;
599 va_start(ap, str);
600 vutf8printf(stdout, str, &ap);
601 va_end(ap);
603 if(m_colored)
604 ResetColor(true);
606 printf( "\n" );
608 if(logfile && m_logFileLevel > 2)
610 outTimestamp(logfile);
612 va_list ap;
613 va_start(ap, str);
614 vfprintf(logfile, str, ap);
615 va_end(ap);
617 fprintf(logfile, "\n" );
618 fflush(logfile);
620 fflush(stdout);
623 void Log::outCommand( uint32 account, const char * str, ... )
625 if( !str )
626 return;
628 if( m_logLevel > 1 )
630 if(m_colored)
631 SetColor(true,m_colors[LogDetails]);
633 if(m_includeTime)
634 outTime();
636 va_list ap;
637 va_start(ap, str);
638 vutf8printf(stdout, str, &ap);
639 va_end(ap);
641 if(m_colored)
642 ResetColor(true);
644 printf( "\n" );
646 if(logfile && m_logFileLevel > 1)
648 va_list ap;
649 outTimestamp(logfile);
650 va_start(ap, str);
651 vfprintf(logfile, str, ap);
652 fprintf(logfile, "\n" );
653 va_end(ap);
654 fflush(logfile);
657 if (m_gmlog_per_account)
659 if (FILE* per_file = openGmlogPerAccount (account))
661 va_list ap;
662 outTimestamp(per_file);
663 va_start(ap, str);
664 vfprintf(per_file, str, ap);
665 fprintf(per_file, "\n" );
666 va_end(ap);
667 fclose(per_file);
670 else if (gmLogfile)
672 va_list ap;
673 outTimestamp(gmLogfile);
674 va_start(ap, str);
675 vfprintf(gmLogfile, str, ap);
676 fprintf(gmLogfile, "\n" );
677 va_end(ap);
678 fflush(gmLogfile);
681 fflush(stdout);
684 void Log::outChar(const char * str, ... )
687 if (!str)
688 return;
690 if(charLogfile)
692 va_list ap;
693 outTimestamp(charLogfile);
694 va_start(ap, str);
695 vfprintf(charLogfile, str, ap);
696 fprintf(charLogfile, "\n" );
697 va_end(ap);
698 fflush(charLogfile);
702 void Log::outWorldPacketDump( uint32 socket, uint32 opcode, char const* opcodeName, ByteBuffer const* packet, bool incoming )
704 if (!worldLogfile)
705 return;
707 outTimestamp(worldLogfile);
709 fprintf(worldLogfile,"\n%s:\nSOCKET: %u\nLENGTH: " SIZEFMTD "\nOPCODE: %s (0x%.4X)\nDATA:\n",
710 incoming ? "CLIENT" : "SERVER",
711 socket, packet->size(), opcodeName, opcode);
713 size_t p = 0;
714 while (p < packet->size())
716 for (size_t j = 0; j < 16 && p < packet->size(); ++j)
717 fprintf(worldLogfile, "%.2X ", (*packet)[p++]);
719 fprintf(worldLogfile, "\n");
722 fprintf(worldLogfile, "\n\n");
723 fflush(worldLogfile);
726 void Log::outCharDump( const char * str, uint32 account_id, uint32 guid, const char * name )
728 if(charLogfile)
730 fprintf(charLogfile, "== START DUMP == (account: %u guid: %u name: %s )\n%s\n== END DUMP ==\n",account_id,guid,name,str );
731 fflush(charLogfile);
735 void Log::outMenu( const char * str, ... )
737 if( !str )
738 return;
740 SetColor(true,m_colors[LogNormal]);
742 if(m_includeTime)
743 outTime();
745 va_list ap;
747 va_start(ap, str);
748 vutf8printf(stdout, str, &ap);
749 va_end(ap);
751 ResetColor(true);
753 if(logfile)
755 outTimestamp(logfile);
757 va_start(ap, str);
758 vfprintf(logfile, str, ap);
759 va_end(ap);
761 fprintf(logfile, "\n" );
762 fflush(logfile);
764 fflush(stdout);
767 void Log::outRALog( const char * str, ... )
769 if( !str )
770 return;
771 va_list ap;
772 if (raLogfile)
774 outTimestamp(raLogfile);
775 va_start(ap, str);
776 vfprintf(raLogfile, str, ap);
777 fprintf(raLogfile, "\n" );
778 va_end(ap);
779 fflush(raLogfile);
781 fflush(stdout);
784 void outstring_log(const char * str, ...)
786 if( !str )
787 return;
789 char buf[256];
790 va_list ap;
791 va_start(ap, str);
792 vsnprintf(buf, 256, str, ap);
793 va_end(ap);
795 sLog.outString("%s", buf);
798 void detail_log(const char * str, ...)
800 if( !str )
801 return;
803 char buf[256];
804 va_list ap;
805 va_start(ap, str);
806 vsnprintf(buf,256, str, ap);
807 va_end(ap);
809 sLog.outDetail("%s", buf);
812 void debug_log(const char * str, ...)
814 if( !str )
815 return;
817 char buf[256];
818 va_list ap;
819 va_start(ap, str);
820 vsnprintf(buf,256, str, ap);
821 va_end(ap);
823 sLog.outDebug("%s", buf);
826 void error_log(const char * str, ...)
828 if( !str )
829 return;
831 char buf[256];
832 va_list ap;
833 va_start(ap, str);
834 vsnprintf(buf,256, str, ap);
835 va_end(ap);
837 sLog.outError("%s", buf);
840 void error_db_log(const char * str, ...)
842 if( !str )
843 return;
845 char buf[256];
846 va_list ap;
847 va_start(ap, str);
848 vsnprintf(buf,256, str, ap);
849 va_end(ap);
851 sLog.outErrorDb("%s", buf);