Skip to main content

Configuring Logging and Formatters

When you need to adjust the verbosity of a Flyte service or ensure logs are correctly parsed by cloud providers like Google Cloud Platform, you configure the global logger using the logger.Config struct. Flyte uses a centralized logging system built on top of logrus that supports multiple output formats and context-aware logging.

Configuring the Global Logger

To initialize or update the logger configuration programmatically, use the logger.SetConfig function. This updates the global state used by all logging calls in the application.

import (
"context"
"github.com/flyteorg/flyte/v2/flytestdlib/logger"
)

func main() {
ctx := context.Background()

// Configure the logger for production JSON output
err := logger.SetConfig(&logger.Config{
Level: logger.InfoLevel,
IncludeSourceCode: false,
Formatter: logger.FormatterConfig{
Type: logger.FormatterJSON,
},
})
if err != nil {
// Handle configuration error
panic(err)
}

logger.Infof(ctx, "Logger initialized with level: %v", logger.GetConfig().Level)
}

Configuration via YAML

Flyte services typically manage this configuration through a Logger section in their configuration files (e.g., config.yaml):

logger:
level: 4
show-source: false
mute: false
formatter:
type: "json"

Adjusting Log Severity Levels

The logger.Level type defines the minimum severity required for a message to be logged. Flyte defines the following levels in flytestdlib/logger/config.go:

ConstantValueDescription
logger.PanicLevel0Highest severity. Logs the message and then calls panic().
logger.FatalLevel1Logs the message and calls os.Exit(1).
logger.ErrorLevel2Used for errors that require attention.
logger.WarnLevel3Non-critical entries that deserve investigation.
logger.InfoLevel4General operational entries (Default).
logger.DebugLevel5Very verbose logging for development and troubleshooting.

Choosing a Formatter

Flyte supports three primary FormatterType values defined in flytestdlib/logger/config.go:

JSON Formatter (Default)

Sets type: "json". This produces structured logs suitable for most log aggregation systems. It uses ts as the timestamp key and disables HTML escaping by default.

Text Formatter

Sets type: "text". This produces human-readable logs, which is useful during local development.

GCP Formatter

Sets type: "gcp". This uses the GcpFormatter class to produce logs compatible with GCP Stackdriver/Cloud Logging. It maps Flyte log levels to specific GcpSeverity strings:

// Mapping found in flytestdlib/logger/gcp_formatter.go
var logrusToGcp = map[logrus.Level]GcpSeverity{
logrus.DebugLevel: GcpSeverityDebug, // "DEBUG"
logrus.InfoLevel: GcpSeverityInfo, // "INFO"
logrus.WarnLevel: GcpSeverityWarning, // "WARNING"
logrus.ErrorLevel: GcpSeverityError, // "ERROR"
logrus.FatalLevel: GcpSeverityCritical, // "CRITICAL"
logrus.PanicLevel: GcpSeverityAlert, // "ALERT"
}

Performance and Debugging Options

Including Source Code Location

Setting IncludeSourceCode: true (or show-source: true in YAML) adds a src field to every log entry containing the file and line number (e.g., config_test.go:25).

Warning: This feature uses runtime.Caller(3) to determine the call site. This incurs a performance penalty and is only recommended for debug or development builds.

Muting Logs

The Mute field in logger.Config allows you to suppress all log output, including panics.

cfg := &logger.Config{
Mute: true, // Suppresses all output
}

Warning: This is intended primarily for benchmarks and unit tests. Using this in production will prevent any error visibility, including critical system panics.

Context-Aware Logging

Once configured, use the context-aware functions to ensure log fields stored in the context.Context (such as request IDs) are included in the output.

func Process(ctx context.Context) {
// Standard info log
logger.Info(ctx, "Starting process")

// Formatted error log
if err := doWork(); err != nil {
logger.Errorf(ctx, "Process failed: %v", err)
}
}

These functions retrieve the current configuration via logger.GetConfig() and check logger.IsLoggable() before dispatching to the underlying logrus.StandardLogger().