TrinityCore
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
Log Class Reference

#include <Log.h>

Public Member Functions

void Initialize (boost::asio::io_service *ioService)
 
void SetSynchronous ()
 
void LoadFromConfig ()
 
void Close ()
 
bool ShouldLog (std::string const &type, LogLevel level) const
 
bool SetLogLevel (std::string const &name, char const *level, bool isLogger=true)
 
template<typename Format , typename... Args>
void outMessage (std::string const &filter, LogLevel const level, Format &&fmt, Args &&...args)
 
template<typename Format , typename... Args>
void outCommand (uint32 account, Format &&fmt, Args &&...args)
 
void outCharDump (char const *str, uint32 account_id, uint64 guid, char const *name)
 
void SetRealmId (uint32 id)
 
template<class AppenderImpl >
void RegisterAppender ()
 
std::string constGetLogsDir () const
 
std::string constGetLogsTimestamp () const
 

Static Public Member Functions

static Loginstance ()
 

Private Types

typedef std::unordered_map
< std::string, Logger
LoggerMap
 

Private Member Functions

 Log ()
 
 ~Log ()
 
void write (std::unique_ptr< LogMessage > &&msg) const
 
Logger constGetLoggerByType (std::string const &type) const
 
AppenderGetAppenderByName (std::string const &name)
 
uint8 NextAppenderId ()
 
void CreateAppenderFromConfig (std::string const &name)
 
void CreateLoggerFromConfig (std::string const &name)
 
void ReadAppendersFromConfig ()
 
void ReadLoggersFromConfig ()
 

Static Private Member Functions

static std::string GetTimestampStr ()
 

Private Attributes

AppenderCreatorMap appenderFactory
 
AppenderMap appenders
 
LoggerMap loggers
 
uint8 AppenderId
 
LogLevel lowestLogLevel
 
std::string m_logsDir
 
std::string m_logsTimestamp
 
boost::asio::io_service * _ioService
 
boost::asio::strand * _strand
 

Member Typedef Documentation

typedef std::unordered_map<std::string, Logger> Log::LoggerMap
private

Constructor & Destructor Documentation

Log::Log ( )
private
32 {
34  RegisterAppender<AppenderConsole>();
35  RegisterAppender<AppenderFile>();
36 }
boost::asio::strand * _strand
Definition: Log.h:116
LogLevel lowestLogLevel
Definition: Log.h:110
static std::string GetTimestampStr()
Definition: Log.cpp:242
boost::asio::io_service * _ioService
Definition: Log.h:115
std::string m_logsTimestamp
Definition: Log.h:113
uint8 AppenderId
Definition: Log.h:109
Definition: Appender.h:39

+ Here is the call graph for this function:

Log::~Log ( )
private
39 {
40  delete _strand;
41  Close();
42 }
boost::asio::strand * _strand
Definition: Log.h:116
void Close()
Definition: Log.cpp:315

+ Here is the call graph for this function:

Member Function Documentation

void Log::Close ( )
316 {
317  loggers.clear();
318  for (AppenderMap::iterator it = appenders.begin(); it != appenders.end(); ++it)
319  delete it->second;
320 
321  appenders.clear();
322 }
LoggerMap loggers
Definition: Log.h:108
AppenderMap appenders
Definition: Log.h:107

+ Here is the caller graph for this function:

