mirror of
https://github.com/github/codeql.git
synced 2025-12-17 01:03:14 +01:00
Swift: add configuration of diagnostics logs
This commit is contained in:
@@ -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
|
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
|
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
|
`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.
|
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
|
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();
|
return output.good();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void flush() { output.flush(); }
|
||||||
|
|
||||||
// write out binlog entries as corresponding JSON diagnostics entries. Expects all entries to have
|
// 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.
|
// a category equal to an id of a previously created SwiftDiagnosticSource.
|
||||||
void write(const char* buffer, std::size_t bufferSize);
|
void write(const char* buffer, std::size_t bufferSize);
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#define LEVEL_REGEX_PATTERN "trace|debug|info|warning|error|critical|no_logs"
|
#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)) {
|
if (auto levels = getEnvOr(envVar, nullptr)) {
|
||||||
// expect comma-separated <glob pattern>:<log severity>
|
// expect comma-separated <glob pattern>:<log severity>
|
||||||
std::regex comma{","};
|
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 begin{levels, levels + strlen(levels), comma, -1};
|
||||||
std::cregex_token_iterator end{};
|
std::cregex_token_iterator end{};
|
||||||
for (auto it = begin; it != end; ++it) {
|
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);
|
sourceRules.emplace_back(pattern, level);
|
||||||
} else {
|
} else {
|
||||||
auto out = matchToView(match[2]);
|
auto out = matchToView(match[2]);
|
||||||
if (out == "bin") {
|
if (out == "binary") {
|
||||||
binary.level = level;
|
binary.level = level;
|
||||||
} else if (out == "text") {
|
} else if (out == "text") {
|
||||||
text.level = level;
|
text.level = level;
|
||||||
} else if (out == "console") {
|
} else if (out == "console") {
|
||||||
console.level = level;
|
console.level = level;
|
||||||
|
} else if (out == "diagnostics") {
|
||||||
|
diagnostics.level = level;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -95,12 +98,14 @@ std::vector<std::string> Log::collectLevelRulesAndReturnProblems(const char* env
|
|||||||
void Log::configure() {
|
void Log::configure() {
|
||||||
// as we are configuring logging right now, we collect problems and log them at the end
|
// 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 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) {
|
if (text || binary) {
|
||||||
std::filesystem::path logFile = getEnvOr("CODEQL_EXTRACTOR_SWIFT_LOG_DIR", "extractor-out/log");
|
std::filesystem::path logFile = getEnvOr("CODEQL_EXTRACTOR_SWIFT_LOG_DIR", "extractor-out/log");
|
||||||
logFile /= "swift";
|
logFile /= "swift";
|
||||||
logFile /= programName;
|
logFile /= programName;
|
||||||
logFile /= now;
|
logFile /= logBaseName;
|
||||||
std::error_code ec;
|
std::error_code ec;
|
||||||
std::filesystem::create_directories(logFile.parent_path(), ec);
|
std::filesystem::create_directories(logFile.parent_path(), ec);
|
||||||
if (!ec) {
|
if (!ec) {
|
||||||
@@ -130,7 +135,7 @@ void Log::configure() {
|
|||||||
std::filesystem::path diagFile =
|
std::filesystem::path diagFile =
|
||||||
getEnvOr("CODEQL_EXTRACTOR_SWIFT_DIAGNOSTIC_DIR", "extractor-out/diagnostics");
|
getEnvOr("CODEQL_EXTRACTOR_SWIFT_DIAGNOSTIC_DIR", "extractor-out/diagnostics");
|
||||||
diagFile /= programName;
|
diagFile /= programName;
|
||||||
diagFile /= now;
|
diagFile /= logBaseName;
|
||||||
diagFile.replace_extension(".jsonl");
|
diagFile.replace_extension(".jsonl");
|
||||||
std::error_code ec;
|
std::error_code ec;
|
||||||
std::filesystem::create_directories(diagFile.parent_path(), ec);
|
std::filesystem::create_directories(diagFile.parent_path(), ec);
|
||||||
@@ -149,8 +154,8 @@ void Log::configure() {
|
|||||||
for (const auto& problem : problems) {
|
for (const auto& problem : problems) {
|
||||||
LOG_ERROR("{}", problem);
|
LOG_ERROR("{}", problem);
|
||||||
}
|
}
|
||||||
LOG_INFO("Logging configured (binary: {}, text: {}, console: {})", binary.level, text.level,
|
LOG_INFO("Logging configured (binary: {}, text: {}, console: {}, diagnostics: {})", binary.level,
|
||||||
console.level);
|
text.level, console.level, diagnostics.level);
|
||||||
initialized = true;
|
initialized = true;
|
||||||
flushImpl();
|
flushImpl();
|
||||||
}
|
}
|
||||||
@@ -163,6 +168,9 @@ void Log::flushImpl() {
|
|||||||
if (binary) {
|
if (binary) {
|
||||||
binary.output.flush();
|
binary.output.flush();
|
||||||
}
|
}
|
||||||
|
if (diagnostics) {
|
||||||
|
diagnostics.output.flush();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Log::LoggerConfiguration Log::getLoggerConfigurationImpl(std::string_view name) {
|
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
|
// * 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
|
// 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
|
// `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
|
// Output default levels can be seen in the corresponding initializers below. By default, all
|
||||||
// loggers are configured with the lowest output level
|
// loggers are configured with the lowest output level
|
||||||
class Log {
|
class Log {
|
||||||
|
|||||||
Reference in New Issue
Block a user