8
8
#include < binlog/binlog.hpp>
9
9
#include < binlog/TextOutputStream.hpp>
10
10
#include < binlog/EventFilter.hpp>
11
+ #include < binlog/adapt_stdfilesystem.hpp>
12
+ #include < binlog/adapt_stdoptional.hpp>
13
+ #include < binlog/adapt_stdvariant.hpp>
11
14
12
15
// Logging macros. These will call `logger()` to get a Logger instance, picking up any `logger`
13
16
// defined in the current scope. Domain-specific loggers can be added or used by either:
64
67
65
68
namespace codeql {
66
69
70
+ // tools should define this to tweak the root name of all loggers
71
+ extern const char * const logRootName;
72
+
67
73
// This class is responsible for the global log state (outputs, log level rules, flushing)
68
74
// State is stored in the singleton `Log::instance()`.
69
75
// Before using logging, `Log::configure("<name>")` should be used (e.g.
70
76
// `Log::configure("extractor")`). Then, `Log::flush()` should be regularly called.
77
+ // Logging is configured upon first usage. This consists in
78
+ // * using environment variable `CODEQL_EXTRACTOR_SWIFT_LOG_DIR` to choose where to dump the log
79
+ // file(s). Log files will go to a subdirectory thereof named after `logRootName`
80
+ // * using environment variable `CODEQL_EXTRACTOR_SWIFT_LOG_LEVELS` to configure levels for
81
+ // loggers and outputs. This must have the form of a comma separated `spec:level` list, where
82
+ // `spec` is either a glob pattern (made up of alphanumeric, `/`, `*` and `.` characters) for
83
+ // matching logger names or one of `out:bin`, `out:text` or `out:console`.
84
+ // Output default levels can be seen in the corresponding initializers below. By default, all
85
+ // loggers are configured with the lowest output level
71
86
class Log {
72
87
public:
73
88
using Level = binlog::Severity;
@@ -79,17 +94,6 @@ class Log {
79
94
Level level;
80
95
};
81
96
82
- // Configure logging. This consists in
83
- // * using environment variable `CODEQL_EXTRACTOR_SWIFT_LOG_DIR` to choose where to dump the log
84
- // file(s). Log files will go to a subdirectory thereof named after `root`
85
- // * using environment variable `CODEQL_EXTRACTOR_SWIFT_LOG_LEVELS` to configure levels for
86
- // loggers and outputs. This must have the form of a comma separated `spec:level` list, where
87
- // `spec` is either a glob pattern (made up of alphanumeric, `/`, `*` and `.` characters) for
88
- // matching logger names or one of `out:bin`, `out:text` or `out:console`.
89
- // Output default levels can be seen in the corresponding initializers below. By default, all
90
- // loggers are configured with the lowest output level
91
- static void configure (std::string_view root) { instance ().configureImpl (root); }
92
-
93
97
// Flush logs to the designated outputs
94
98
static void flush () { instance ().flushImpl (); }
95
99
@@ -101,16 +105,16 @@ class Log {
101
105
private:
102
106
static constexpr const char * format = " %u %S [%n] %m (%G:%L)\n " ;
103
107
104
- Log () = default ;
108
+ Log () { configure (); }
105
109
106
110
static Log& instance () {
107
111
static Log ret;
108
112
return ret;
109
113
}
110
114
111
- static class Logger & logger ();
115
+ class Logger & logger ();
112
116
113
- void configureImpl (std::string_view root );
117
+ void configure ( );
114
118
void flushImpl ();
115
119
LoggerConfiguration getLoggerConfigurationImpl (std::string_view name);
116
120
@@ -148,19 +152,24 @@ class Log {
148
152
FilteredOutput<binlog::TextOutputStream> text{Level::info, textFile, format};
149
153
FilteredOutput<binlog::TextOutputStream> console{Level::warning, std::cerr, format};
150
154
LevelRules sourceRules;
151
- std::string rootName;
152
155
};
153
156
154
157
// This class represent a named domain-specific logger, responsible for pushing logs using the
155
158
// underlying `binlog::SessionWriter` class. This has a configured log level, so that logs on this
156
159
// `Logger` with a level lower than the configured one are no-ops. The level is configured based
157
- // on rules matching `<root name>/<name>` in `CODEQL_EXTRACTOR_SWIFT_LOG_LEVELS` (see above).
158
- // `<root name>` is what is provided to the global `Log::configure`, `<name>` is provided in the
159
- // constructor. If no rule matches the name, the log level defaults to the minimum level of all
160
- // outputs.
160
+ // on rules matching `<logRootName>/<name>` in `CODEQL_EXTRACTOR_SWIFT_LOG_LEVELS` (see above).
161
+ // `<name>` is provided in the constructor. If no rule matches the name, the log level defaults to
162
+ // the minimum level of all outputs.
161
163
class Logger {
162
164
public:
163
- explicit Logger (const std::string& name) : Logger(Log::getLoggerConfiguration(name)) {}
165
+ // configured logger based on name, as explained above
166
+ explicit Logger (std::string_view name) : Logger(Log::getLoggerConfiguration(name)) {}
167
+
168
+ // used internally, public to be accessible to Log for its own logger
169
+ explicit Logger (Log::LoggerConfiguration&& configuration)
170
+ : w{configuration.session , queueSize, /* id */ 0 ,
171
+ std::move (configuration.fullyQualifiedName )},
172
+ level_{configuration.level } {}
164
173
165
174
binlog::SessionWriter& writer () { return w; }
166
175
Log::Level level () const { return level_; }
@@ -172,11 +181,6 @@ class Logger {
172
181
private:
173
182
static constexpr size_t queueSize = 1 << 20 ; // default taken from binlog
174
183
175
- explicit Logger (Log::LoggerConfiguration&& configuration)
176
- : w{configuration.session , queueSize, /* id */ 0 ,
177
- std::move (configuration.fullyQualifiedName )},
178
- level_{configuration.level } {}
179
-
180
184
binlog::SessionWriter w;
181
185
Log::Level level_;
182
186
};
0 commit comments