HAL
log.h
Go to the documentation of this file.
1 // MIT License
2 //
3 // Copyright (c) 2019 Ruhr University Bochum, Chair for Embedded Security. All Rights reserved.
4 // Copyright (c) 2019 Marc Fyrbiak, Sebastian Wallat, Max Hoffmann ("ORIGINAL AUTHORS"). All rights reserved.
5 // Copyright (c) 2021 Max Planck Institute for Security and Privacy. All Rights reserved.
6 // Copyright (c) 2021 Jörn Langheinrich, Julian Speith, Nils Albartus, René Walendy, Simon Klix ("ORIGINAL AUTHORS"). All Rights reserved.
7 //
8 // Permission is hereby granted, free of charge, to any person obtaining a copy
9 // of this software and associated documentation files (the "Software"), to deal
10 // in the Software without restriction, including without limitation the rights
11 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 // copies of the Software, and to permit persons to whom the Software is
13 // furnished to do so, subject to the following conditions:
14 //
15 // The above copyright notice and this permission notice shall be included in all
16 // copies or substantial portions of the Software.
17 //
18 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 // SOFTWARE.
25 
26 #pragma once
27 
28 #include "hal_core/defines.h"
33 
34 #include <functional>
35 #include <map>
36 #include <memory>
37 #include <mutex>
38 #include <set>
39 #include <string>
40 #include <tuple>
41 
42 #define FMT_HEADER_ONLY
43 #pragma GCC diagnostic push
44 #pragma GCC diagnostic ignored "-Wshadow"
45 #include <spdlog/sinks/base_sink.h>
46 #include <spdlog/spdlog.h>
47 #pragma GCC diagnostic pop
48 
49 namespace hal
50 {
51 // macros to stringify to transform int to const char*
52 #define STRINGISTRINGIFY(x) #x
53 #define STRINGIFY(x) STRINGISTRINGIFY(x)
54 
55 // macro to get the log channel
56 #define LOG_CHANNEL(channel) LogManager::get_instance()->get_channel(channel)
57 
70 #define log_info(channel, ...) LOG_CHANNEL(channel)->info(__VA_ARGS__)
71 
72 #define log_trace(channel, ...) LOG_CHANNEL(channel)->trace("[" __FILE__ ":" STRINGIFY(__LINE__) "] " __VA_ARGS__)
73 
74 #define log_debug(channel, ...) LOG_CHANNEL(channel)->debug("[" __FILE__ ":" STRINGIFY(__LINE__) "] " __VA_ARGS__)
75 
76 #define log_warning(channel, ...) LOG_CHANNEL(channel)->warn("[" __FILE__ ":" STRINGIFY(__LINE__) "] " __VA_ARGS__)
77 
78 #define log_error(channel, ...) LOG_CHANNEL(channel)->error("[" __FILE__ ":" STRINGIFY(__LINE__) "] " __VA_ARGS__)
79 
80 #define log_critical(channel, ...) LOG_CHANNEL(channel)->critical("[" __FILE__ ":" STRINGIFY(__LINE__) "] " __VA_ARGS__)
82 
94 #define die(channel, ...) \
95  do \
96  { \
97  LOG_CHANNEL(channel)->critical("[" __FILE__ ":" STRINGIFY(__LINE__) "] " __VA_ARGS__); \
98  exit(1); \
99  } while (0);
100 
105  {
106  public:
107  struct log_sink
108  {
109  std::shared_ptr<spdlog::sinks::sink> spdlog_sink;
110  std::string sink_type;
112  bool truncate;
113  std::filesystem::path path;
114  };
115 
124  static LogManager* get_instance(const std::filesystem::path& file_name = "");
125 
132  void set_file_name(const std::filesystem::path& file_name);
133 
140  void set_format_pattern(const std::string& format);
141 
149  std::shared_ptr<spdlog::logger> get_channel(const std::string& channel_name = "stdout");
150 
156  std::set<std::string> get_channels() const;
157 
166  std::shared_ptr<spdlog::logger> add_channel(const std::string& channel_name, const std::vector<std::shared_ptr<log_sink>>& sinks, const std::string& level = "info");
167 
173  void remove_channel(const std::string& channel_name);
174 
181  std::string get_level_of_channel(const std::string& channel_name) const;
182 
189  void set_level_of_channel(const std::string& channel_name, const std::string& level);
190 
196  std::set<std::string> get_available_log_levels() const;
197 
204  void activate_channel(const std::string& channel_name);
205 
209  void activate_all_channels();
210 
216  void deactivate_channel(const std::string& channel_name);
217 
221  void deactivate_all_channels();
222 
228  CallbackHook<void(const spdlog::level::level_enum&, const std::string&, const std::string&)>& get_gui_callback();
229 
235  ProgramOptions& get_option_descriptions();
236 
242  void handle_options(ProgramArguments& args);
243 
249  std::vector<std::shared_ptr<hal::LogManager::log_sink>> get_default_sinks();
250 
256  void remove_sink_from_default(const std::string& sink_type);
257 
264  static std::shared_ptr<log_sink> create_stdout_sink(const bool colored = true);
265 
275  static std::shared_ptr<log_sink> create_file_sink(const std::filesystem::path& file_name = "", const bool truncate = false);
276 
282  static std::shared_ptr<log_sink> create_gui_sink();
283 
284  private:
285  static std::map<std::string, std::shared_ptr<log_sink>> m_file_sinks;
286 
287  // LogManager class constructor (private due to singleton)
288  LogManager(const std::filesystem::path& file_name);
289 
290  // LogManager class destructor (private due to singleton)
291  ~LogManager();
292 
293  // LogManager class object non-copyable
294  LogManager(const LogManager&) = delete;
295 
296  // LogManager class object non-copyable
297  LogManager& operator=(const LogManager&) = delete;
298 
299  std::filesystem::path m_file_path;
300 
301  std::map<std::string, spdlog::level::level_enum> m_level;
302 
303  std::map<std::string, std::shared_ptr<spdlog::logger>> m_logger;
304 
305  std::map<std::string, std::vector<std::shared_ptr<log_sink>>> m_logger_sinks;
306 
307  CallbackHook<void(const spdlog::level::level_enum&, const std::string&, const std::string&)> m_gui_callback;
308 
309  ProgramOptions m_descriptions;
310 
311  std::string m_enforce_level;
312 
313  std::vector<std::shared_ptr<hal::LogManager::log_sink>> m_default_sinks;
314 
315  static LogManager* m_instance;
316  };
317 
318  class log_gui_sink : public spdlog::sinks::base_sink<std::mutex>
319  {
320  public:
322  log_gui_sink() = default;
324  ~log_gui_sink() = default;
325 
326  protected:
328  void sink_it_(const spdlog::details::log_msg& msg) override;
329  void flush_() override;
330  };
331 } // namespace hal
#define CORE_API
Definition: arch_linux.h:28
log_gui_sink()=default
void sink_it_(const spdlog::details::log_msg &msg) override
Definition: log.cpp:439
void flush_() override
Definition: log.cpp:446
~log_gui_sink()=default
std::string sink_type
Definition: log.h:110
std::filesystem::path path
Definition: log.h:113
std::shared_ptr< spdlog::sinks::sink > spdlog_sink
Definition: log.h:109