From f8d87fffea1be6bd0d10612cf1434ea93e709fce Mon Sep 17 00:00:00 2001 From: Michael 'Flimmy' Flemming Date: Tue, 16 Dec 2025 11:42:12 +0100 Subject: [PATCH 1/3] Change Log Severity from Debug for pipeline or step creation errors --- server/pipeline/create.go | 6 +++--- server/pipeline/stepbuilder/step_builder.go | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/server/pipeline/create.go b/server/pipeline/create.go index 14c648d9b5c..16f66101666 100644 --- a/server/pipeline/create.go +++ b/server/pipeline/create.go @@ -48,7 +48,7 @@ func Create(ctx context.Context, _store store.Store, repo *model.Repo, pipeline if len(ref) == 0 { ref = pipeline.Ref } - log.Debug().Str("repo", repo.FullName).Msgf("ignoring pipeline as skip-ci was found in the commit (%s) message '%s'", ref, pipeline.Message) + log.Info().Str("repo", repo.FullName).Msgf("ignoring pipeline as skip-ci was found in the commit (%s) message '%s'", ref, pipeline.Message) return nil, ErrFiltered } } @@ -80,7 +80,7 @@ func Create(ctx context.Context, _store store.Store, repo *model.Repo, pipeline configService := server.Config.Services.Manager.ConfigServiceFromRepo(repo) forgeYamlConfigs, configFetchErr := configService.Fetch(ctx, _forge, repoUser, repo, pipeline, nil, false) if errors.Is(configFetchErr, &forge_types.ErrConfigNotFound{}) { - log.Debug().Str("repo", repo.FullName).Err(configFetchErr).Msgf("cannot find config '%s' in '%s' with user: '%s'", repo.Config, pipeline.Ref, repoUser.Login) + log.Info().Str("repo", repo.FullName).Err(configFetchErr).Msgf("cannot find config '%s' in '%s' with user: '%s'", repo.Config, pipeline.Ref, repoUser.Login) if err := _store.DeletePipeline(pipeline); err != nil { log.Error().Str("repo", repo.FullName).Err(err).Msg("failed to delete pipeline without config") } @@ -100,7 +100,7 @@ func Create(ctx context.Context, _store store.Store, repo *model.Repo, pipeline } if len(pipelineItems) == 0 { - log.Debug().Str("repo", repo.FullName).Msg(ErrFiltered.Error()) + log.Info().Str("repo", repo.FullName).Msg(ErrFiltered.Error()) if err := _store.DeletePipeline(pipeline); err != nil { log.Error().Str("repo", repo.FullName).Err(err).Msg("failed to delete empty pipeline") } diff --git a/server/pipeline/stepbuilder/step_builder.go b/server/pipeline/stepbuilder/step_builder.go index ab690ee1f95..a2c044b1aff 100644 --- a/server/pipeline/stepbuilder/step_builder.go +++ b/server/pipeline/stepbuilder/step_builder.go @@ -162,7 +162,7 @@ func (b *StepBuilder) genItemForWorkflow(workflow *model.Workflow, axis matrix.A // checking if filtered. if match, err := parsed.When.Match(workflowMetadata, true, environ); !match && err == nil { - log.Debug().Str("pipeline", workflow.Name).Msg( + log.Info().Str("pipeline", workflow.Name).Msg( "marked as skipped, does not match metadata", ) return nil, nil From a2e66d680109c5a082baca8c771110ff681b3d62 Mon Sep 17 00:00:00 2001 From: Michael 'Flimmy' Flemming Date: Wed, 18 Feb 2026 14:58:54 +0100 Subject: [PATCH 2/3] make log level for pipeline skips configurable --- cmd/server/flags.go | 6 ++++++ cmd/server/setup.go | 8 ++++++++ server/config.go | 2 ++ server/pipeline/create.go | 6 +++--- server/pipeline/stepbuilder/step_builder.go | 3 ++- 5 files changed, 21 insertions(+), 4 deletions(-) diff --git a/cmd/server/flags.go b/cmd/server/flags.go index ac5a3fd666f..0e267ea7387 100644 --- a/cmd/server/flags.go +++ b/cmd/server/flags.go @@ -197,6 +197,12 @@ var flags = append([]cli.Flag{ Usage: "The maximum time in minutes you can set in the repo settings before a pipeline gets killed", Value: 120, }, + &cli.StringFlag{ + Sources: cli.EnvVars("WOODPECKER_LOG_LEVEL_PIPELINE_SKIPS"), + Name: "log-level-pipeline-skips", + Usage: "log level for pipeline lifecycle events (skip-ci, filtered, blocked). one of: trace, debug, info, warn, error", + Value: "debug", + }, &cli.StringSliceFlag{ Sources: cli.EnvVars("WOODPECKER_DEFAULT_WORKFLOW_LABELS"), Name: "default-workflow-labels", diff --git a/cmd/server/setup.go b/cmd/server/setup.go index 5728a8b153c..2ae48e159ec 100644 --- a/cmd/server/setup.go +++ b/cmd/server/setup.go @@ -25,6 +25,7 @@ import ( "strings" "time" + "github.com/rs/zerolog" "github.com/rs/zerolog/log" "github.com/tink-crypto/tink-go/v2/subtle/random" "github.com/urfave/cli/v3" @@ -260,6 +261,13 @@ func setupEvilGlobals(ctx context.Context, c *cli.Command, s store.Store) (err e server.Config.WebUI.SkipVersionCheck = c.Bool("skip-version-check") server.Config.Pipeline.PrivilegedPlugins = c.StringSlice("plugins-privileged") + // set log level for pipeline lifecycle events (skip-ci, filtered, blocked) + eventLogLevel, err := zerolog.ParseLevel(c.String("log-level-pipeline-skips")) + if err != nil { + return fmt.Errorf("invalid pipeline-event-log-level: %w", err) + } + server.Config.Pipeline.LogLevelForSkips = eventLogLevel + // prometheus server.Config.Prometheus.AuthToken = c.String("prometheus-auth-token") diff --git a/server/config.go b/server/config.go index 5548c85d0e6..63d387b9115 100644 --- a/server/config.go +++ b/server/config.go @@ -18,6 +18,7 @@ package server import ( "time" + "github.com/rs/zerolog" "go.woodpecker-ci.org/woodpecker/v3/server/cache" "go.woodpecker-ci.org/woodpecker/v3/server/logging" "go.woodpecker-ci.org/woodpecker/v3/server/model" @@ -77,6 +78,7 @@ var Config = struct { PrivilegedPlugins []string DefaultTimeout int64 MaxTimeout int64 + LogLevelForSkips zerolog.Level Proxy struct { No string HTTP string diff --git a/server/pipeline/create.go b/server/pipeline/create.go index 16f66101666..9cc608c5137 100644 --- a/server/pipeline/create.go +++ b/server/pipeline/create.go @@ -48,7 +48,7 @@ func Create(ctx context.Context, _store store.Store, repo *model.Repo, pipeline if len(ref) == 0 { ref = pipeline.Ref } - log.Info().Str("repo", repo.FullName).Msgf("ignoring pipeline as skip-ci was found in the commit (%s) message '%s'", ref, pipeline.Message) + log.WithLevel(server.Config.Pipeline.LogLevelForSkips).Str("repo", repo.FullName).Msgf("ignoring pipeline as skip-ci was found in the commit (%s) message '%s'", ref, pipeline.Message) return nil, ErrFiltered } } @@ -80,7 +80,7 @@ func Create(ctx context.Context, _store store.Store, repo *model.Repo, pipeline configService := server.Config.Services.Manager.ConfigServiceFromRepo(repo) forgeYamlConfigs, configFetchErr := configService.Fetch(ctx, _forge, repoUser, repo, pipeline, nil, false) if errors.Is(configFetchErr, &forge_types.ErrConfigNotFound{}) { - log.Info().Str("repo", repo.FullName).Err(configFetchErr).Msgf("cannot find config '%s' in '%s' with user: '%s'", repo.Config, pipeline.Ref, repoUser.Login) + log.WithLevel(server.Config.Pipeline.LogLevelForSkips).Str("repo", repo.FullName).Err(configFetchErr).Msgf("cannot find config '%s' in '%s' with user: '%s'", repo.Config, pipeline.Ref, repoUser.Login) if err := _store.DeletePipeline(pipeline); err != nil { log.Error().Str("repo", repo.FullName).Err(err).Msg("failed to delete pipeline without config") } @@ -100,7 +100,7 @@ func Create(ctx context.Context, _store store.Store, repo *model.Repo, pipeline } if len(pipelineItems) == 0 { - log.Info().Str("repo", repo.FullName).Msg(ErrFiltered.Error()) + log.WithLevel(server.Config.Pipeline.LogLevelForSkips).Str("repo", repo.FullName).Msg(ErrFiltered.Error()) if err := _store.DeletePipeline(pipeline); err != nil { log.Error().Str("repo", repo.FullName).Err(err).Msg("failed to delete empty pipeline") } diff --git a/server/pipeline/stepbuilder/step_builder.go b/server/pipeline/stepbuilder/step_builder.go index a2c044b1aff..909bb31d61f 100644 --- a/server/pipeline/stepbuilder/step_builder.go +++ b/server/pipeline/stepbuilder/step_builder.go @@ -36,6 +36,7 @@ import ( "go.woodpecker-ci.org/woodpecker/v3/pipeline/frontend/yaml/linter" "go.woodpecker-ci.org/woodpecker/v3/pipeline/frontend/yaml/matrix" yaml_types "go.woodpecker-ci.org/woodpecker/v3/pipeline/frontend/yaml/types" + "go.woodpecker-ci.org/woodpecker/v3/server" forge_types "go.woodpecker-ci.org/woodpecker/v3/server/forge/types" "go.woodpecker-ci.org/woodpecker/v3/server/model" ) @@ -162,7 +163,7 @@ func (b *StepBuilder) genItemForWorkflow(workflow *model.Workflow, axis matrix.A // checking if filtered. if match, err := parsed.When.Match(workflowMetadata, true, environ); !match && err == nil { - log.Info().Str("pipeline", workflow.Name).Msg( + log.WithLevel(server.Config.Pipeline.LogLevelForSkips).Str("pipeline", workflow.Name).Msg( "marked as skipped, does not match metadata", ) return nil, nil From 44e1739eb67408b41afa8c09470eecebfbf583f2 Mon Sep 17 00:00:00 2001 From: Michael 'Flimmy' Flemming Date: Wed, 18 Feb 2026 15:09:18 +0100 Subject: [PATCH 3/3] add docs for the configurable pipeline skips log level --- docs/docs/30-administration/10-configuration/10-server.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/docs/30-administration/10-configuration/10-server.md b/docs/docs/30-administration/10-configuration/10-server.md index 61e67b1091f..48d07f30d5e 100644 --- a/docs/docs/30-administration/10-configuration/10-server.md +++ b/docs/docs/30-administration/10-configuration/10-server.md @@ -858,6 +858,13 @@ The default time for a repo in minutes before a pipeline gets killed The maximum time in minutes you can set in the repo settings before a pipeline gets killed +### LOG_LEVEL_PIPELINE_SKIPS + +- Name: `WOODPECKER_LOG_LEVEL_PIPELINE_SKIPS` +- Default: `debug` + +The log level for pipeline lifecycle events (skip-ci, filtered, blocked). Possible values are `trace`, `debug`, `info`, `warn` and `error` + --- ### SESSION_EXPIRES