Skip to content

Commit a5162b0

Browse files
committed
Swift: remove Log::configure
1 parent 6ef9088 commit a5162b0

File tree

3 files changed

+39
-31
lines changed

3 files changed

+39
-31
lines changed

swift/extractor/infra/log/SwiftLogging.cpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -96,15 +96,14 @@ void collectSeverityRules(const char* var, LevelConfiguration&& configuration) {
9696

9797
} // namespace
9898

99-
void Log::configureImpl(std::string_view root) {
100-
rootName = root;
99+
void Log::configure() {
101100
// as we are configuring logging right now, we collect problems and log them at the end
102101
std::vector<std::string> problems;
103102
collectSeverityRules("CODEQL_EXTRACTOR_SWIFT_LOG_LEVELS",
104103
{sourceRules, binary.level, text.level, console.level, problems});
105104
if (text || binary) {
106105
std::filesystem::path logFile = getEnvOr("CODEQL_EXTRACTOR_SWIFT_LOG_DIR", ".");
107-
logFile /= root;
106+
logFile /= logRootName;
108107
logFile /= std::to_string(std::chrono::system_clock::now().time_since_epoch().count());
109108
std::error_code ec;
110109
std::filesystem::create_directories(logFile.parent_path(), ec);
@@ -145,11 +144,15 @@ void Log::flushImpl() {
145144
}
146145

147146
Log::LoggerConfiguration Log::getLoggerConfigurationImpl(std::string_view name) {
148-
LoggerConfiguration ret{session, rootName};
147+
LoggerConfiguration ret{session, logRootName};
149148
ret.fullyQualifiedName += '/';
150149
ret.fullyQualifiedName += name;
151150
ret.level = std::min({binary.level, text.level, console.level});
152151
ret.level = getLevelFor(ret.fullyQualifiedName, sourceRules, ret.level);
152+
// avoid Logger constructor loop
153+
if (name != "logging") {
154+
LOG_DEBUG("Configuring logger {} with level {}", ret.fullyQualifiedName, ret.level);
155+
}
153156
return ret;
154157
}
155158

@@ -161,7 +164,7 @@ Log& Log::write(const char* buffer, std::streamsize size) {
161164
}
162165

163166
Logger& Log::logger() {
164-
static Logger ret{"logging"};
167+
static Logger ret{getLoggerConfigurationImpl("logging")};
165168
return ret;
166169
}
167170

swift/extractor/infra/log/SwiftLogging.h

Lines changed: 29 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
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:
@@ -64,10 +67,22 @@
6467

6568
namespace 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
7186
class 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.
161163
class 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
};

swift/extractor/main.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020

2121
using namespace std::string_literals;
2222

23+
const char* const codeql::logRootName = "extractor";
24+
2325
// must be called before processFrontendOptions modifies output paths
2426
static void lockOutputSwiftModuleTraps(codeql::SwiftExtractorState& state,
2527
const swift::FrontendOptions& options) {
@@ -214,7 +216,6 @@ int main(int argc, char** argv, char** envp) {
214216
initializeSwiftModules();
215217

216218
const auto configuration = configure(argc, argv);
217-
codeql::Log::configure("extractor");
218219
{
219220
codeql::Logger logger{"main"};
220221
LOG_INFO("calling extractor with arguments \"{}\"", argDump(argc, argv));

0 commit comments

Comments
 (0)