TrinityCore
Log.h
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#ifndef TRINITYCORE_LOG_H
19#define TRINITYCORE_LOG_H
20
21#include "Define.h"
22#include "AsioHacksFwd.h"
23#include "LogCommon.h"
24#include "StringFormat.h"
25#include <memory>
26#include <unordered_map>
27#include <vector>
28
29class Appender;
30class Logger;
31struct LogMessage;
32
33namespace Trinity
34{
35 namespace Asio
36 {
37 class IoContext;
38 }
39}
40
41#define LOGGER_ROOT "root"
42
43typedef Appender*(*AppenderCreatorFn)(uint8 id, std::string const& name, LogLevel level, AppenderFlags flags, std::vector<std::string_view> const& extraArgs);
44
45template <class AppenderImpl>
46Appender* CreateAppender(uint8 id, std::string const& name, LogLevel level, AppenderFlags flags, std::vector<std::string_view> const& extraArgs)
47{
48 return new AppenderImpl(id, name, level, flags, extraArgs);
49}
50
52{
53 private:
54 Log();
55 ~Log();
56 Log(Log const&) = delete;
57 Log(Log&&) = delete;
58 Log& operator=(Log const&) = delete;
59 Log& operator=(Log&&) = delete;
60
61 public:
62 static Log* instance();
63
64 void Initialize(Trinity::Asio::IoContext* ioContext);
65 void SetSynchronous(); // Not threadsafe - should only be called from main() after all threads are joined
66 void LoadFromConfig();
67 void Close();
68 bool ShouldLog(std::string_view type, LogLevel level) const;
69 bool SetLogLevel(std::string const& name, int32 level, bool isLogger = true);
70
71 template<typename... Args>
72 void OutMessage(std::string_view filter, LogLevel const level, Trinity::FormatString<Args...> fmt, Args&&... args)
73 {
74 OutMessageImpl(filter, level, fmt, Trinity::MakeFormatArgs(args...));
75 }
76
77 template<typename... Args>
78 void OutCommand(uint32 account, Trinity::FormatString<Args...> fmt, Args&&... args)
79 {
80 if (!ShouldLog("commands.gm", LOG_LEVEL_INFO))
81 return;
82
83 OutCommandImpl(account, fmt, Trinity::MakeFormatArgs(args...));
84 }
85
86 void OutCharDump(char const* str, uint32 account_id, uint64 guid, char const* name);
87
88 void SetRealmId(uint32 id);
89
90 template<class AppenderImpl>
92 {
93 RegisterAppender(AppenderImpl::type, &CreateAppender<AppenderImpl>);
94 }
95
96 std::string const& GetLogsDir() const { return m_logsDir; }
97 std::string const& GetLogsTimestamp() const { return m_logsTimestamp; }
98
99 void CreateAppenderFromConfigLine(std::string const& name, std::string const& options);
100 void CreateLoggerFromConfigLine(std::string const& name, std::string const& options);
101
102 private:
103 static std::string GetTimestampStr();
104 void write(std::unique_ptr<LogMessage> msg) const;
105
106 Logger const* GetLoggerByType(std::string_view type) const;
107 Appender* GetAppenderByName(std::string_view name);
108 uint8 NextAppenderId();
109 void CreateAppenderFromConfig(std::string const& name);
110 void CreateLoggerFromConfig(std::string const& name);
111 void ReadAppendersFromConfig();
112 void ReadLoggersFromConfig();
113 void RegisterAppender(uint8 index, AppenderCreatorFn appenderCreateFn);
114 void OutMessageImpl(std::string_view filter, LogLevel level, Trinity::FormatStringView messageFormat, Trinity::FormatArgs messageFormatArgs);
115 void OutCommandImpl(uint32 account, Trinity::FormatStringView messageFormat, Trinity::FormatArgs messageFormatArgs);
116
117 std::unordered_map<uint8, AppenderCreatorFn> appenderFactory;
118 std::unordered_map<uint8, std::unique_ptr<Appender>> appenders;
119 std::unordered_map<std::string_view, std::unique_ptr<Logger>> loggers;
122
123 std::string m_logsDir;
124 std::string m_logsTimestamp;
125
128};
129
130#define sLog Log::instance()
131
132#ifdef PERFORMANCE_PROFILING
133#define TC_LOG_MESSAGE_BODY(filterType__, level__, ...) ((void)0)
134#elif TRINITY_PLATFORM != TRINITY_PLATFORM_WINDOWS
135
136// This will catch format errors on build time
137#define TC_LOG_MESSAGE_BODY(filterType__, level__, ...) \
138 do { \
139 if (Log* logInstance = sLog; logInstance->ShouldLog(filterType__, level__)) \
140 logInstance->OutMessage(filterType__, level__, __VA_ARGS__); \
141 } while (0)
142#else
143#define TC_LOG_MESSAGE_BODY(filterType__, level__, ...) \
144 __pragma(warning(push)) \
145 __pragma(warning(disable:4127)) \
146 do { \
147 if (Log* logInstance = sLog; logInstance->ShouldLog(filterType__, level__)) \
148 logInstance->OutMessage(filterType__, level__, __VA_ARGS__); \
149 } while (0) \
150 __pragma(warning(pop))
151#endif
152
153#define TC_LOG_TRACE(filterType__, ...) \
154 TC_LOG_MESSAGE_BODY(filterType__, LOG_LEVEL_TRACE, __VA_ARGS__)
155
156#define TC_LOG_DEBUG(filterType__, ...) \
157 TC_LOG_MESSAGE_BODY(filterType__, LOG_LEVEL_DEBUG, __VA_ARGS__)
158
159#define TC_LOG_INFO(filterType__, ...) \
160 TC_LOG_MESSAGE_BODY(filterType__, LOG_LEVEL_INFO, __VA_ARGS__)
161
162#define TC_LOG_WARN(filterType__, ...) \
163 TC_LOG_MESSAGE_BODY(filterType__, LOG_LEVEL_WARN, __VA_ARGS__)
164
165#define TC_LOG_ERROR(filterType__, ...) \
166 TC_LOG_MESSAGE_BODY(filterType__, LOG_LEVEL_ERROR, __VA_ARGS__)
167
168#define TC_LOG_FATAL(filterType__, ...) \
169 TC_LOG_MESSAGE_BODY(filterType__, LOG_LEVEL_FATAL, __VA_ARGS__)
170
171#endif
uint8_t uint8
Definition: Define.h:144
#define TC_COMMON_API
Definition: Define.h:99
int32_t int32
Definition: Define.h:138
uint64_t uint64
Definition: Define.h:141
uint32_t uint32
Definition: Define.h:142
uint16 flags
Definition: DisableMgr.cpp:49
AppenderFlags
Definition: LogCommon.h:50
LogLevel
Definition: LogCommon.h:25
@ LOG_LEVEL_INFO
Definition: LogCommon.h:29
Appender *(* AppenderCreatorFn)(uint8 id, std::string const &name, LogLevel level, AppenderFlags flags, std::vector< std::string_view > const &extraArgs)
Definition: Log.h:43
Appender * CreateAppender(uint8 id, std::string const &name, LogLevel level, AppenderFlags flags, std::vector< std::string_view > const &extraArgs)
Definition: Log.h:46
Definition: Log.h:52
std::unordered_map< std::string_view, std::unique_ptr< Logger > > loggers
Definition: Log.h:119
Trinity::Asio::Strand * _strand
Definition: Log.h:127
std::string const & GetLogsDir() const
Definition: Log.h:96
void OutCommand(uint32 account, Trinity::FormatString< Args... > fmt, Args &&... args)
Definition: Log.h:78
std::unordered_map< uint8, std::unique_ptr< Appender > > appenders
Definition: Log.h:118
std::string m_logsTimestamp
Definition: Log.h:124
Log(Log &&)=delete
Trinity::Asio::IoContext * _ioContext
Definition: Log.h:126
uint8 AppenderId
Definition: Log.h:120
Log & operator=(Log const &)=delete
Log & operator=(Log &&)=delete
void OutMessage(std::string_view filter, LogLevel const level, Trinity::FormatString< Args... > fmt, Args &&... args)
Definition: Log.h:72
void RegisterAppender()
Definition: Log.h:91
std::string m_logsDir
Definition: Log.h:123
Log(Log const &)=delete
std::string const & GetLogsTimestamp() const
Definition: Log.h:97
std::unordered_map< uint8, AppenderCreatorFn > appenderFactory
Definition: Log.h:117
LogLevel lowestLogLevel
Definition: Log.h:121
Definition: Logger.h:30
fmt::format_args FormatArgs
Definition: StringFormat.h:31
fmt::format_string< Args... > FormatString
Definition: StringFormat.h:27
constexpr auto MakeFormatArgs(Args &&... args)
Definition: StringFormat.h:34
fmt::string_view FormatStringView
Definition: StringFormat.h:29