From 8c13faf3d8dc845a4cce19bdc3efcecff33a2b58 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Fri, 5 Sep 2025 14:07:15 +0100 Subject: [PATCH] Go: Set log level based on `CODEQL_VERBOSITY` --- .../cli/go-autobuilder/go-autobuilder.go | 2 + go/extractor/cli/go-extractor/BUILD.bazel | 1 + go/extractor/cli/go-extractor/go-extractor.go | 3 ++ go/extractor/util/BUILD.bazel | 2 + go/extractor/util/logging.go | 45 +++++++++++++++++++ go/extractor/util/logging_test.go | 33 ++++++++++++++ 6 files changed, 86 insertions(+) create mode 100644 go/extractor/util/logging.go create mode 100644 go/extractor/util/logging_test.go diff --git a/go/extractor/cli/go-autobuilder/go-autobuilder.go b/go/extractor/cli/go-autobuilder/go-autobuilder.go index 1601b5659d33..ae9a478c3674 100644 --- a/go/extractor/cli/go-autobuilder/go-autobuilder.go +++ b/go/extractor/cli/go-autobuilder/go-autobuilder.go @@ -623,6 +623,8 @@ func installDependenciesAndBuild() { } func main() { + util.SetLogLevel() + if len(os.Args) == 1 { installDependenciesAndBuild() } else if len(os.Args) == 2 && os.Args[1] == "--identify-environment" { diff --git a/go/extractor/cli/go-extractor/BUILD.bazel b/go/extractor/cli/go-extractor/BUILD.bazel index 769e4a7b09bc..ec7cf150f0a6 100644 --- a/go/extractor/cli/go-extractor/BUILD.bazel +++ b/go/extractor/cli/go-extractor/BUILD.bazel @@ -11,6 +11,7 @@ go_library( deps = [ "//go/extractor", "//go/extractor/diagnostics", + "//go/extractor/util", ], ) diff --git a/go/extractor/cli/go-extractor/go-extractor.go b/go/extractor/cli/go-extractor/go-extractor.go index 425af6cd55d8..72ab3291f3cc 100644 --- a/go/extractor/cli/go-extractor/go-extractor.go +++ b/go/extractor/cli/go-extractor/go-extractor.go @@ -10,6 +10,7 @@ import ( "github.com/github/codeql-go/extractor" "github.com/github/codeql-go/extractor/diagnostics" + "github.com/github/codeql-go/extractor/util" ) var cpuprofile, memprofile string @@ -96,6 +97,8 @@ func parseFlags(args []string, mimic bool, extractTests bool) ([]string, []strin } func main() { + util.SetLogLevel() + extractTestsDefault := os.Getenv("CODEQL_EXTRACTOR_GO_OPTION_EXTRACT_TESTS") == "true" buildFlags, patterns, extractTests := parseFlags(os.Args[1:], false, extractTestsDefault) diff --git a/go/extractor/util/BUILD.bazel b/go/extractor/util/BUILD.bazel index dd294a63a9c1..b8f005378aa2 100644 --- a/go/extractor/util/BUILD.bazel +++ b/go/extractor/util/BUILD.bazel @@ -6,6 +6,7 @@ go_library( name = "util", srcs = [ "extractvendordirs.go", + "logging.go", "registryproxy.go", "semver.go", "util.go", @@ -18,6 +19,7 @@ go_library( go_test( name = "util_test", srcs = [ + "logging_test.go", "registryproxy_test.go", "semver_test.go", "util_test.go", diff --git a/go/extractor/util/logging.go b/go/extractor/util/logging.go new file mode 100644 index 000000000000..b0919151edfd --- /dev/null +++ b/go/extractor/util/logging.go @@ -0,0 +1,45 @@ +package util + +import ( + "log/slog" + "os" + "strings" +) + +// Mirrors the verbosity definitions in the CodeQL CLI, which are passed to us +// in the `CODEQL_VERBOSITY` environment variable. +type Verbosity string + +const ( + // Only print error messages. + Errors Verbosity = "errors" + // Print warnings and error messages. + Warnings Verbosity = "warnings" + // Default verbosity. + Progress Verbosity = "progress" + // More details of normal operations. + Details Verbosity = "progress+" + // Debug level set by e.g. the CodeQL Action. + Spammy Verbosity = "progress++" + // The most detailed. + Spammier Verbosity = "progress+++" +) + +func parseLogLevel(value string) slog.Level { + value = strings.ToLower(value) + if strings.HasPrefix(value, string(Details)) { + return slog.LevelDebug + } else if value == string(Errors) { + return slog.LevelError + } else if value == string(Warnings) { + return slog.LevelWarn + } else { + // Default + return slog.LevelInfo + } +} + +// Sets the log level for the default `slog` logger, based on `CODEQL_VERBOSITY`. +func SetLogLevel() { + slog.SetLogLoggerLevel(parseLogLevel(os.Getenv("CODEQL_VERBOSITY"))) +} diff --git a/go/extractor/util/logging_test.go b/go/extractor/util/logging_test.go new file mode 100644 index 000000000000..1409f7b8d9a0 --- /dev/null +++ b/go/extractor/util/logging_test.go @@ -0,0 +1,33 @@ +package util + +import ( + "log/slog" + "strings" + "testing" +) + +func assertLogLevel(t *testing.T, value string, level slog.Level) { + actual := parseLogLevel(value) + if actual != level { + t.Errorf("Expected %s to parse as %s, but got %s", value, level, actual) + } +} + +func TestParseLogLevel(t *testing.T) { + // Known verbosity levels. + assertLogLevel(t, string(Errors), slog.LevelError) + assertLogLevel(t, string(Warnings), slog.LevelWarn) + assertLogLevel(t, string(Progress), slog.LevelInfo) + assertLogLevel(t, string(Details), slog.LevelDebug) + assertLogLevel(t, string(Spammy), slog.LevelDebug) + assertLogLevel(t, string(Spammier), slog.LevelDebug) + + // Ignore case + assertLogLevel(t, strings.ToUpper(string(Spammier)), slog.LevelDebug) + assertLogLevel(t, strings.ToUpper(string(Errors)), slog.LevelError) + + // Other values default to LevelInfo + assertLogLevel(t, "", slog.LevelInfo) + assertLogLevel(t, "unknown", slog.LevelInfo) + assertLogLevel(t, "none", slog.LevelInfo) +}