TrinityCore
Loading...
Searching...
No Matches
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 name, LogLevel level, AppenderFlags flags, std::vector<std::string_view> const& extraArgs);
44
45template <class AppenderImpl>
46Appender* CreateAppender(uint8 id, std::string name, LogLevel level, AppenderFlags flags, std::vector<std::string_view> const& extraArgs)
47{
48 return new AppenderImpl(id, std::move(name), level, flags, extraArgs);
49}
50
52{
53 private:
54 Log();
55 ~Log();
56
57 public:
58 Log(Log const&) = delete;
59 Log(Log&&) = delete;
60 Log& operator=(Log const&) = delete;
61 Log& operator=(Log&&) = delete;
62
63 static Log* instance() noexcept;
64
65 void Initialize(Trinity::Asio::IoContext* ioContext);
66 void SetAsynchronous(Trinity::Asio::IoContext* ioContext);
67 void SetSynchronous(); // Not threadsafe - should only be called from main() after all threads are joined
68 void LoadFromConfig();
69 void Close();
70 bool ShouldLog(std::string_view type, LogLevel level) const noexcept;
71 Logger const* GetEnabledLogger(std::string_view type, LogLevel level) const noexcept;
72 bool SetLogLevel(std::string const& name, int32 level, bool isLogger = true);
73
74 template<typename... Args>
75 void OutMessage(std::string_view filter, LogLevel level, Trinity::FormatString<Args...> fmt, Args&&... args) noexcept
76 {
77 this->OutMessageImpl(GetLoggerByType(filter), filter, level, fmt, Trinity::MakeFormatArgs(args...));
78 }
79
80 template<typename... Args>
81 void OutMessageTo(Logger const* logger, std::string_view filter, LogLevel level, Trinity::FormatString<Args...> fmt, Args&&... args) noexcept
82 {
83 this->OutMessageImpl(logger, filter, level, fmt, Trinity::MakeFormatArgs(args...));
84 }
85
86 template<typename... Args>
87 void OutCommand(uint32 account, Trinity::FormatString<Args...> fmt, Args&&... args) noexcept
88 {
89 if (!ShouldLog("commands.gm", LOG_LEVEL_INFO))
90 return;
91
92 this->OutCommandImpl(account, fmt, Trinity::MakeFormatArgs(args...));
93 }
94
95 void OutCharDump(std::string const& str, uint32 account_id, uint64 guid, std::string const& name) const noexcept;
96
97 void SetRealmId(uint32 id);
98
99 template<class AppenderImpl>
101 {
102 this->RegisterAppender(AppenderImpl::type, &CreateAppender<AppenderImpl>);
103 }
104
105 std::string const& GetLogsDir() const { return m_logsDir; }
106 std::string const& GetLogsTimestamp() const { return m_logsTimestamp; }
107
108 void CreateAppenderFromConfigLine(std::string const& name, std::string const& options);
109 void CreateLoggerFromConfigLine(std::string const& name, std::string const& options);
110
111 template <typename StringOrStringView>
112 static constexpr std::string_view make_string_view(StringOrStringView const& stringOrStringView)
113 {
114 return stringOrStringView;
115 }
116
117 template <size_t CharArraySize>
118 static consteval std::string_view make_string_view(char const(&chars)[CharArraySize])
119 {
120 return { std::begin(chars), (chars[CharArraySize - 1] == '\0' ? CharArraySize - 1 : CharArraySize) };
121 }
122
123 template <size_t CharArraySize>
124 static consteval Trinity::FormatStringView make_format_string_view(char const(&chars)[CharArraySize])
125 {
126 return { std::begin(chars), (chars[CharArraySize - 1] == '\0' ? CharArraySize - 1 : CharArraySize) };
127 }
128
129 private:
130 static std::string GetTimestampStr();
131
132 Logger const* GetLoggerByType(std::string_view type) const;
133 Appender* GetAppenderByName(std::string_view name);
134 uint8 NextAppenderId();
135 void CreateAppenderFromConfig(std::string const& name);
136 void CreateLoggerFromConfig(std::string const& name);
137 void ReadAppendersFromConfig();
138 void ReadLoggersFromConfig();
139 void RegisterAppender(uint8 index, AppenderCreatorFn appenderCreateFn);
140 void OutMessageImpl(Logger const* logger, std::string_view filter, LogLevel level, Trinity::FormatStringView messageFormat, Trinity::FormatArgs messageFormatArgs) const noexcept;
141 void OutCommandImpl(uint32 account, Trinity::FormatStringView messageFormat, Trinity::FormatArgs messageFormatArgs) const noexcept;
142
143 std::unordered_map<uint8, AppenderCreatorFn> appenderFactory;
144 std::unordered_map<uint8, std::unique_ptr<Appender>> appenders;
145 std::unordered_map<std::string_view, std::unique_ptr<Logger>> loggers;
148
149 std::string m_logsDir;
150 std::string m_logsTimestamp;
151
154};
155
156#define sLog Log::instance()
157
158#define TC_LOG_MESSAGE_BODY_CORE(filterType__, level__, message__, ...) \
159 do { \
160 Log* logInstance = sLog; \
161 if (Logger const* loggerInstance = logInstance->GetEnabledLogger(Log::make_string_view((filterType__)), (level__))) \
162 logInstance->OutMessageTo(loggerInstance, Log::make_string_view((filterType__)), (level__), \
163 Log::make_format_string_view((message__)), ## __VA_ARGS__); \
164 } while (0)
165
166#ifdef PERFORMANCE_PROFILING
167#define TC_LOG_MESSAGE_BODY(filterType__, level__, message__, ...) ((void)0)
168#elif TRINITY_PLATFORM != TRINITY_PLATFORM_WINDOWS
169#define TC_LOG_MESSAGE_BODY(filterType__, level__, message__, ...) TC_LOG_MESSAGE_BODY_CORE(filterType__, level__, message__, ## __VA_ARGS__)
170#else
171#define TC_LOG_MESSAGE_BODY(filterType__, level__, message__, ...) \
172 __pragma(warning(push)) \
173 __pragma(warning(disable:4127)) \
174 TC_LOG_MESSAGE_BODY_CORE(filterType__, level__, message__, ## __VA_ARGS__) \
175 __pragma(warning(pop))
176#endif
177
178#define TC_LOG_TRACE(filterType__, message__, ...) \
179 TC_LOG_MESSAGE_BODY(filterType__, LOG_LEVEL_TRACE, message__, ## __VA_ARGS__)
180
181#define TC_LOG_DEBUG(filterType__, message__, ...) \
182 TC_LOG_MESSAGE_BODY(filterType__, LOG_LEVEL_DEBUG, message__, ## __VA_ARGS__)
183
184#define TC_LOG_INFO(filterType__, message__, ...) \
185 TC_LOG_MESSAGE_BODY(filterType__, LOG_LEVEL_INFO, message__, ## __VA_ARGS__)
186
187#define TC_LOG_WARN(filterType__, message__, ...) \
188 TC_LOG_MESSAGE_BODY(filterType__, LOG_LEVEL_WARN, message__, ## __VA_ARGS__)
189
190#define TC_LOG_ERROR(filterType__, message__, ...) \
191 TC_LOG_MESSAGE_BODY(filterType__, LOG_LEVEL_ERROR, message__, ## __VA_ARGS__)
192
193#define TC_LOG_FATAL(filterType__, message__, ...) \
194 TC_LOG_MESSAGE_BODY(filterType__, LOG_LEVEL_FATAL, message__, ## __VA_ARGS__)
195
196#endif
uint8_t uint8
Definition Define.h:156
#define TC_COMMON_API
Definition Define.h:99
int32_t int32
Definition Define.h:150
uint64_t uint64
Definition Define.h:153
uint32_t uint32
Definition Define.h:154
uint16 flags
AppenderFlags
Definition LogCommon.h:50
LogLevel
Definition LogCommon.h:25
@ LOG_LEVEL_INFO
Definition LogCommon.h:29
Appender * CreateAppender(uint8 id, std::string name, LogLevel level, AppenderFlags flags, std::vector< std::string_view > const &extraArgs)
Definition Log.h:46
Appender *(* AppenderCreatorFn)(uint8 id, std::string name, LogLevel level, AppenderFlags flags, std::vector< std::string_view > const &extraArgs)
Definition Log.h:43
Definition Log.h:52
std::unordered_map< std::string_view, std::unique_ptr< Logger > > loggers
Definition Log.h:145
Trinity::Asio::Strand * _strand
Definition Log.h:153
std::string const & GetLogsDir() const
Definition Log.h:105
void OutCommand(uint32 account, Trinity::FormatString< Args... > fmt, Args &&... args) noexcept
Definition Log.h:87
std::unordered_map< uint8, std::unique_ptr< Appender > > appenders
Definition Log.h:144
std::string m_logsTimestamp
Definition Log.h:150
Log(Log &&)=delete
Trinity::Asio::IoContext * _ioContext
Definition Log.h:152
static constexpr std::string_view make_string_view(StringOrStringView const &stringOrStringView)
Definition Log.h:112
uint8 AppenderId
Definition Log.h:146
Log & operator=(Log const &)=delete
Log & operator=(Log &&)=delete
static consteval std::string_view make_string_view(char const(&chars)[CharArraySize])
Definition Log.h:118
void RegisterAppender()
Definition Log.h:100
std::string m_logsDir
Definition Log.h:149
void OutMessageTo(Logger const *logger, std::string_view filter, LogLevel level, Trinity::FormatString< Args... > fmt, Args &&... args) noexcept
Definition Log.h:81
Log(Log const &)=delete
std::string const & GetLogsTimestamp() const
Definition Log.h:106
std::unordered_map< uint8, AppenderCreatorFn > appenderFactory
Definition Log.h:143
LogLevel lowestLogLevel
Definition Log.h:147
static consteval Trinity::FormatStringView make_format_string_view(char const(&chars)[CharArraySize])
Definition Log.h:124
fmt::format_args FormatArgs
fmt::format_string< Args... > FormatString
constexpr auto MakeFormatArgs(Args &&... args)
fmt::string_view FormatStringView
STL namespace.