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
26#include <memory>
27#include <unordered_map>
28#include <vector>
29
30class Appender;
31class Logger;
32struct LogMessage;
33
34namespace Trinity
35{
36 namespace Asio
37 {
38 class IoContext;
39 }
40}
41
42#define LOGGER_ROOT "root"
43
44typedef Appender*(*AppenderCreatorFn)(uint8 id, std::string const& name, LogLevel level, AppenderFlags flags, std::vector<std::string_view> const& extraArgs);
45
46template <class AppenderImpl>
47Appender* CreateAppender(uint8 id, std::string const& name, LogLevel level, AppenderFlags flags, std::vector<std::string_view> const& extraArgs)
48{
49 return new AppenderImpl(id, name, level, flags, extraArgs);
50}
51
53{
54 typedef std::unordered_map<std::string, Logger> LoggerMap;
55
56 private:
57 Log();
58 ~Log();
59 Log(Log const&) = delete;
60 Log(Log&&) = delete;
61 Log& operator=(Log const&) = delete;
62 Log& operator=(Log&&) = delete;
63
64 public:
65 static Log* instance();
66
67 void Initialize(Trinity::Asio::IoContext* ioContext);
68 void SetSynchronous(); // Not threadsafe - should only be called from main() after all threads are joined
69 void LoadFromConfig();
70 void Close();
71 bool ShouldLog(std::string const& type, LogLevel level) const;
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 const level, Trinity::FormatString<Args...> fmt, Args&&... args)
76 {
77 this->OutMessageImpl(filter, level, fmt, Trinity::MakeFormatArgs(args...));
78 }
79
80 template<typename... Args>
81 void OutCommand(uint32 account, Trinity::FormatString<Args...> fmt, Args&&... args)
82 {
83 if (!ShouldLog("commands.gm", LOG_LEVEL_INFO))
84 return;
85
86 this->OutCommandImpl(account, fmt, Trinity::MakeFormatArgs(args...));
87 }
88
89 void OutCharDump(char const* str, uint32 account_id, uint64 guid, char const* name);
90
91 void SetRealmId(uint32 id);
92
93 template<class AppenderImpl>
95 {
96 this->RegisterAppender(AppenderImpl::type, &CreateAppender<AppenderImpl>);
97 }
98
99 std::string const& GetLogsDir() const { return m_logsDir; }
100 std::string const& GetLogsTimestamp() const { return m_logsTimestamp; }
101
102 private:
103 static std::string GetTimestampStr();
104 void write(std::unique_ptr<LogMessage> msg) const;
105
106 Logger const* GetLoggerByType(std::string const& 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, 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 (sLog->ShouldLog(filterType__, level__)) \
140 sLog->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 (sLog->ShouldLog(filterType__, level__)) \
148 sLog->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:135
#define TC_COMMON_API
Definition Define.h:96
int32_t int32
Definition Define.h:129
uint64_t uint64
Definition Define.h:132
uint32_t uint32
Definition Define.h:133
uint16 flags
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:44
Appender * CreateAppender(uint8 id, std::string const &name, LogLevel level, AppenderFlags flags, std::vector< std::string_view > const &extraArgs)
Definition Log.h:47
Definition Log.h:53
Trinity::Asio::Strand * _strand
Definition Log.h:127
std::string const & GetLogsDir() const
Definition Log.h:99
void OutCommand(uint32 account, Trinity::FormatString< Args... > fmt, Args &&... args)
Definition Log.h:81
std::unordered_map< uint8, std::unique_ptr< Appender > > appenders
Definition Log.h:118
std::string m_logsTimestamp
Definition Log.h:124
std::unordered_map< std::string, Logger > LoggerMap
Definition Log.h:54
Log(Log &&)=delete
Trinity::Asio::IoContext * _ioContext
Definition Log.h:126
uint8 AppenderId
Definition Log.h:120
std::unordered_map< std::string, std::unique_ptr< Logger > > loggers
Definition Log.h:119
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:75
void RegisterAppender()
Definition Log.h:94
std::string m_logsDir
Definition Log.h:123
Log(Log const &)=delete
std::string const & GetLogsTimestamp() const
Definition Log.h:100
std::unordered_map< uint8, AppenderCreatorFn > appenderFactory
Definition Log.h:117
LogLevel lowestLogLevel
Definition Log.h:121
fmt::format_args FormatArgs
fmt::format_string< Args... > FormatString
constexpr auto MakeFormatArgs(Args &&... args)
fmt::string_view FormatStringView