void Log::CreateAppenderFromConfig ( std::string const name)
private
71 {
72  if (appenderName.empty())
73  return;
74 
75  // Format=type, level, flags, optional1, optional2
76  // if type = File. optional1 = file and option2 = mode
77  // if type = Console. optional1 = Color
78  std::string options = sConfigMgr->GetStringDefault(appenderName.c_str(), "");
79 
80  Tokenizer tokens(options, ',');
81  Tokenizer::const_iterator iter = tokens.begin();
82 
83  size_t size = tokens.size();
84  std::string name = appenderName.substr(9);
85 
86  if (size < 2)
87  {
88  fprintf(stderr, "Log::CreateAppenderFromConfig: Wrong configuration for appender %s. Config line: %s\n", name.c_str(), options.c_str());
89  return;
90  }
91 
93  AppenderType type = AppenderType(atoi(*iter++));
94  LogLevel level = LogLevel(atoi(*iter++));
95 
96  if (level > LOG_LEVEL_FATAL)
97  {
98  fprintf(stderr, "Log::CreateAppenderFromConfig: Wrong Log Level %d for appender %s\n", level, name.c_str());
99  return;
100  }
101 
102  if (size > 2)
103  flags = AppenderFlags(atoi(*iter++));
104 
105  auto factoryFunction = appenderFactory.find(type);
106  if (factoryFunction == appenderFactory.end())
107  {
108  fprintf(stderr, "Log::CreateAppenderFromConfig: Unknown type %d for appender %s\n", type, name.c_str());
109  return;
110  }
111 
112  try
113  {
114  Appender* appender = factoryFunction->second(NextAppenderId(), name, level, flags, ExtraAppenderArgs(iter, tokens.end()));
115  appenders[appender->getId()] = appender;
116  }
117  catch (InvalidAppenderArgsException const& iaae)
118  {
119  fprintf(stderr, "%s", iaae.what());
120  }
121 }
AppenderType
Definition: Appender.h:44
Definition: Util.h:45
uint8 NextAppenderId()
Definition: Log.cpp:44
AppenderCreatorMap appenderFactory
Definition: Log.h:106
#define sConfigMgr
Definition: Config.h:61
FMT_API int fprintf(std::FILE *f, CStringRef format, ArgList args)
std::vector< char const * > ExtraAppenderArgs
Definition: Appender.h:116
uint8 getId() const
Definition: Appender.cpp:45
AppenderFlags
Definition: Appender.h:52
Definition: Appender.h:126
StorageType::const_iterator const_iterator
Definition: Util.h:52
LogLevel
Definition: Appender.h:31
AppenderMap appenders
Definition: Log.h:107
Definition: Appender.h:54
Definition: Appender.h:39
uint8 flags
Definition: DisableMgr.cpp:44
Definition: Appender.h:88

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void Log::CreateLoggerFromConfig ( std::string const name)
private
124 {
125  if (appenderName.empty())
126  return;
127 
129  uint8 type = uint8(-1);
130 
131  std::string options = sConfigMgr->GetStringDefault(appenderName.c_str(), "");
132  std::string name = appenderName.substr(7);
133 
134  if (options.empty())
135  {
136  fprintf(stderr, "Log::CreateLoggerFromConfig: Missing config option Logger.%s\n", name.c_str());
137  return;
138  }
139 
140  Tokenizer tokens(options, ',');
141  Tokenizer::const_iterator iter = tokens.begin();
142 
143  if (tokens.size() != 2)
144  {
145  fprintf(stderr, "Log::CreateLoggerFromConfig: Wrong config option Logger.%s=%s\n", name.c_str(), options.c_str());
146  return;
147  }
148 
149  Logger& logger = loggers[name];
150  if (!logger.getName().empty())
151  {
152  fprintf(stderr, "Error while configuring Logger %s. Already defined\n", name.c_str());
153  return;
154  }
155 
156  level = LogLevel(atoi(*iter++));
157  if (level > LOG_LEVEL_FATAL)
158  {
159  fprintf(stderr, "Log::CreateLoggerFromConfig: Wrong Log Level %u for logger %s\n", type, name.c_str());
160  return;
161  }
162 
163  if (level < lowestLogLevel)
164  lowestLogLevel = level;
165 
166  logger.Create(name, level);
167  //fprintf(stdout, "Log::CreateLoggerFromConfig: Created Logger %s, Level %u\n", name.c_str(), level);
168 
169  std::istringstream ss(*iter);
170  std::string str;
171 
172  ss >> str;
173  while (ss)
174  {
175  if (Appender* appender = GetAppenderByName(str))
176  {
177  logger.addAppender(appender->getId(), appender);
178  //fprintf(stdout, "Log::CreateLoggerFromConfig: Added Appender %s to Logger %s\n", appender->getName().c_str(), name.c_str());
179  }
180  else
181  fprintf(stderr, "Error while configuring Appender %s in Logger %s. Appender does not exist", str.c_str(), name.c_str());
182  ss >> str;
183  }
184 }
Definition: Logger.h:23
LoggerMap loggers
Definition: Log.h:108
void addAppender(uint8 type, Appender *)
Definition: Logger.cpp:38
Definition: Util.h:45
#define sConfigMgr
Definition: Config.h:61
FMT_API int fprintf(std::FILE *f, CStringRef format, ArgList args)
LogLevel lowestLogLevel
Definition: Log.h:110
void Create(std::string const &name, LogLevel level)
Definition: Logger.cpp:22
Appender * GetAppenderByName(std::string const &name)
Definition: Log.cpp:61
StorageType::const_iterator const_iterator
Definition: Util.h:52
Definition: Appender.h:33
LogLevel
Definition: Appender.h:31
uint8_t uint8
Definition: g3dmath.h:164
Definition: Appender.h:39
uint8_t uint8
Definition: Define.h:152
std::string const & getName() const
Definition: Logger.cpp:28
Definition: Appender.h:88

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Appender * Log::GetAppenderByName ( std::string const name)
private
62 {
63  AppenderMap::iterator it = appenders.begin();
64  while (it != appenders.end() && it->second && it->second->getName() != name)
65  ++it;
66 
67  return it == appenders.end() ? NULL : it->second;
68 }
arena_t NULL
Definition: jemalloc_internal.h:624
AppenderMap appenders
Definition: Log.h:107

