neoGFX
Cross-platform C++ app/game engine
Loading...
Searching...
No Matches
i_logger.hpp
Go to the documentation of this file.
1// i_logger.hpp
2/*
3 * Copyright (c) 2020 Leigh Johnston.
4 *
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are
9 * met:
10 *
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 *
14 * * Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 *
18 * * Neither the name of Leigh Johnston nor the names of any
19 * other contributors to this software may be used to endorse or
20 * promote products derived from this software without specific prior
21 * written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
24 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
25 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
26 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
27 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
29 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 */
35
36#pragma once
37
38#include <neolib/neolib.hpp>
39#include <functional>
40#include <sstream>
42#include <neolib/task/event.hpp>
44
45namespace neolib
46{
47 namespace logger
48 {
49 enum class severity : uint32_t
50 {
51 Trace = 0,
52 Debug = 1,
53 Info = 2,
54 Warning = 3,
55 Error = 4,
56 Fatal = 5
57 };
58
59 enum class category_id : int32_t {};
60
61 struct category
62 {
64 template <typename IdType>
65 category(IdType aId) :
66 id{ static_cast<category_id>(aId) }
67 {
68 }
69 };
70
71 typedef uint64_t line_id_t;
73
74 struct endl_t {};
75 struct flush_t {};
76
77 const endl_t endl;
79
81 {
82 protected:
83 typedef std::ostringstream buffer_t;
84 private:
85 typedef std::map<std::thread::id, buffer_t> buffer_list_t;
86 public:
88 {
89 static client_logger_buffers sIntance;
90 return sIntance;
91 }
92 public:
94 {
95 std::lock_guard<std::recursive_mutex> lg{ mutex() };
96 thread_local struct cleanup
97 {
99 ~cleanup()
100 {
101 std::lock_guard<std::recursive_mutex> lg{ parent.mutex() };
102 parent.buffers().erase(std::this_thread::get_id());
103 }
104 } cleanup{ *this };
105 return iBuffers[std::this_thread::get_id()];
106 }
107 buffer_list_t& buffers()
108 {
109 return iBuffers;
110 }
111 private:
112 std::recursive_mutex& mutex() const
113 {
114 return iMutex;
115 }
116 private:
117 mutable std::recursive_mutex iMutex;
118 buffer_list_t iBuffers;
119 };
121 class i_logger;
122
124 {
125 public:
126 virtual ~i_formatter() = default;
127 public:
128 virtual void format(i_logger const& aLogger, i_string const& aUnformattedMessage, i_string& aFormattedMessage) = 0;
129 };
130
131 class i_logger : public i_service
132 {
133 template <std::size_t Instance>
134 friend class logger;
135 public:
136 declare_event(new_log_message, i_string const&)
137 public:
138 struct logging_thread_already_created : std::logic_error { logging_thread_already_created() : std::logic_error{ "neolib::logger::i_logger::logging_thread_already_created" } {} };
139 struct no_formatter : std::logic_error { no_formatter() : std::logic_error{ "neolib::logger::i_logger::no_formatter" } {} };
140 public:
141 virtual ~i_logger() = default;
142 public:
143 virtual void copy_to(i_logger& aLogger) = 0;
144 virtual void cancel_copy_to(i_logger& aLogger) = 0;
145 virtual bool has_logging_thread() const = 0;
146 virtual void create_logging_thread() = 0;
147 public:
148 virtual severity filter_severity() const = 0;
149 virtual void set_filter_severity(severity aSeverity) = 0;
150 virtual void register_category(category_id aId, i_string const& aName) = 0;
151 virtual bool category_enabled(category_id aId) const = 0;
152 virtual void enable_category(category_id aId) = 0;
153 virtual void disable_category(category_id aId) = 0;
154 public:
155 virtual bool has_formatter() const = 0;
156 virtual i_formatter& formatter() const = 0;
157 virtual void set_formatter(i_formatter& aFormatter) = 0;
158 virtual void clear_formatter() = 0;
159 public:
160 virtual line_id_t line_id() const = 0;
161 virtual void reset_line_id(line_id_t aLineId = DefaultInitialLineId) = 0;
162 public:
163 virtual i_logger& operator<<(severity aSeverity) = 0;
164 virtual i_logger& operator<<(category_id aCategory) = 0;
165 public:
166 template <typename IdType>
167 void register_category(IdType aId, std::string const& aName = {})
168 {
169 register_category(static_cast<category_id>(aId), string{ aName });
170 }
171 template <typename IdType>
172 void category_enabled(IdType aId)
173 {
174 category_enabled(static_cast<category_id>(aId));
175 }
176 template <typename IdType>
177 void enable_category(IdType aId)
178 {
179 enable_category(static_cast<category_id>(aId));
180 }
181 template <typename IdType>
182 void disable_category(IdType aId)
183 {
184 disable_category(static_cast<category_id>(aId));
185 }
186 public:
188 {
189 return (*this) << aCategory.id;
190 }
192 {
193 auto& buffer = client_logger_buffers::instance().buffer();
194 buffer << std::endl;
195 flush(string{ buffer.str() });
196 buffer.str({});
197 return *this;
198 }
200 {
201 auto& buffer = client_logger_buffers::instance().buffer();
202 buffer << std::flush;
203 flush(string{ buffer.str() });
204 buffer.str({});
205 return *this;
206 }
207 template<typename T>
208 i_logger& operator<<(T const& aValue)
209 {
211 return *this;
212 }
213 public:
214 virtual void commit() = 0;
215 virtual void wait() const = 0;
216 protected:
217 virtual void flush(i_string const& aMessage) = 0;
218 };
219
220 class formatter : public i_formatter
221 {
222 public:
223 typedef std::function<void(i_logger const&, i_string const&, i_string&)> function_type;
224 public:
225 formatter(function_type aFormattingFunction) :
226 iFormattingFunction{ aFormattingFunction }
227 {
228 }
229 public:
230 void format(i_logger const& aLogger, i_string const& aUnformattedMessage, i_string& aFormattedMessage) override
231 {
232 iFormattingFunction(aLogger, aUnformattedMessage, aFormattedMessage);
233 }
234 private:
235 function_type iFormattingFunction;
236 };
237 }
238}
static client_logger_buffers & instance()
Definition i_logger.hpp:87
std::function< void(i_logger const &, i_string const &, i_string &)> function_type
Definition i_logger.hpp:223
formatter(function_type aFormattingFunction)
Definition i_logger.hpp:225
void format(i_logger const &aLogger, i_string const &aUnformattedMessage, i_string &aFormattedMessage) override
Definition i_logger.hpp:230
virtual ~i_formatter()=default
virtual void format(i_logger const &aLogger, i_string const &aUnformattedMessage, i_string &aFormattedMessage)=0
virtual void clear_formatter()=0
i_logger & operator<<(endl_t)
Definition i_logger.hpp:191
virtual void reset_line_id(line_id_t aLineId=DefaultInitialLineId)=0
virtual void cancel_copy_to(i_logger &aLogger)=0
virtual bool category_enabled(category_id aId) const =0
void enable_category(IdType aId)
Definition i_logger.hpp:177
i_logger & operator<<(category aCategory)
Definition i_logger.hpp:187
virtual severity filter_severity() const =0
virtual void create_logging_thread()=0
i_logger & operator<<(T const &aValue)
Definition i_logger.hpp:208
void disable_category(IdType aId)
Definition i_logger.hpp:182
virtual void set_filter_severity(severity aSeverity)=0
virtual void enable_category(category_id aId)=0
virtual void commit()=0
virtual bool has_formatter() const =0
virtual void copy_to(i_logger &aLogger)=0
virtual i_logger & operator<<(severity aSeverity)=0
virtual void register_category(category_id aId, i_string const &aName)=0
virtual void flush(i_string const &aMessage)=0
virtual void wait() const =0
virtual i_formatter & formatter() const =0
virtual void set_formatter(i_formatter &aFormatter)=0
void register_category(IdType aId, std::string const &aName={})
Definition i_logger.hpp:167
virtual line_id_t line_id() const =0
void category_enabled(IdType aId)
Definition i_logger.hpp:172
virtual void disable_category(category_id aId)=0
virtual i_logger & operator<<(category_id aCategory)=0
virtual bool has_logging_thread() const =0
virtual ~i_logger()=default
i_logger & operator<<(flush_t)
Definition i_logger.hpp:199
const flush_t flush
Definition i_logger.hpp:78
const endl_t endl
Definition i_logger.hpp:77
constexpr line_id_t DefaultInitialLineId
Definition i_logger.hpp:72
uint64_t line_id_t
Definition i_logger.hpp:71
Definition plf_hive.h:79
#define declare_event(declName,...)
Definition i_event.hpp:305