Skip to content

Commit 3f139bd

Browse files
committed
Swift: address logging review comments
1 parent acaa6a5 commit 3f139bd

File tree

6 files changed

+29
-36
lines changed

6 files changed

+29
-36
lines changed

swift/README.md

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,14 +50,15 @@ You can also run `../misc/codegen/codegen.py`, as long as you are beneath the `s
5050
A log file is produced for each run under `CODEQL_EXTRACTOR_SWIFT_LOG_DIR` (the usual DB log directory).
5151

5252
You can use the environment variable `CODEQL_EXTRACTOR_SWIFT_LOG_LEVELS` to configure levels for
53-
loggers and outputs. This must have the form of a comma separated `spec:level` list, where
53+
loggers and outputs. This must have the form of a comma separated `spec:min_level` list, where
5454
`spec` is either a glob pattern (made up of alphanumeric, `/`, `*` and `.` characters) for
55-
matching logger names or one of `out:bin`, `out:text` or `out:console`, and `level` is one of `trace`, `debug`, `info`,
56-
`warning`, `error`, `critical` or `no_logs` to turn logs completely off.
55+
matching logger names or one of `out:bin`, `out:text` or `out:console`, and `min_level` is one
56+
of `trace`, `debug`, `info`, `warning`, `error`, `critical` or `no_logs` to turn logs completely off.
57+
5758
Current output default levels are no binary logs, `info` logs or higher in the text file and `warning` logs or higher on
58-
standard error. By default, all loggers are configured with the lowest output level. Logger names are visible in the
59-
textual logs between `[...]`. Examples are `extractor/dispatcher` or `extractor/<source filename>.trap`. An example
60-
of `CODEQL_EXTRACTOR_SWIFT_LOG_LEVELS` usage is the following:
59+
standard error. By default, all loggers are configured with the lowest logging level of all outputs (`info` by default).
60+
Logger names are visible in the textual logs between `[...]`. Examples are `extractor/dispatcher`
61+
or `extractor/<source filename>.trap`. An example of `CODEQL_EXTRACTOR_SWIFT_LOG_LEVELS` usage is the following:
6162

6263
```bash
6364
export CODEQL_EXTRACTOR_SWIFT_LOG_LEVELS=out:console:trace,out:text:no_logs,*:warning,*.trap:trace
@@ -109,4 +110,5 @@ In particular for breakpoints to work you might need to setup the following remo
109110
| `bazel-out` | `/absolute/path/to/codeql/bazel-out` |
110111

111112
### Thread safety
113+
112114
The extractor is single-threaded, and there was no effort to make anything in it thread-safe.

swift/extractor/infra/SwiftDispatcher.h

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -152,11 +152,7 @@ class SwiftDispatcher {
152152
return *l;
153153
}
154154
waitingForNewLabel = e;
155-
// TODO: more generic and informational visiting one-line log
156-
if constexpr (std::is_convertible_v<E, const swift::ValueDecl*>) {
157-
const swift::ValueDecl* x = e;
158-
LOG_TRACE("{}", x->getName().getBaseIdentifier().str());
159-
}
155+
// TODO: add tracing logs for visited stuff, maybe within the translators?
160156
visit(e, std::forward<Args>(args)...);
161157
Log::flush();
162158
// TODO when everything is moved to structured C++ classes, this should be moved to createEntry

swift/extractor/infra/log/SwiftLogging.cpp

Lines changed: 14 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,11 @@ Log::Level getLevelFor(std::string_view name, const LevelRules& rules, Log::Leve
2323
return dflt;
2424
}
2525

