libfilezilla
logger.hpp
Go to the documentation of this file.
1 #ifndef LIBFILEZILLA_LOGGER_HEADER
2 #define LIBFILEZILLA_LOGGER_HEADER
3 
8 #include "format.hpp"
9 
10 #include <atomic>
11 
12 namespace fz {
13 namespace logmsg
14 {
15  enum type : uint64_t
16  {
18  status = 1ull,
19 
21  error = 1ull << 1,
22 
24  command = 1ull << 2,
25 
27  reply = 1ull << 3,
28 
30  debug_warning = 1ull << 4,
31  debug_info = 1ull << 5,
32  debug_verbose = 1ull << 6,
33  debug_debug = 1ull << 7,
34 
37  custom1 = 1ull << 32,
38  custom32 = 1ull << 63
39  };
40 }
41 
50 class FZ_PUBLIC_SYMBOL logger_interface
51 {
52 public:
53  logger_interface() noexcept = default;
54  virtual ~logger_interface() = default;
55 
56  logger_interface(logger_interface const&) = delete;
57  logger_interface& operator=(logger_interface const&) = delete;
58 
59 
61  virtual void do_log(logmsg::type t, std::wstring && msg) = 0;
62 
68  template<typename String, typename...Args>
69  void log(logmsg::type t, String&& fmt, Args&& ...args)
70  {
71  if (should_log(t)) {
72  std::wstring formatted = fz::sprintf(fz::to_wstring(std::forward<String>(fmt)), args...);
73  do_log(t, std::move(formatted));
74  }
75  }
76 
82  template<typename String, typename...Args>
83  void log_u(logmsg::type t, String&& fmt, Args const& ...args)
84  {
85  if (should_log(t)) {
86  std::wstring formatted = fz::sprintf(fz::to_wstring(std::forward<String>(fmt)), assume_strings_are_utf8(args)...);
87  do_log(t, std::move(formatted));
88  }
89  }
90 
92  template<typename String>
93  void log_raw(logmsg::type t, String&& msg)
94  {
95  if (should_log(t)) {
96  std::wstring formatted = fz::to_wstring(std::forward<String>(msg));
97  do_log(t, std::move(formatted));
98  }
99  }
100 
101  template<typename String>
102  void log_u_raw(logmsg::type t, String&& msg)
103  {
104  if (should_log(t)) {
105  std::wstring formatted = fz::to_wstring_from_utf8(std::forward<String>(msg));
106  do_log(t, std::move(formatted));
107  }
108  }
109 
111  bool should_log(logmsg::type t) const {
112  return level_ & t;
113  }
114 
117  return static_cast<logmsg::type>(level_.load());
118  }
119 
121  virtual void set_all(logmsg::type t) {
122  level_ = t;
123  }
124 
126  void set(logmsg::type t, bool flag) {
127  if (flag) {
128  enable(t);
129  }
130  else {
131  disable(t);
132  }
133  }
134 
136  virtual void enable(logmsg::type t) {
137  level_ |= t;
138  }
139 
141  virtual void disable(logmsg::type t) {
142  level_ &= ~t;
143  }
144 
145 protected:
146  std::atomic<uint64_t> level_{logmsg::status | logmsg::error | logmsg::command | logmsg::reply};
147 
148 private:
149  std::wstring assume_strings_are_utf8(std::string_view const& arg) {
150  return fz::to_wstring_from_utf8(arg);
151  }
152  std::wstring assume_strings_are_utf8(std::string const& arg) {
153  return fz::to_wstring_from_utf8(arg);
154  }
155  std::wstring assume_strings_are_utf8(char const* arg) {
156  return fz::to_wstring_from_utf8(arg);
157  }
158 
159  template <typename T>
160  T const& assume_strings_are_utf8(T const& arg) {
161  return arg;
162  }
163 };
164 
166 class FZ_PUBLIC_SYMBOL null_logger final : public logger_interface
167 {
168 public:
169  null_logger() noexcept
170  {
171  disable(levels());
172  }
173 
174  virtual void do_log(logmsg::type, std::wstring &&) override {}
175  virtual void set_all(logmsg::type) override {}
176  virtual void enable(logmsg::type) override {}
177 };
178 
179 null_logger FZ_PUBLIC_SYMBOL & get_null_logger();
180 
182 class FZ_PUBLIC_SYMBOL stdout_logger final : public logger_interface
183 {
184 public:
185  virtual void do_log(logmsg::type, std::wstring &&) override;
186 };
187 
188 
189 }
190 
191 #endif
Abstract interface for logging strings.
Definition: logger.hpp:51
void log(logmsg::type t, String &&fmt, Args &&...args)
Definition: logger.hpp:69
void log_raw(logmsg::type t, String &&msg)
Logs the raw string, it is not treated as format string.
Definition: logger.hpp:93
void set(logmsg::type t, bool flag)
Sets whether the given types should be logged.
Definition: logger.hpp:126
virtual void do_log(logmsg::type t, std::wstring &&msg)=0
The one thing you need to override.
virtual void disable(logmsg::type t)
Disables logging for the passed message types.
Definition: logger.hpp:141
virtual void enable(logmsg::type t)
Enables logging for the passed message types.
Definition: logger.hpp:136
logmsg::type levels() const
Returns all currently enabled log levels.
Definition: logger.hpp:116
void log_u(logmsg::type t, String &&fmt, Args const &...args)
Definition: logger.hpp:83
bool should_log(logmsg::type t) const
Is any of the passed log levels set.
Definition: logger.hpp:111
virtual void set_all(logmsg::type t)
Sets which message types should be logged.
Definition: logger.hpp:121
A logger that does not log anything.
Definition: logger.hpp:167
virtual void do_log(logmsg::type, std::wstring &&) override
The one thing you need to override.
Definition: logger.hpp:174
virtual void set_all(logmsg::type) override
Sets which message types should be logged.
Definition: logger.hpp:175
virtual void enable(logmsg::type) override
Enables logging for the passed message types.
Definition: logger.hpp:176
A simple logger that writes to stdout.
Definition: logger.hpp:183
virtual void do_log(logmsg::type, std::wstring &&) override
The one thing you need to override.
Header for the sprintf string formatting function.
type
Definition: logger.hpp:16
@ debug_warning
Debug messages aimed at developers.
Definition: logger.hpp:30
@ command
Commands, aimed at the users.
Definition: logger.hpp:24
@ reply
Replies, aimed at the users.
Definition: logger.hpp:27
@ status
Generic status messages aimed at the user.
Definition: logger.hpp:18
@ custom1
Definition: logger.hpp:37
@ error
Error messages aimed at the user.
Definition: logger.hpp:21
The namespace used by libfilezilla.
Definition: apply.hpp:17
std::wstring to_wstring_from_utf8(std::string_view const &in)
Converts from std::string in UTF-8 into std::wstring.
std::wstring to_wstring(std::string_view const &in)
Converts from std::string in system encoding into std::wstring.
std::string sprintf(std::string_view const &fmt, Args &&... args)
A simple type-safe sprintf replacement.
Definition: format.hpp:456