-
Notifications
You must be signed in to change notification settings - Fork 23
/
Copy pathlogging.hpp
164 lines (130 loc) · 5.94 KB
/
logging.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
/// @file log/logging.hpp
///
/// @brief Defines logging infrastructure
#pragma once
#include <cstdint>
#include <map>
#include <memory>
#include <ostream>
#include <boost/log/attributes/clock.hpp>
#include <boost/log/expressions/keyword.hpp>
#include <boost/log/sinks/sync_frontend.hpp>
#include <boost/log/sinks/text_ostream_backend.hpp>
#include <boost/log/sources/severity_channel_logger.hpp>
#include <boost/log/utility/manipulators/add_value.hpp>
#include <boost/utility/string_view.hpp>
namespace viam {
namespace sdk {
/// @defgroup Log Classes related to logging
/// @brief Severity levels for the logger.
/// @ingroup Log
/// @remark Our enums are usually prefixed with k_, but these values are meant to be used without
/// namespace qualification in the log macros, eg `VIAM_SDK_LOG(info)` instead of
/// `VIAM_SDK_LOG(k_info)`.
enum class log_level : std::int8_t {
trace = -2,
debug = -1,
info = 0, // default value is info
warn = 1,
error = 2,
fatal = 3,
};
std::string to_string(log_level);
log_level level_from_string(std::string level);
std::ostream& operator<<(std::ostream&, log_level);
/// @brief Type alias for the log source in the C++ SDK.
/// @ingroup Log
///
/// In the paradigm of Boost.Log the C++ SDK has precisely one logging source, namely the source of
/// messages generated by the user invoking one of the logging macros.
using LogSource = boost::log::sources::severity_channel_logger_mt<log_level>;
/// @brief Returns the "channel name" of general log messages not originating from resources.
/// @ingroup Log
const char* global_resource_name();
/// @class LogManager logging.hpp "log/logging.hpp"
/// @brief Manages the logging infrastructure in the SDDK.
/// @ingroup Log
///
/// Handles initialization and bookkeeping for logging infrastructure in the C++ SDK. This includes
/// console logging, if active, and both global and resource-level log filtering.
class LogManager {
public:
struct Filter {
const LogManager* parent;
bool operator()(const boost::log::attribute_value_set&) const;
};
/// @brief Returns the unique logger instance.
///
/// This is the only way to access the logger.
static LogManager& get();
/// @brief Override the channel name of general log messages not originating from resources.
void set_global_resource_name(const std::string& name);
/// @brief Set the global logger severity.
void set_global_log_level(log_level);
/// @brief Set the global logger severity from a command line argument vector.
///
/// Sets severity to debug if "--log-level=debug" is
/// the third argument. Sets severity to info otherwise. Useful for module
/// implementations. See LogLevel documentation in the RDK for more information on
/// how to start modules with a "log-level" commandline argument.
void set_global_log_level(int argc, char** argv);
/// @brief Set the logger severity for a resource.
///
/// LogManager can maintain separate severity levels for individual resources. For example, you
/// may want to only report "error" messages for global logs and logs for one component of a
/// modular resource, but enable verbose logging for a new component that is still being
/// debugged.
/// @see @ref Resource, which has a set_log_level method which automatically provides its own
/// resource name.
void set_resource_log_level(const std::string& resource, log_level);
/// @brief Return the SDK global log source.
///
/// Users should prefer to log messages using the logging macros below.
LogSource& global_logger();
private:
friend class RobotClient;
friend class Instance;
LogManager() = default;
LogManager(const LogManager&) = delete;
LogManager(LogManager&&) = delete;
LogManager& operator=(const LogManager&) = delete;
LogManager& operator=(LogManager&&) = delete;
void init_logging();
void disable_console_logging();
LogSource sdk_logger_;
boost::shared_ptr<boost::log::sinks::synchronous_sink<boost::log::sinks::text_ostream_backend>>
console_sink_;
log_level global_level_{log_level::info};
std::map<std::string, log_level> resource_levels_;
};
namespace log_detail {
// Some of the filenames in the SDK are not unique, eg config/resource.hpp, resource/resource.hpp.
// This function trims a full filename /path/to/some/file.xpp to some/file.xpp
boost::string_view trim_filename(const char* file);
} // namespace log_detail
BOOST_LOG_ATTRIBUTE_KEYWORD_TYPE(attr_channel, "Channel", std::string);
BOOST_LOG_ATTRIBUTE_KEYWORD_TYPE(attr_sev, "Severity", viam::sdk::log_level);
BOOST_LOG_ATTRIBUTE_KEYWORD_TYPE(attr_file, "file", boost::string_view);
BOOST_LOG_ATTRIBUTE_KEYWORD_TYPE(attr_line, "line", unsigned int);
BOOST_LOG_ATTRIBUTE_KEYWORD_TYPE(attr_time,
"TimeStamp",
boost::log::attributes::local_clock::value_type);
#define VIAM_SDK_LOG_IMPL(lg, level) \
BOOST_LOG_SEV((lg), ::viam::sdk::log_level::level) \
<< ::boost::log::add_value(::viam::sdk::attr_file_type{}, \
::viam::sdk::log_detail::trim_filename(__FILE__)) \
<< ::boost::log::add_value(::viam::sdk::attr_line_type{}, __LINE__)
/// @brief Log macro for general SDK logs.
/// @ingroup Log
///
/// Use this macro to generate log messages pertaining to the SDK at large.
#define VIAM_SDK_LOG(level) VIAM_SDK_LOG_IMPL(::viam::sdk::LogManager::get().global_logger(), level)
/// @brief Log macro for resource-level logs.
/// @ingroup Log
///
/// This macro can only be called from the definition of a member function of a class inheriting
/// @ref Resource. It will log messages to the log source of that specific resource, allowing
/// resource-level log filtering.
#define VIAM_RESOURCE_LOG(level) VIAM_SDK_LOG_IMPL(this->logger_, level)
} // namespace sdk
} // namespace viam