26-
const char* getEnvOr(const char* var, const char* deflt) {
26+
const char* getEnvOr(const char* var, const char* dflt) {
2727
if (const char* ret = getenv(var)) {
2828
return ret;
2929
}
30-
return deflt;
30+
return dflt;
3131
}
3232

3333
std::string_view matchToView(std::csub_match m) {
@@ -48,16 +48,11 @@ Log::Level matchToLevel(std::csub_match m) {
4848
return stringToLevel(matchToView(m));
4949
}
5050

51-
struct LevelConfiguration {
52-
LevelRules& sourceRules;
53-
Log::Level& binSeverity;
54-
Log::Level& textSeverity;
55-
Log::Level& consoleSeverity;
56-
std::vector<std::string>& problems;
57-
};
51+
} // namespace
5852

59-
void collectSeverityRules(const char* var, LevelConfiguration&& configuration) {
60-
if (auto levels = getEnvOr(var, nullptr)) {
53+
std::vector<std::string> Log::collectSeverityRulesAndReturnProblems(const char* envVar) {
54+
std::vector<std::string> problems;
55+
if (auto levels = getEnvOr(envVar, nullptr)) {
6156
// expect comma-separated <glob pattern>:<log severity>
6257
std::regex comma{","};
6358
std::regex levelAssignment{R"((?:([*./\w]+)|(?:out:(bin|text|console))):()" LEVEL_REGEX_PATTERN
@@ -76,31 +71,28 @@ void collectSeverityRules(const char* var, LevelConfiguration&& configuration) {
7671
pattern.insert(pos, (pattern[pos] == '*') ? "." : "\\");
7772
pos += 2;
7873
}
79-
configuration.sourceRules.emplace_back(pattern, level);
74+
sourceRules.emplace_back(pattern, level);
8075
} else {
8176
auto out = matchToView(match[2]);
8277
if (out == "bin") {
83-
configuration.binSeverity = level;
78+
binary.level = level;
8479
} else if (out == "text") {
85-
configuration.textSeverity = level;
80+
text.level = level;
8681
} else if (out == "console") {
87-
configuration.consoleSeverity = level;
82+
console.level = level;
8883
}
8984
}
9085
} else {
91-
configuration.problems.emplace_back("Malformed log level rule: " + it->str());
86+
problems.emplace_back("Malformed log level rule: " + it->str());
9287
}
9388
}
9489
}
90+
return problems;
9591
}
9692

97-
} // namespace
98-
9993
void Log::configure() {
10094
// as we are configuring logging right now, we collect problems and log them at the end
101-
std::vector<std::string> problems;
102-
collectSeverityRules("CODEQL_EXTRACTOR_SWIFT_LOG_LEVELS",
103-
{sourceRules, binary.level, text.level, console.level, problems});
95+
auto problems = collectSeverityRulesAndReturnProblems("CODEQL_EXTRACTOR_SWIFT_LOG_LEVELS");
10496
if (text || binary) {
10597
std::filesystem::path logFile = getEnvOr("CODEQL_EXTRACTOR_SWIFT_LOG_DIR", ".");
10698
logFile /= logRootName;
@@ -144,7 +136,7 @@ void Log::flushImpl() {
144136
}
145137

146138
Log::LoggerConfiguration Log::getLoggerConfigurationImpl(std::string_view name) {
147-
LoggerConfiguration ret{session, logRootName};
139+
LoggerConfiguration ret{session, std::string{logRootName}};
148140
ret.fullyQualifiedName += '/';
149141
ret.fullyQualifiedName += name;
150142
ret.level = std::min({binary.level, text.level, console.level});

swift/extractor/infra/log/SwiftLogging.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@
6868
namespace codeql {
6969

7070
// tools should define this to tweak the root name of all loggers
71-
extern const char* const logRootName;
71+
extern const std::string_view logRootName;
7272

7373
// This class is responsible for the global log state (outputs, log level rules, flushing)
7474
// State is stored in the singleton `Log::instance()`.
@@ -152,6 +152,7 @@ class Log {
152152
FilteredOutput<binlog::TextOutputStream> text{Level::info, textFile, format};
153153
FilteredOutput<binlog::TextOutputStream> console{Level::warning, std::cerr, format};
154154
LevelRules sourceRules;
155+
std::vector<std::string> collectSeverityRulesAndReturnProblems(const char* envVar);
155156
};
156157

157158
// This class represent a named domain-specific logger, responsible for pushing logs using the

swift/extractor/main.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020

2121
using namespace std::string_literals;
2222

23-
const char* const codeql::logRootName = "extractor";
23+
const std::string_view codeql::logRootName = "extractor";
2424

2525
// must be called before processFrontendOptions modifies output paths
2626
static void lockOutputSwiftModuleTraps(codeql::SwiftExtractorState& state,
@@ -182,6 +182,7 @@ codeql::SwiftExtractorConfiguration configure(int argc, char** argv) {
182182
return configuration;
183183
}
184184

185+
// TODO: use `absl::StrJoin` or `boost::algorithm::join`
185186
static auto argDump(int argc, char** argv) {
186187
std::string ret;
187188
for (auto arg = argv + 1; arg < argv + argc; ++arg) {
@@ -192,13 +193,13 @@ static auto argDump(int argc, char** argv) {
192193
return ret;
193194
}
194195

196+
// TODO: use `absl::StrJoin` or `boost::algorithm::join`
195197
static auto envDump(char** envp) {
196198
std::string ret;
197199
for (auto env = envp; *env; ++env) {
198200
ret += *env;
199201
ret += '\n';
200202
}
201-
ret.pop_back();
202203
return ret;
203204
}
204205

swift/extractor/trap/TrapLabel.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ class UntypedTrapLabel {
5555
size_t strSize() const {
5656
if (id_ == undefined) return 17; // #ffffffffffffffff
5757
if (id_ == 0) return 2; // #0
58+
// TODO: use absl::bit_width or C+20 std::bit_width instead of this ugly formula
5859
return /* # */ 1 + /* hex digits */ static_cast<size_t>(ceil(log2(id_ + 1) / 4));
5960
}
6061
};

0 commit comments

Comments
 (0)