Swift: add configuration of diagnostics logs

This commit is contained in:
Paolo Tranquilli 2023-05-09 13:59:39 +02:00
Родитель ca94b20284
Коммит 84c017083f
4 изменённых файлов: 20 добавлений и 10 удалений

Просмотреть файл

@ -52,7 +52,7 @@ A log file is produced for each run under `CODEQL_EXTRACTOR_SWIFT_LOG_DIR` (the
You can use the environment variable `CODEQL_EXTRACTOR_SWIFT_LOG_LEVELS` to configure levels for
loggers and outputs. This must have the form of a comma separated `spec:min_level` list, where
`spec` is either a glob pattern (made up of alphanumeric, `/`, `*` and `.` characters) for
matching logger names or one of `out:bin`, `out:text` or `out:console`, and `min_level` is one
matching logger names or one of `out:binary`, `out:text`, `out:console` or `out:diagnostics`, and `min_level` is one
of `trace`, `debug`, `info`, `warning`, `error`, `critical` or `no_logs` to turn logs completely off.
Current output default levels are no binary logs, `info` logs or higher in the text file and `warning` logs or higher on

Просмотреть файл

@ -67,6 +67,8 @@ class SwiftDiagnosticsDumper {
return output.good();
}
void flush() { output.flush(); }
// write out binlog entries as corresponding JSON diagnostics entries. Expects all entries to have
// a category equal to an id of a previously created SwiftDiagnosticSource.
void write(const char* buffer, std::size_t bufferSize);

Просмотреть файл

@ -3,6 +3,7 @@
#include <filesystem>
#include <stdlib.h>
#include <optional>
#include <unistd.h>
#define LEVEL_REGEX_PATTERN "trace|debug|info|warning|error|critical|no_logs"
@ -57,8 +58,8 @@ std::vector<std::string> Log::collectLevelRulesAndReturnProblems(const char* env
if (auto levels = getEnvOr(envVar, nullptr)) {
// expect comma-separated <glob pattern>:<log severity>
std::regex comma{","};
std::regex levelAssignment{R"((?:([*./\w]+)|(?:out:(bin|text|console))):()" LEVEL_REGEX_PATTERN
")"};
std::regex levelAssignment{
R"((?:([*./\w]+)|(?:out:(binary|text|console|diagnostics))):()" LEVEL_REGEX_PATTERN ")"};
std::cregex_token_iterator begin{levels, levels + strlen(levels), comma, -1};
std::cregex_token_iterator end{};
for (auto it = begin; it != end; ++it) {
@ -76,12 +77,14 @@ std::vector<std::string> Log::collectLevelRulesAndReturnProblems(const char* env
sourceRules.emplace_back(pattern, level);
} else {
auto out = matchToView(match[2]);
if (out == "bin") {
if (out == "binary") {
binary.level = level;
} else if (out == "text") {
text.level = level;
} else if (out == "console") {
console.level = level;
} else if (out == "diagnostics") {
diagnostics.level = level;
}
}
} else {
@ -95,12 +98,14 @@ std::vector<std::string> Log::collectLevelRulesAndReturnProblems(const char* env
void Log::configure() {
// as we are configuring logging right now, we collect problems and log them at the end
auto problems = collectLevelRulesAndReturnProblems("CODEQL_EXTRACTOR_SWIFT_LOG_LEVELS");
auto now = std::to_string(std::chrono::system_clock::now().time_since_epoch().count());
auto logBaseName = std::to_string(std::chrono::system_clock::now().time_since_epoch().count());
logBaseName += '-';
logBaseName += std::to_string(getpid());
if (text || binary) {
std::filesystem::path logFile = getEnvOr("CODEQL_EXTRACTOR_SWIFT_LOG_DIR", "extractor-out/log");
logFile /= "swift";
logFile /= programName;
logFile /= now;
logFile /= logBaseName;
std::error_code ec;
std::filesystem::create_directories(logFile.parent_path(), ec);
if (!ec) {
@ -130,7 +135,7 @@ void Log::configure() {
std::filesystem::path diagFile =
getEnvOr("CODEQL_EXTRACTOR_SWIFT_DIAGNOSTIC_DIR", "extractor-out/diagnostics");
diagFile /= programName;
diagFile /= now;
diagFile /= logBaseName;
diagFile.replace_extension(".jsonl");
std::error_code ec;
std::filesystem::create_directories(diagFile.parent_path(), ec);
@ -149,8 +154,8 @@ void Log::configure() {
for (const auto& problem : problems) {
LOG_ERROR("{}", problem);
}
LOG_INFO("Logging configured (binary: {}, text: {}, console: {})", binary.level, text.level,
console.level);
LOG_INFO("Logging configured (binary: {}, text: {}, console: {}, diagnostics: {})", binary.level,
text.level, console.level, diagnostics.level);
initialized = true;
flushImpl();
}
@ -163,6 +168,9 @@ void Log::flushImpl() {
if (binary) {
binary.output.flush();
}
if (diagnostics) {
diagnostics.output.flush();
}
}
Log::LoggerConfiguration Log::getLoggerConfigurationImpl(std::string_view name) {

Просмотреть файл

@ -99,7 +99,7 @@ extern const std::string_view programName;
// * using environment variable `CODEQL_EXTRACTOR_SWIFT_LOG_LEVELS` to configure levels for
// loggers and outputs. This must have the form of a comma separated `spec:level` list, where
// `spec` is either a glob pattern (made up of alphanumeric, `/`, `*` and `.` characters) for
// matching logger names or one of `out:bin`, `out:text` or `out:console`.
// matching logger names or one of `out:binary`, `out:text`, `out:console` or `out:diagnostics`.
// Output default levels can be seen in the corresponding initializers below. By default, all
// loggers are configured with the lowest output level
class Log {