+ Here is the caller graph for this function:

Logger const * Log::GetLoggerByType ( std::string const type) const
inlineprivate
120 {
121  LoggerMap::const_iterator it = loggers.find(type);
122  if (it != loggers.end())
123  return &(it->second);
124 
125  if (type == LOGGER_ROOT)
126  return NULL;
127 
128  std::string parentLogger = LOGGER_ROOT;
129  size_t found = type.find_last_of(".");
130  if (found != std::string::npos)
131  parentLogger = type.substr(0,found);
132 
133  return GetLoggerByType(parentLogger);
134 }
LoggerMap loggers
Definition: Log.h:108
arena_t NULL
Definition: jemalloc_internal.h:624
#define LOGGER_ROOT
Definition: Log.h:35
Logger const * GetLoggerByType(std::string const &type) const
Definition: Log.h:119

+ Here is the caller graph for this function:

std::string const& Log::GetLogsDir ( ) const
inline
91 { return m_logsDir; }
std::string m_logsDir
Definition: Log.h:112
std::string const& Log::GetLogsTimestamp ( ) const
inline
92 { return m_logsTimestamp; }
std::string m_logsTimestamp
Definition: Log.h:113
std::string Log::GetTimestampStr ( )
staticprivate
243 {
244  time_t tt = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
245 
246  std::tm aTm;
247  localtime_r(&tt, &aTm);
248 
249  // YYYY year
250  // MM month (2 digits 01-12)
251  // DD day (2 digits 01-31)
252  // HH hour (2 digits 00-23)
253  // MM minutes (2 digits 00-59)
254  // SS seconds (2 digits 00-59)
255  return Trinity::StringFormat("%04d-%02d-%02d_%02d-%02d-%02d",
256  aTm.tm_year + 1900, aTm.tm_mon + 1, aTm.tm_mday, aTm.tm_hour, aTm.tm_min, aTm.tm_sec);
257 }
std::string StringFormat(Format &&fmt, Args &&...args)
Default TC string format function.
Definition: StringFormat.h:28
TC_COMMON_API struct tm * localtime_r(const time_t *time, struct tm *result)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void Log::Initialize ( boost::asio::io_service *  ioService)
331 {
332  if (ioService)
333  {
334  _ioService = ioService;
335  _strand = new boost::asio::strand(*ioService);
336  }
337 
338  LoadFromConfig();
339 }
boost::asio::strand * _strand
Definition: Log.h:116
void LoadFromConfig()
Definition: Log.cpp:348
boost::asio::io_service * _ioService
Definition: Log.h:115

