From f34e4c475b6b298f1a0b669ddfe45601103ec567 Mon Sep 17 00:00:00 2001 From: NopeCharon <115794254+NopeCharon@users.noreply.github.com> Date: Mon, 26 Oct 2026 17:50:17 +0530 Subject: [PATCH] Make the log level of Go services configurable All Go services call services.SetupServiceLogging(), which hard coded the logrus level to info. Operators who want to reduce log volume (or debug a service) had no way to change it without rebuilding. Add a common --log_level flag, which can also be set through the PL_LOG_LEVEL environment variable like every other service flag, and use it in SetupServiceLogging(). It accepts any logrus level name (panic, fatal, error, warn, info, debug, trace) and defaults to info, so existing deployments keep their current behavior. An invalid value is a fatal configuration error, in line with how CheckServiceFlags() handles other invalid flags. Fixes #2280 Signed-off-by: NopeCharon <115794254+NopeCharon@users.noreply.github.com> --- src/shared/services/BUILD.bazel | 14 ++++ src/shared/services/logging.go | 7 +- src/shared/services/logging_test.go | 97 ++++++++++++++++++++++++++++ src/shared/services/service_flags.go | 1 + 4 files changed, 118 insertions(+), 1 deletion(-) create mode 100644 src/shared/services/logging_test.go diff --git a/src/shared/services/BUILD.bazel b/src/shared/services/BUILD.bazel index a2c83a9e3f8..567797b2db3 100644 --- a/src/shared/services/BUILD.bazel +++ b/src/shared/services/BUILD.bazel @@ -15,6 +15,7 @@ # SPDX-License-Identifier: Apache-2.0 load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("//bazel:pl_build_system.bzl", "pl_go_test") go_library( name = "services", @@ -50,3 +51,16 @@ go_library( "@org_golang_google_grpc//status", ], ) + +pl_go_test( + name = "services_test", + srcs = ["logging_test.go"], + embed = [":services"], + deps = [ + "@com_github_sirupsen_logrus//:logrus", + "@com_github_spf13_pflag//:pflag", + "@com_github_spf13_viper//:viper", + "@com_github_stretchr_testify//assert", + "@com_github_stretchr_testify//require", + ], +) diff --git a/src/shared/services/logging.go b/src/shared/services/logging.go index 923e0741aa3..1f1f4fea86e 100644 --- a/src/shared/services/logging.go +++ b/src/shared/services/logging.go @@ -24,6 +24,7 @@ import ( "time" log "github.com/sirupsen/logrus" + "github.com/spf13/viper" "github.com/zenazn/goji/web/mutil" version "px.dev/pixie/src/shared/goversion" @@ -39,7 +40,11 @@ func init() { func SetupServiceLogging() { // Setup logging. log.SetOutput(os.Stdout) - log.SetLevel(log.InfoLevel) + level, err := log.ParseLevel(viper.GetString("log_level")) + if err != nil { + log.WithError(err).Fatal("Flag --log_level or ENV PL_LOG_LEVEL is invalid") + } + log.SetLevel(level) } // HTTPLoggingMiddleware is a middleware function used for logging HTTP requests. diff --git a/src/shared/services/logging_test.go b/src/shared/services/logging_test.go new file mode 100644 index 00000000000..8e7dbbb85d9 --- /dev/null +++ b/src/shared/services/logging_test.go @@ -0,0 +1,97 @@ +/* + * Copyright 2018- The Pixie Authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package services + +import ( + "testing" + + log "github.com/sirupsen/logrus" + "github.com/spf13/pflag" + "github.com/spf13/viper" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestSetupServiceLogging(t *testing.T) { + SetupCommonFlags() + + tests := []struct { + name string + logLevel string + expectedLevel log.Level + }{ + { + name: "default", + logLevel: "", + expectedLevel: log.InfoLevel, + }, + { + name: "debug", + logLevel: "debug", + expectedLevel: log.DebugLevel, + }, + { + name: "error", + logLevel: "error", + expectedLevel: log.ErrorLevel, + }, + { + name: "case insensitive", + logLevel: "WARN", + expectedLevel: log.WarnLevel, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + origLevel := log.GetLevel() + t.Cleanup(func() { + viper.Reset() + log.SetLevel(origLevel) + }) + + require.NoError(t, viper.BindPFlag("log_level", pflag.Lookup("log_level"))) + if test.logLevel != "" { + viper.Set("log_level", test.logLevel) + } + + SetupServiceLogging() + assert.Equal(t, test.expectedLevel, log.GetLevel()) + }) + } +} + +func TestSetupServiceLogging_InvalidLevel(t *testing.T) { + origLevel := log.GetLevel() + origExitFunc := log.StandardLogger().ExitFunc + t.Cleanup(func() { + viper.Reset() + log.SetLevel(origLevel) + log.StandardLogger().ExitFunc = origExitFunc + }) + + exitCode := 0 + log.StandardLogger().ExitFunc = func(code int) { + exitCode = code + } + + viper.Set("log_level", "verbose") + SetupServiceLogging() + assert.Equal(t, 1, exitCode) +} diff --git a/src/shared/services/service_flags.go b/src/shared/services/service_flags.go index 26983703ca9..a2d017bb413 100644 --- a/src/shared/services/service_flags.go +++ b/src/shared/services/service_flags.go @@ -51,6 +51,7 @@ func setupCommonFlags() { pflag.String("jwt_signing_key", "", "The signing key used for JWTs") pflag.String("pod_name", "", "The pod name") pflag.Bool("version", false, "Print the version and quit.") + pflag.String("log_level", log.InfoLevel.String(), "The log level. One of: panic, fatal, error, warn, info, debug, trace.") } // SetupCommonFlags sets flags that are used by every service, even non GRPC servers.