88#include < binlog/binlog.hpp>
99#include < binlog/TextOutputStream.hpp>
1010#include < binlog/EventFilter.hpp>
11+ #include < binlog/adapt_stdfilesystem.hpp>
12+ #include < binlog/adapt_stdoptional.hpp>
13+ #include < binlog/adapt_stdvariant.hpp>
1114
1215// Logging macros. These will call `logger()` to get a Logger instance, picking up any `logger`
1316// defined in the current scope. Domain-specific loggers can be added or used by either:
6467
6568namespace codeql {
6669
70+ // tools should define this to tweak the root name of all loggers
71+ extern const char * const logRootName;
72+
6773// This class is responsible for the global log state (outputs, log level rules, flushing)
6874// State is stored in the singleton `Log::instance()`.
6975// Before using logging, `Log::configure("<name>")` should be used (e.g.
7076// `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
7186class Log {
7287 public:
7388 using Level = binlog::Severity;
@@ -79,17 +94,6 @@ class Log {
7994 Level level;
8095 };
8196
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-
9397 // Flush logs to the designated outputs
9498 static void flush () { instance ().flushImpl (); }
9599
@@ -101,16 +105,16 @@ class Log {
101105 private:
102106 static constexpr const char * format = " %u %S [%n] %m (%G:%L)\n " ;
103107
104- Log () = default ;
108+ Log () { configure (); }
105109
106110 static Log& instance () {
107111 static Log ret;
108112 return ret;
109113 }
110114
111- static class Logger & logger ();
115+ class Logger & logger ();
112116
113- void configureImpl (std::string_view root );
117+ void configure ( );
114118 void flushImpl ();
115119 LoggerConfiguration getLoggerConfigurationImpl (std::string_view name);
116120
@@ -148,19 +152,24 @@ class Log {
148152 FilteredOutput<binlog::TextOutputStream> text{Level::info, textFile, format};
149153 FilteredOutput<binlog::TextOutputStream> console{Level::warning, std::cerr, format};
150154 LevelRules sourceRules;
151- std::string rootName;
152155};
153156
154157// This class represent a named domain-specific logger, responsible for pushing logs using the
155158// underlying `binlog::SessionWriter` class. This has a configured log level, so that logs on this
156159// `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.
161163class Logger {
162164 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 } {}
164173
165174 binlog::SessionWriter& writer () { return w; }
166175 Log::Level level () const { return level_; }
@@ -172,11 +181,6 @@ class Logger {
172181 private:
173182 static constexpr size_t queueSize = 1 << 20 ; // default taken from binlog
174183
175- explicit Logger (Log::LoggerConfiguration&& configuration)
176- : w{configuration.session , queueSize, /* id */ 0 ,
177- std::move (configuration.fullyQualifiedName )},
178- level_{configuration.level } {}
179-
180184 binlog::SessionWriter w;
181185 Log::Level level_;
182186};
0 commit comments