+ Here is the call graph for this function:

Log * Log::instance ( )
static
325 {
326  static Log instance;
327  return &instance;
328 }
static Log * instance()
Definition: Log.cpp:324
Definition: Log.h:37
void Log::LoadFromConfig ( )
349 {
350  Close();
351 
353  AppenderId = 0;
354  m_logsDir = sConfigMgr->GetStringDefault("LogsDir", "");
355  if (!m_logsDir.empty())
356  if ((m_logsDir.at(m_logsDir.length() - 1) != '/') && (m_logsDir.at(m_logsDir.length() - 1) != '\\'))
357  m_logsDir.push_back('/');
358 
361 }
std::string m_logsDir
Definition: Log.h:112
void ReadAppendersFromConfig()
Definition: Log.cpp:186
#define sConfigMgr
Definition: Config.h:61
LogLevel lowestLogLevel
Definition: Log.h:110
void Close()
Definition: Log.cpp:315
uint8 AppenderId
Definition: Log.h:109
Definition: Appender.h:39
void ReadLoggersFromConfig()
Definition: Log.cpp:197

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

uint8 Log::NextAppenderId ( )
private
45 {
46  return AppenderId++;
47 }
uint8 AppenderId
Definition: Log.h:109

+ Here is the caller graph for this function:

void Log::outCharDump ( char const str,
uint32  account_id,
uint64  guid,
char const name 
)
292 {
293  if (!str || !ShouldLog("entities.player.dump", LOG_LEVEL_INFO))
294  return;
295 
296  std::ostringstream ss;
297  ss << "== START DUMP == (account: " << accountId << " guid: " << guid << " name: " << name
298  << ")\n" << str << "\n== END DUMP ==\n";
299 
300  std::unique_ptr<LogMessage> msg(new LogMessage(LOG_LEVEL_INFO, "entities.player.dump", ss.str()));
301  std::ostringstream param;
302  param << guid << '_' << name;
303 
304  msg->param1 = param.str();
305 
306  write(std::move(msg));
307 }
Definition: Appender.h:36
void write(std::unique_ptr< LogMessage > &&msg) const
Definition: Log.cpp:228
Definition: Appender.h:62
bool ShouldLog(std::string const &type, LogLevel level) const
Definition: Log.h:136

+ Here is the call graph for this function:

template<typename Format , typename... Args>
void Log::outCommand ( uint32  account,
Format &&  fmt,
Args &&...  args 
)
inline
65  {
66  if (!ShouldLog("commands.gm", LOG_LEVEL_INFO))
67  return;
68 
69  std::unique_ptr<LogMessage> msg =
70  Trinity::make_unique<LogMessage>(LOG_LEVEL_INFO, "commands.gm",
71  Trinity::StringFormat(std::forward<Format>(fmt), std::forward<Args>(args)...));
72 
73  msg->param1 = std::to_string(account);
74 
75  write(std::move(msg));
76  }
Definition: Appender.h:36
void write(std::unique_ptr< LogMessage > &&msg) const
Definition: Log.cpp:228
std::string StringFormat(Format &&fmt, Args &&...args)
Default TC string format function.
Definition: StringFormat.h:28
Definition: format.h:285
std::string param1
Definition: Appender.h:78
bool ShouldLog(std::string const &type, LogLevel level) const
Definition: Log.h:136

+ Here is the call graph for this function:

