2012-08-03 17:29:43 +02:00
/*
2020-01-02 06:44:10 +01:00
* This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
2012-08-03 17:29:43 +02:00
*
* 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, see <http://www.gnu.org/licenses/>.
*/
2012-08-03 14:20:18 +02:00
#include "AppenderConsole.h"
2017-05-11 22:29:51 +02:00
#include "LogMessage.h"
2020-08-28 00:11:16 +02:00
#include "SmartEnum.h"
#include "StringFormat.h"
#include "StringConvert.h"
2012-08-03 14:20:18 +02:00
#include "Util.h"
2017-03-04 18:44:13 +01:00
#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS
2014-07-20 02:54:12 +02:00
#include <Windows.h>
#endif
2012-08-03 14:20:18 +02:00
2020-08-28 00:11:16 +02:00
AppenderConsole :: AppenderConsole ( uint8 id , std :: string const & name , LogLevel level , AppenderFlags flags , std :: vector < std :: string_view > const & args )
2015-08-16 00:12:18 +02:00
: Appender ( id , name , level , flags ), _colored ( false )
2012-08-03 14:20:18 +02:00
{
2017-05-11 22:29:51 +02:00
for ( uint8 i = 0 ; i < NUM_ENABLED_LOG_LEVELS ; ++ i )
2020-08-28 00:11:16 +02:00
_colors [ i ] = ColorTypes ( NUM_COLOR_TYPES );
2015-08-16 00:12:18 +02:00
2020-08-28 00:11:16 +02:00
if ( 3 < args . size ())
InitColors ( name , args [ 3 ]);
2012-08-03 14:20:18 +02:00
}
2020-08-28 00:11:16 +02:00
void AppenderConsole :: InitColors ( std :: string const & name , std :: string_view str )
2012-08-03 14:20:18 +02:00
{
if ( str . empty ())
{
_colored = false ;
return ;
}
2020-08-28 00:11:16 +02:00
std :: vector < std :: string_view > colorStrs = Trinity :: Tokenize ( str , ' ' , false );
if ( colorStrs . size () != NUM_ENABLED_LOG_LEVELS )
2012-08-03 14:20:18 +02:00
{
2020-08-28 00:11:16 +02:00
throw InvalidAppenderArgsException ( Trinity :: StringFormat ( "Log::CreateAppenderFromConfig: Invalid color data '%s' for console appender %s (expected %u entries, got %zu)",
std :: string ( str ). c_str (), name . c_str (), NUM_ENABLED_LOG_LEVELS , colorStrs . size ()));
2012-08-03 14:20:18 +02:00
}
2017-05-11 22:29:51 +02:00
for ( uint8 i = 0 ; i < NUM_ENABLED_LOG_LEVELS ; ++ i )
2020-08-28 00:11:16 +02:00
{
if ( Optional < uint8 > color = Trinity :: StringTo < uint8 > ( colorStrs [ i ]); color && EnumUtils :: IsValid < ColorTypes > ( * color ))
_colors [ i ] = static_cast < ColorTypes > ( * color );
else
{
throw InvalidAppenderArgsException ( Trinity :: StringFormat ( "Log::CreateAppenderFromConfig: Invalid color '%s' for log level %s on console appender %s" ,
std :: string ( colorStrs [ i ]). c_str (), EnumUtils :: ToTitle ( static_cast < LogLevel > ( i )), name . c_str ()));
}
}
2012-08-03 14:20:18 +02:00
_colored = true ;
}
void AppenderConsole :: SetColor ( bool stdout_stream , ColorTypes color )
{
2017-03-04 18:44:13 +01:00
#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS
2020-08-28 00:11:16 +02:00
static WORD WinColorFG [ NUM_COLOR_TYPES ] =
2012-08-03 14:20:18 +02:00
{
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 ]);
2013-11-11 14:34:44 +01:00
#else
2012-08-03 14:20:18 +02:00
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
};
2020-08-28 00:11:16 +02:00
static uint8 UnixColorFG [ NUM_COLOR_TYPES ] =
2012-08-03 14:20:18 +02:00
{
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
};
2020-08-28 00:11:16 +02:00
fprintf (( stdout_stream ? stdout : stderr ), " \x1b [%d%sm" , UnixColorFG [ color ], ( color >= YELLOW && color < NUM_COLOR_TYPES ? ";1" : "" ));
2012-08-03 14:20:18 +02:00
#endif
}
void AppenderConsole :: ResetColor ( bool stdout_stream )
{
2017-03-04 18:44:13 +01:00
#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS
2012-08-03 14:20:18 +02:00
HANDLE hConsole = GetStdHandle ( stdout_stream ? STD_OUTPUT_HANDLE : STD_ERROR_HANDLE );
SetConsoleTextAttribute ( hConsole , FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED );
#else
fprintf (( stdout_stream ? stdout : stderr ), " \x1b [0m" );
#endif
}
2015-03-11 10:06:24 +01:00
void AppenderConsole :: _write ( LogMessage const * message )
2012-08-03 14:20:18 +02:00
{
2015-03-11 10:06:24 +01:00
bool stdout_stream = ! ( message -> level == LOG_LEVEL_ERROR || message -> level == LOG_LEVEL_FATAL );
2012-08-03 14:20:18 +02:00
if ( _colored )
{
uint8 index ;
2015-03-11 10:06:24 +01:00
switch ( message -> level )
2012-08-03 14:20:18 +02:00
{
case LOG_LEVEL_TRACE :
index = 5 ;
break ;
case LOG_LEVEL_DEBUG :
index = 4 ;
break ;
case LOG_LEVEL_INFO :
index = 3 ;
break ;
case LOG_LEVEL_WARN :
index = 2 ;
break ;
case LOG_LEVEL_FATAL :
index = 0 ;
break ;
2019-03-30 17:48:36 +01:00
case LOG_LEVEL_ERROR :
2020-07-18 20:42:28 +02:00
[[fallthrough]] ;
2012-08-03 14:20:18 +02:00
default :
index = 1 ;
break ;
}
SetColor ( stdout_stream , _colors [ index ]);
2015-03-11 10:06:24 +01:00
utf8printf ( stdout_stream ? stdout : stderr , "%s%s \n " , message -> prefix . c_str (), message -> text . c_str ());
2012-08-03 14:20:18 +02:00
ResetColor ( stdout_stream );
}
else
2015-03-11 10:06:24 +01:00
utf8printf ( stdout_stream ? stdout : stderr , "%s%s \n " , message -> prefix . c_str (), message -> text . c_str ());
2012-08-03 14:20:18 +02:00
}