Files
TCPlayerbotCore/src/shared/Log.cpp
T

664 lines
15 KiB
C++
Raw Normal View History

/*
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
2008-10-14 11:57:03 -05:00
*
* Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/>
2008-10-02 16:23:55 -05: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
2008-10-14 11:57:03 -05:00
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2008-10-02 16:23:55 -05:00
* 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
2008-10-14 11:57:03 -05:00
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2008-10-02 16:23:55 -05:00
*/
#include "Common.h"
#include "Log.h"
#include "Policies/SingletonImp.h"
#include "Config/ConfigEnv.h"
#include "Util.h"
#include <stdarg.h>
2009-03-19 21:13:52 +01:00
#include <stdio.h>
2008-10-02 16:23:55 -05:00
INSTANTIATE_SINGLETON_1( Log );
enum LogType
{
LogNormal = 0,
LogDetails,
LogDebug,
LogError
};
const int LogType_count = int(LogError) +1;
2008-11-25 16:36:50 -06:00
Log::Log() :
raLogfile(NULL), logfile(NULL), gmLogfile(NULL), charLogfile(NULL),
2009-03-19 21:13:52 +01:00
dberLogfile(NULL), m_gmlog_per_account(false)
2008-11-25 16:36:50 -06:00
{
Initialize();
}
2009-03-19 21:13:52 +01:00
Log::~Log()
2008-10-02 16:23:55 -05:00
{
2009-03-19 21:13:52 +01:00
if( logfile != NULL )
fclose(logfile);
logfile = NULL;
2008-10-02 16:23:55 -05:00
2009-03-19 21:13:52 +01:00
if( gmLogfile != NULL )
fclose(gmLogfile);
gmLogfile = NULL;
2008-10-02 16:23:55 -05:00
2009-03-19 21:13:52 +01:00
if (charLogfile != NULL)
fclose(charLogfile);
charLogfile = NULL;
2008-10-02 16:23:55 -05:00
2009-03-19 21:13:52 +01:00
if( dberLogfile != NULL )
fclose(dberLogfile);
dberLogfile = NULL;
2008-10-02 16:23:55 -05:00
2009-03-19 21:13:52 +01:00
if (raLogfile != NULL)
fclose(raLogfile);
raLogfile = NULL;
2008-10-02 16:23:55 -05:00
}
void Log::SetLogLevel(char *Level)
{
int32 NewLevel =atoi((char*)Level);
if ( NewLevel <0 )
NewLevel = 0;
m_logLevel = NewLevel;
2009-03-19 21:13:52 +01:00
outString( "LogLevel is %u",m_logLevel );
2008-10-02 16:23:55 -05:00
}
void Log::SetLogFileLevel(char *Level)
{
int32 NewLevel =atoi((char*)Level);
if ( NewLevel <0 )
NewLevel = 0;
m_logFileLevel = NewLevel;
2009-03-19 21:13:52 +01:00
outString( "LogFileLevel is %u",m_logFileLevel );
}
void Log::SetDBLogLevel(char *Level)
{
int32 NewLevel = atoi((char*)Level);
if ( NewLevel < 0 )
NewLevel = 0;
m_dbLogLevel = NewLevel;
outString( "DBLogLevel is %u",m_dbLogLevel );
2008-10-02 16:23:55 -05:00
}
void Log::Initialize()
{
2009-03-19 21:13:52 +01:00
/// Check whether we'll log GM commands/RA events/character outputs
m_dbChar = sConfig.GetBoolDefault("DBLog.Char", false);
m_dbRA = sConfig.GetBoolDefault("DBLog.RA", false);
m_dbGM = sConfig.GetBoolDefault("DBLog.GM", false);
2008-11-25 16:36:50 -06:00
/// Common log files data
m_logsDir = sConfig.GetStringDefault("LogsDir","");
if(!m_logsDir.empty())
2008-10-02 16:23:55 -05:00
{
2008-11-25 16:36:50 -06:00
if((m_logsDir.at(m_logsDir.length()-1)!='/') && (m_logsDir.at(m_logsDir.length()-1)!='\\'))
m_logsDir.append("/");
2008-10-02 16:23:55 -05:00
}
2008-11-25 16:36:50 -06:00
m_logsTimestamp = "_" + GetTimestampStr();
2008-10-02 16:23:55 -05:00
2008-11-25 16:36:50 -06:00
/// Open specific log files
logfile = openLogFile("LogFile","LogTimestamp","w");
2008-10-02 16:23:55 -05:00
2008-11-25 16:36:50 -06:00
m_gmlog_per_account = sConfig.GetBoolDefault("GmLogPerAccount",false);
if(!m_gmlog_per_account)
gmLogfile = openLogFile("GMLogFile","GmLogTimestamp","a");
else
2008-10-02 16:23:55 -05:00
{
2008-11-25 16:36:50 -06:00
// GM log settings for per account case
m_gmlog_filename_format = sConfig.GetStringDefault("GMLogFile", "");
if(!m_gmlog_filename_format.empty())
2008-10-02 16:23:55 -05:00
{
2008-11-25 16:36:50 -06:00
bool m_gmlog_timestamp = sConfig.GetBoolDefault("GmLogTimestamp",false);
2008-10-02 16:23:55 -05:00
2008-11-25 16:36:50 -06:00
size_t dot_pos = m_gmlog_filename_format.find_last_of(".");
if(dot_pos!=m_gmlog_filename_format.npos)
{
if(m_gmlog_timestamp)
m_gmlog_filename_format.insert(dot_pos,m_logsTimestamp);
m_gmlog_filename_format.insert(dot_pos,"_#%u");
}
2008-10-02 16:23:55 -05:00
else
2008-11-25 16:36:50 -06:00
{
m_gmlog_filename_format += "_#%u";
if(m_gmlog_timestamp)
m_gmlog_filename_format += m_logsTimestamp;
}
m_gmlog_filename_format = m_logsDir + m_gmlog_filename_format;
2008-10-02 16:23:55 -05:00
}
}
2008-11-25 16:36:50 -06:00
charLogfile = openLogFile("CharLogFile","CharLogTimestamp","a");
dberLogfile = openLogFile("DBErrorLogFile",NULL,"a");
raLogfile = openLogFile("RaLogFile",NULL,"a");
// Main log file settings
2009-03-19 21:13:52 +01:00
m_logLevel = sConfig.GetIntDefault("LogLevel", LOGL_NORMAL);
m_logFileLevel = sConfig.GetIntDefault("LogFileLevel", LOGL_NORMAL);
m_dbLogLevel = sConfig.GetIntDefault("DBLogLevel", LOGL_NORMAL);
2008-10-02 16:23:55 -05:00
m_logFilter = 0;
if(sConfig.GetBoolDefault("LogFilter_TransportMoves", true))
m_logFilter |= LOG_FILTER_TRANSPORT_MOVES;
if(sConfig.GetBoolDefault("LogFilter_CreatureMoves", true))
m_logFilter |= LOG_FILTER_CREATURE_MOVES;
if(sConfig.GetBoolDefault("LogFilter_VisibilityChanges", true))
m_logFilter |= LOG_FILTER_VISIBILITY_CHANGES;
if(sConfig.GetBoolDefault("LogFilter_AchievementUpdates", true))
m_logFilter |= LOG_FILTER_ACHIEVEMENT_UPDATES;
2008-10-02 16:23:55 -05:00
2008-11-25 16:36:50 -06:00
// Char log settings
2008-10-02 16:23:55 -05:00
m_charLog_Dump = sConfig.GetBoolDefault("CharLogDump", false);
}
2008-11-25 16:36:50 -06:00
FILE* Log::openLogFile(char const* configFileName,char const* configTimeStampFlag, char const* mode)
{
std::string logfn=sConfig.GetStringDefault(configFileName, "");
if(logfn.empty())
return NULL;
if(configTimeStampFlag && sConfig.GetBoolDefault(configTimeStampFlag,false))
{
size_t dot_pos = logfn.find_last_of(".");
if(dot_pos!=logfn.npos)
logfn.insert(dot_pos,m_logsTimestamp);
else
logfn += m_logsTimestamp;
}
return fopen((m_logsDir+logfn).c_str(), mode);
}
FILE* Log::openGmlogPerAccount(uint32 account)
{
if(m_gmlog_filename_format.empty())
return NULL;
2008-11-26 14:23:50 -06:00
char namebuf[TRINITY_PATH_MAX];
snprintf(namebuf,TRINITY_PATH_MAX,m_gmlog_filename_format.c_str(),account);
2008-11-25 16:36:50 -06:00
return fopen(namebuf, "a");
}
2008-10-02 16:23:55 -05:00
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);
}
2009-03-19 21:13:52 +01:00
void Log::outDB( uint8 type, const char * str, ... )
2008-10-02 16:23:55 -05:00
{
2009-03-19 21:13:52 +01:00
if(!str)
2008-10-02 16:23:55 -05:00
return;
2009-03-19 21:13:52 +01:00
std::string new_str(str);
LoginDatabase.escape_string(new_str);
char nnew_str[MAX_QUERY_LEN];
2008-10-02 16:23:55 -05:00
2009-03-19 21:13:52 +01:00
va_list ap;
va_start(ap, str);
int res = vsnprintf(nnew_str, MAX_QUERY_LEN, new_str.c_str(), ap);
va_end(ap);
2008-10-02 16:23:55 -05:00
2009-03-19 21:13:52 +01:00
if ( (res < 0) || (!nnew_str) || (std::string(nnew_str).empty()) )
return;
2008-10-02 16:23:55 -05:00
2009-03-19 21:13:52 +01:00
LoginDatabase.PExecute("INSERT INTO logs (time, realm, type, string) "
"VALUES (%u, %u, %u, '%s');", time(0), realm, type, nnew_str);
2008-10-02 16:23:55 -05:00
}
void Log::outString( const char * str, ... )
{
if( !str )
return;
2009-03-19 21:13:52 +01:00
if (m_enableLogDB)
{
// we don't want empty strings in the DB
std::string s(str);
if(s.empty() || s == " ")
return;
2008-10-02 16:23:55 -05:00
2009-03-19 21:13:52 +01:00
va_list ap2;
va_start(ap2, str);
char nnew_str[MAX_QUERY_LEN];
vsnprintf(nnew_str, MAX_QUERY_LEN, str, ap2);
outDB(LOG_TYPE_STRING, nnew_str);
va_end(ap2);
}
2008-10-02 16:23:55 -05:00
UTF8PRINTF(stdout,str,);
printf( "\n" );
if(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;
2009-03-19 21:13:52 +01:00
if (m_enableLogDB)
{
va_list ap2;
va_start(ap2, err);
char nnew_str[MAX_QUERY_LEN];
vsnprintf(nnew_str, MAX_QUERY_LEN, err, ap2);
outDB(LOG_TYPE_ERROR, nnew_str);
va_end(ap2);
}
2008-10-02 16:23:55 -05:00
UTF8PRINTF(stderr,err,);
fprintf( stderr, "\n" );
if(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;
2009-03-19 21:13:52 +01:00
if (m_enableLogDB)
{
va_list ap2;
va_start(ap2, err);
char nnew_str[MAX_QUERY_LEN];
vsnprintf(nnew_str, MAX_QUERY_LEN, err, ap2);
outDB(LOG_TYPE_DBERR, nnew_str);
va_end(ap2);
}
2008-10-02 16:23:55 -05:00
UTF8PRINTF(stderr,err,);
fprintf( stderr, "\n" );
if(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)
{
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;
2009-03-19 21:13:52 +01:00
if (m_enableLogDB && m_dbLogLevel > LOGL_NORMAL)
2008-10-02 16:23:55 -05:00
{
2009-03-19 21:13:52 +01:00
va_list ap2;
va_start(ap2, str);
char nnew_str[MAX_QUERY_LEN];
vsnprintf(nnew_str, MAX_QUERY_LEN, str, ap2);
outDB(LOG_TYPE_BASIC, nnew_str);
va_end(ap2);
}
2008-10-02 16:23:55 -05:00
2009-03-19 21:13:52 +01:00
if( m_logLevel > LOGL_NORMAL )
{
2008-10-02 16:23:55 -05:00
UTF8PRINTF(stdout,str,);
printf( "\n" );
}
2009-03-19 21:13:52 +01:00
if(logfile && m_logFileLevel > LOGL_NORMAL)
2008-10-02 16:23:55 -05:00
{
va_list ap;
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;
2009-03-19 21:13:52 +01:00
if (m_enableLogDB && m_dbLogLevel >= LOGL_BASIC)
2008-10-02 16:23:55 -05:00
{
2009-03-19 21:13:52 +01:00
va_list ap2;
va_start(ap2, str);
char nnew_str[MAX_QUERY_LEN];
vsnprintf(nnew_str, MAX_QUERY_LEN, str, ap2);
outDB(LOG_TYPE_DETAIL, nnew_str);
va_end(ap2);
}
2008-10-02 16:23:55 -05:00
2009-03-19 21:13:52 +01:00
if( m_logLevel > LOGL_BASIC )
{
2008-10-02 16:23:55 -05:00
UTF8PRINTF(stdout,str,);
printf( "\n" );
}
2009-03-19 21:13:52 +01:00
if(logfile && m_logFileLevel > LOGL_BASIC)
2008-10-02 16:23:55 -05:00
{
va_list ap;
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;
2009-03-19 21:13:52 +01:00
if( m_logLevel > LOGL_DETAIL )
2008-10-02 16:23:55 -05:00
{
UTF8PRINTF(stdout,str,);
}
2009-03-19 21:13:52 +01:00
if(logfile && m_logFileLevel > LOGL_DETAIL)
2008-10-02 16:23:55 -05:00
{
va_list ap;
va_start(ap, str);
vfprintf(logfile, str, ap);
va_end(ap);
}
}
void Log::outDebug( const char * str, ... )
{
if( !str )
return;
2009-03-19 21:13:52 +01:00
if (m_enableLogDB && m_dbLogLevel >= LOGL_DETAIL)
{
va_list ap2;
va_start(ap2, str);
char nnew_str[MAX_QUERY_LEN];
vsnprintf(nnew_str, MAX_QUERY_LEN, str, ap2);
outDB(LOG_TYPE_DEBUG, nnew_str);
va_end(ap2);
}
2008-10-02 16:23:55 -05:00
2009-03-19 21:13:52 +01:00
if( m_logLevel > LOGL_DETAIL )
{
2008-10-02 16:23:55 -05:00
UTF8PRINTF(stdout,str,);
printf( "\n" );
}
2009-03-19 21:13:52 +01:00
if(logfile && m_logFileLevel > LOGL_DETAIL)
2008-10-02 16:23:55 -05:00
{
va_list ap;
va_start(ap, str);
vfprintf(logfile, str, ap);
va_end(ap);
fprintf(logfile, "\n" );
fflush(logfile);
}
fflush(stdout);
}
2008-11-25 16:36:50 -06:00
void Log::outCommand( uint32 account, const char * str, ... )
2008-10-02 16:23:55 -05:00
{
if( !str )
return;
2009-03-19 21:13:52 +01:00
// TODO: support accountid
if (m_enableLogDB && m_dbGM)
2008-10-02 16:23:55 -05:00
{
2009-03-19 21:13:52 +01:00
va_list ap2;
va_start(ap2, str);
char nnew_str[MAX_QUERY_LEN];
vsnprintf(nnew_str, MAX_QUERY_LEN, str, ap2);
outDB(LOG_TYPE_GM, nnew_str);
va_end(ap2);
}
2008-10-02 16:23:55 -05:00
2009-03-19 21:13:52 +01:00
if( m_logLevel > LOGL_NORMAL )
{
2008-10-02 16:23:55 -05:00
UTF8PRINTF(stdout,str,);
printf( "\n" );
}
2009-03-19 21:13:52 +01:00
if(logfile && m_logFileLevel > LOGL_NORMAL)
2008-10-02 16:23:55 -05:00
{
va_list ap;
va_start(ap, str);
vfprintf(logfile, str, ap);
fprintf(logfile, "\n" );
va_end(ap);
fflush(logfile);
}
2008-11-25 16:36:50 -06:00
if (m_gmlog_per_account)
{
if (FILE* per_file = openGmlogPerAccount (account))
{
va_list ap;
va_start(ap, str);
vfprintf(per_file, str, ap);
fprintf(per_file, "\n" );
va_end(ap);
fclose(per_file);
}
}
else if (gmLogfile)
2008-10-02 16:23:55 -05:00
{
va_list ap;
va_start(ap, str);
vfprintf(gmLogfile, str, ap);
fprintf(gmLogfile, "\n" );
va_end(ap);
fflush(gmLogfile);
}
2008-11-25 16:36:50 -06:00
2008-10-02 16:23:55 -05:00
fflush(stdout);
}
void Log::outChar(const char * str, ... )
{
if (!str)
return;
2009-03-19 21:13:52 +01:00
if (m_enableLogDB && m_dbChar)
{
va_list ap2;
va_start(ap2, str);
char nnew_str[MAX_QUERY_LEN];
vsnprintf(nnew_str, MAX_QUERY_LEN, str, ap2);
outDB(LOG_TYPE_CHAR, nnew_str);
va_end(ap2);
}
2008-10-02 16:23:55 -05:00
if(charLogfile)
{
va_list ap;
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);
}
}
2009-03-19 21:13:52 +01:00
void Log::outRemote( const char * str, ... )
2008-10-02 16:23:55 -05:00
{
if( !str )
return;
2009-03-19 21:13:52 +01:00
if (m_enableLogDB && m_dbRA)
2008-10-02 16:23:55 -05:00
{
2009-03-19 21:13:52 +01:00
va_list ap2;
va_start(ap2, str);
char nnew_str[MAX_QUERY_LEN];
vsnprintf(nnew_str, MAX_QUERY_LEN, str, ap2);
outDB(LOG_TYPE_RA, nnew_str);
va_end(ap2);
2008-10-02 16:23:55 -05:00
}
if (raLogfile)
{
2009-03-19 21:13:52 +01:00
va_list ap;
2008-10-02 16:23:55 -05:00
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);
2008-10-14 11:57:03 -05:00
Trinity::Singleton<Log>::Instance().outString(buf);
2008-10-02 16:23:55 -05:00
}
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);
2008-10-14 11:57:03 -05:00
Trinity::Singleton<Log>::Instance().outDetail(buf);
2008-10-02 16:23:55 -05:00
}
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);
2008-10-14 11:57:03 -05:00
Trinity::Singleton<Log>::Instance().outDebug(buf);
2008-10-02 16:23:55 -05:00
}
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);
2008-10-14 11:57:03 -05:00
Trinity::Singleton<Log>::Instance().outError(buf);
2008-10-02 16:23:55 -05:00
}
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);
2008-10-14 11:57:03 -05:00
Trinity::Singleton<Log>::Instance().outErrorDb(buf);
2008-10-02 16:23:55 -05:00
}
2009-02-17 20:07:49 -06:00