template<typename Format , typename... Args>
void Log::outMessage ( std::string const filter,
LogLevel const  level,
Format &&  fmt,
Args &&...  args 
)
inline
58  {
59  write(Trinity::make_unique<LogMessage>(level, filter,
60  Trinity::StringFormat(std::forward<Format>(fmt), std::forward<Args>(args)...)));
61  }
void write(std::unique_ptr< LogMessage > &&msg) const
Definition: Log.cpp:228
std::string StringFormat(Format &&fmt, Args &&...args)
Default TC string format function.
Definition: StringFormat.h:28
Definition: format.h:285

+ Here is the call graph for this function:

void Log::ReadAppendersFromConfig ( )
private
187 {
188  std::list<std::string> keys = sConfigMgr->GetKeysByString("Appender.");
189 
190  while (!keys.empty())
191  {
192  CreateAppenderFromConfig(keys.front());
193  keys.pop_front();
194  }
195 }
void CreateAppenderFromConfig(std::string const &name)
Definition: Log.cpp:70
#define sConfigMgr
Definition: Config.h:61

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void Log::ReadLoggersFromConfig ( )
private
198 {
199  std::list<std::string> keys = sConfigMgr->GetKeysByString("Logger.");
200 
201  while (!keys.empty())
202  {
203  CreateLoggerFromConfig(keys.front());
204  keys.pop_front();
205  }
206 
207  // Bad config configuration, creating default config
208  if (loggers.find(LOGGER_ROOT) == loggers.end())
209  {
210  fprintf(stderr, "Wrong Loggers configuration. Review your Logger config section.\n"
211  "Creating default loggers [root (Error), server (Info)] to console\n");
212 
213  Close(); // Clean any Logger or Appender created
214 
216  appenders[appender->getId()] = appender;
217 
218  Logger& rootLogger = loggers[LOGGER_ROOT];
219  rootLogger.Create(LOGGER_ROOT, LOG_LEVEL_ERROR);
220  rootLogger.addAppender(appender->getId(), appender);
221 
222  Logger& serverLogger = loggers["server"];
223  serverLogger.Create("server", LOG_LEVEL_INFO);
224  serverLogger.addAppender(appender->getId(), appender);
225  }
226 }
Definition: Logger.h:23
void CreateLoggerFromConfig(std::string const &name)
Definition: Log.cpp:123
LoggerMap loggers
Definition: Log.h:108
Definition: Appender.h:35
Definition: Appender.h:36
void addAppender(uint8 type, Appender *)
Definition: Logger.cpp:38
uint8 NextAppenderId()
Definition: Log.cpp:44
#define sConfigMgr
Definition: Config.h:61
FMT_API int fprintf(std::FILE *f, CStringRef format, ArgList args)
void Create(std::string const &name, LogLevel level)
Definition: Logger.cpp:22
std::vector< char const * > ExtraAppenderArgs
Definition: Appender.h:116
Definition: Appender.h:38
void Close()
Definition: Log.cpp:315
uint8 getId() const
Definition: Appender.cpp:45
#define LOGGER_ROOT
Definition: Log.h:35
AppenderMap appenders
Definition: Log.h:107
Definition: Appender.h:54
Definition: AppenderConsole.h:45

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

template<class AppenderImpl >
void Log::RegisterAppender ( )
inline
84  {
85  using Index = typename AppenderImpl::TypeIndex;
86  auto itr = appenderFactory.find(Index::value);
87  ASSERT(itr == appenderFactory.end());
88  appenderFactory[Index::value] = &CreateAppender<AppenderImpl>;
89  }
AppenderCreatorMap appenderFactory
Definition: Log.h:106
#define ASSERT
Definition: Errors.h:55
const FieldDescriptor value
Definition: descriptor.h:1522
bool Log::SetLogLevel ( std::string const name,
char const level,
bool  isLogger = true 
)
260 {
261  LogLevel newLevel = LogLevel(atoi(newLevelc));
262  if (newLevel < 0)
263  return false;
264 
265  if (isLogger)
266  {
267  LoggerMap::iterator it = loggers.begin();
268  while (it != loggers.end() && it->second.getName() != name)
269  ++it;
270 
271  if (it == loggers.end())
272  return false;
273 
274  it->second.setLogLevel(newLevel);
275 
276  if (newLevel != LOG_LEVEL_DISABLED && newLevel < lowestLogLevel)
277  lowestLogLevel = newLevel;
278  }
279  else
280  {
281  Appender* appender = GetAppenderByName(name);
282  if (!appender)
283  return false;
284 
285  appender->setLogLevel(newLevel);
286  }
287 
288  return true;
289 }
LoggerMap loggers
Definition: Log.h:108
LogLevel lowestLogLevel
Definition: Log.h:110
Appender * GetAppenderByName(std::string const &name)
Definition: Log.cpp:61
Definition: Appender.h:33
void setLogLevel(LogLevel)
Definition: Appender.cpp:65
LogLevel
Definition: Appender.h:31
Definition: Appender.h:88

+ Here is the call graph for this function:

void Log::SetRealmId ( uint32  id)
310 {
311  for (AppenderMap::iterator it = appenders.begin(); it != appenders.end(); ++it)
312  it->second->setRealmId(id);
313 }
AppenderMap appenders
Definition: Log.h:107
void Log::SetSynchronous ( )
342 {
343  delete _strand;
344  _strand = nullptr;
345  _ioService = nullptr;
346 }
boost::asio::strand * _strand
Definition: Log.h:116
boost::asio::io_service * _ioService
Definition: Log.h:115
bool Log::ShouldLog ( std::string const type,
LogLevel  level 
) const
inline
137 {
138  // TODO: Use cache to store "Type.sub1.sub2": "Type" equivalence, should
139  // Speed up in cases where requesting "Type.sub1.sub2" but only configured
140  // Logger "Type"
141 
142  // Don't even look for a logger if the LogLevel is lower than lowest log levels across all loggers
143  if (level < lowestLogLevel)
144  return false;
145 
146  Logger const* logger = GetLoggerByType(type);
147  if (!logger)
148  return false;
149 
150  LogLevel logLevel = logger->getLogLevel();
151  return logLevel != LOG_LEVEL_DISABLED && logLevel <= level;
152 }
Definition: Logger.h:23
LogLevel lowestLogLevel
Definition: Log.h:110
Definition: Appender.h:33
LogLevel
Definition: Appender.h:31
LogLevel getLogLevel() const
Definition: Logger.cpp:33
Logger const * GetLoggerByType(std::string const &type) const
Definition: Log.h:119

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void Log::write ( std::unique_ptr< LogMessage > &&  msg) const
private
229 {
230  Logger const* logger = GetLoggerByType(msg->type);
231 
232  if (_ioService)
233  {
234  auto logOperation = std::shared_ptr<LogOperation>(new LogOperation(logger, std::move(msg)));
235 
236  _ioService->post(_strand->wrap([logOperation](){ logOperation->call(); }));
237  }
238  else
239  logger->write(msg.get());
240 }
Definition: Logger.h:23
boost::asio::strand * _strand
Definition: Log.h:116
std::string const type
Definition: Appender.h:75
void write(LogMessage *message) const
Definition: Logger.cpp:53
boost::asio::io_service * _ioService
Definition: Log.h:115
Definition: LogOperation.h:27
Logger const * GetLoggerByType(std::string const &type) const
Definition: Log.h:119

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Member Data Documentation

boost::asio::io_service* Log::_ioService
private
boost::asio::strand* Log::_strand
private
AppenderCreatorMap Log::appenderFactory
private
uint8 Log::AppenderId
private
AppenderMap Log::appenders
private
LoggerMap Log::loggers
private
LogLevel Log::lowestLogLevel
private
std::string Log::m_logsDir
private
std::string Log::m_logsTimestamp
private

The documentation for this class was generated from the following files: