mirror of
https://github.com/andwati/zitadel.git
synced 2026-10-18 05:52:51 +00:00
feat(logging): add streams (#11435)
# Which Problems Are Solved Streams allow differentiating logs produced by different components of Zitadel. # How the Problems Are Solved The `backend/v3/instrumentation/logging` package now exposes convenience function for setting and getting a logger from the context. As well as high-level functions to emit log records at various levels. When constructing a new logger a "stream" needs to be specified: - **runtime**: General runtime logs, such as startup and shutdown messages. Default for logs that do not belong to the other categories. - **request**: Logs for incoming API and HTTP requests. - **event_handler**: Logs for event handling in projections. - **queue**: Logs for the job queue processing. - **event_pusher**: Logs for event pushing to the database. Disabled by default, contains sensitive information. Each line from the returned logger contains a `stream` field as well as a `version` field with the current Zitadel version. ## Runtime config Streams can be enabled by passing an array of stream names in the runtime config. Because some log streams may contain sensitive data (especially events), it is now also possible to mask values by their key. # Additional Changes - Wrap `slogctx` in the `logging` package. (Except API error converter packages, because of import cycle) - Add some docs to `logging` package so other devs understand how to add logging to Zitadel - Add `logging.OnError` and `logging.WithError` helper functions with `Panic()` and `Fatal()` methods, to preserve current calls in the `cmd` packages. - Add instance context extractor. - Only output request details in the request info log. Request ID remains propagated through context. - Moved middleware functionality into protocol specific packages. - Removed setting of URI to context in metric middleware. There were ony setters and no getters. (Unused value) - Reuse a single statusWriter in the middleware package for middlewares that need to know the response status. # Additional Context - Closes #11333 - Closes #11331 - Partly #11330 --------- Co-authored-by: Silvan <[email protected]>
This commit is contained in:
+13
-12
@@ -7,8 +7,8 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/cockroachdb/cockroach-go/v2/crdb"
|
||||
"github.com/zitadel/logging"
|
||||
|
||||
"github.com/zitadel/zitadel/backend/v3/instrumentation/logging"
|
||||
"github.com/zitadel/zitadel/internal/database"
|
||||
"github.com/zitadel/zitadel/internal/eventstore"
|
||||
)
|
||||
@@ -36,38 +36,39 @@ func (mig *CorrectCreationDate) Execute(ctx context.Context, _ eventstore.Event)
|
||||
defer cancel()
|
||||
|
||||
for i := 0; ; i++ {
|
||||
logging.WithFields("mig", mig.String(), "iteration", i).Debug("start iteration")
|
||||
logCtx := logging.With(ctx, "mig", mig.String(), "iteration", i)
|
||||
logging.Info(logCtx, "start iteration")
|
||||
var affected int64
|
||||
err = crdb.ExecuteTx(ctx, mig.dbClient.DB, nil, func(tx *sql.Tx) error {
|
||||
_, err := tx.ExecContext(ctx, correctCreationDate10CreateTable)
|
||||
err = crdb.ExecuteTx(logCtx, mig.dbClient.DB, nil, func(tx *sql.Tx) error {
|
||||
_, err := tx.ExecContext(logCtx, correctCreationDate10CreateTable)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
logging.WithFields("mig", mig.String(), "iteration", i).Debug("temp table created")
|
||||
logging.Debug(logCtx, "temp table created")
|
||||
|
||||
_, err = tx.ExecContext(ctx, correctCreationDate10Truncate)
|
||||
_, err = tx.ExecContext(logCtx, correctCreationDate10Truncate)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = tx.ExecContext(ctx, correctCreationDate10FillTable)
|
||||
_, err = tx.ExecContext(logCtx, correctCreationDate10FillTable)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
logging.WithFields("mig", mig.String(), "iteration", i).Debug("temp table filled")
|
||||
logging.Debug(logCtx, "temp table filled")
|
||||
|
||||
res := tx.QueryRowContext(ctx, correctCreationDate10CountWrongEvents)
|
||||
res := tx.QueryRowContext(logCtx, correctCreationDate10CountWrongEvents)
|
||||
if err := res.Scan(&affected); err != nil || affected == 0 {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = tx.ExecContext(ctx, correctCreationDate10Update)
|
||||
_, err = tx.ExecContext(logCtx, correctCreationDate10Update)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
logging.WithFields("mig", mig.String(), "iteration", i, "count", affected).Debug("creation dates updated")
|
||||
logging.Debug(logCtx, "creation dates updated")
|
||||
return nil
|
||||
})
|
||||
logging.WithFields("mig", mig.String(), "iteration", i).Debug("end iteration")
|
||||
logging.Debug(logCtx, "end iteration")
|
||||
if affected == 0 || err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
+2
-2
@@ -8,8 +8,8 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/jackc/pgx/v5/pgconn"
|
||||
"github.com/zitadel/logging"
|
||||
|
||||
"github.com/zitadel/zitadel/backend/v3/instrumentation/logging"
|
||||
"github.com/zitadel/zitadel/internal/database"
|
||||
"github.com/zitadel/zitadel/internal/eventstore"
|
||||
)
|
||||
@@ -45,7 +45,7 @@ func (mig *NewEventsTable) Execute(ctx context.Context, _ eventstore.Event) erro
|
||||
}
|
||||
for _, stmt := range statements {
|
||||
stmt.query = strings.ReplaceAll(stmt.query, "{{.username}}", mig.dbClient.Username())
|
||||
logging.WithFields("file", stmt.file, "migration", mig.String()).Info("execute statement")
|
||||
logging.Info(ctx, "execute statement", "file", stmt.file, "migration", mig.String())
|
||||
_, err = mig.dbClient.ExecContext(ctx, stmt.query)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
+2
-3
@@ -4,8 +4,7 @@ import (
|
||||
"context"
|
||||
"embed"
|
||||
|
||||
"github.com/zitadel/logging"
|
||||
|
||||
"github.com/zitadel/zitadel/backend/v3/instrumentation/logging"
|
||||
"github.com/zitadel/zitadel/internal/database"
|
||||
"github.com/zitadel/zitadel/internal/eventstore"
|
||||
)
|
||||
@@ -25,7 +24,7 @@ func (mig *CurrentProjectionState) Execute(ctx context.Context, _ eventstore.Eve
|
||||
return err
|
||||
}
|
||||
for _, stmt := range statements {
|
||||
logging.WithFields("file", stmt.file, "migration", mig.String()).Info("execute statement")
|
||||
logging.Info(ctx, "execute statement", "file", stmt.file, "migration", mig.String())
|
||||
_, err = mig.dbClient.ExecContext(ctx, stmt.query)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
+2
-3
@@ -4,8 +4,7 @@ import (
|
||||
"context"
|
||||
_ "embed"
|
||||
|
||||
"github.com/zitadel/logging"
|
||||
|
||||
"github.com/zitadel/zitadel/backend/v3/instrumentation/logging"
|
||||
"github.com/zitadel/zitadel/internal/database"
|
||||
"github.com/zitadel/zitadel/internal/eventstore"
|
||||
)
|
||||
@@ -25,7 +24,7 @@ func (mig *UniqueConstraintToLower) Execute(ctx context.Context, _ eventstore.Ev
|
||||
return err
|
||||
}
|
||||
count, err := res.RowsAffected()
|
||||
logging.WithFields("count", count).Info("unique constraints updated")
|
||||
logging.Info(ctx, "unique constraints updated", "count", count)
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
+2
-3
@@ -5,8 +5,7 @@ import (
|
||||
"embed"
|
||||
"fmt"
|
||||
|
||||
"github.com/zitadel/logging"
|
||||
|
||||
"github.com/zitadel/zitadel/backend/v3/instrumentation/logging"
|
||||
"github.com/zitadel/zitadel/internal/database"
|
||||
"github.com/zitadel/zitadel/internal/eventstore"
|
||||
)
|
||||
@@ -26,7 +25,7 @@ func (mig *AddPositionToIndexEsWm) Execute(ctx context.Context, _ eventstore.Eve
|
||||
return err
|
||||
}
|
||||
for _, stmt := range statements {
|
||||
logging.WithFields("file", stmt.file, "migration", mig.String()).Info("execute statement")
|
||||
logging.Info(ctx, "execute statement", "file", stmt.file, "migration", mig.String())
|
||||
if _, err := mig.dbClient.ExecContext(ctx, stmt.query); err != nil {
|
||||
return fmt.Errorf("%s %s: %w", mig.String(), stmt.file, err)
|
||||
}
|
||||
|
||||
+6
-5
@@ -10,8 +10,8 @@ import (
|
||||
|
||||
"github.com/jackc/pgx/v5"
|
||||
"github.com/jackc/pgx/v5/pgconn"
|
||||
"github.com/zitadel/logging"
|
||||
|
||||
"github.com/zitadel/zitadel/backend/v3/instrumentation/logging"
|
||||
"github.com/zitadel/zitadel/internal/command"
|
||||
"github.com/zitadel/zitadel/internal/database"
|
||||
"github.com/zitadel/zitadel/internal/eventstore"
|
||||
@@ -82,19 +82,20 @@ func (mig *FillV3Milestones) pushEventsByInstance(ctx context.Context, milestone
|
||||
slices.Sort(order)
|
||||
|
||||
for i, instanceID := range order {
|
||||
logging.WithFields("instance_id", instanceID, "migration", mig.String(), "progress", fmt.Sprintf("%d/%d", i+1, len(order))).Info("filter existing milestone events")
|
||||
logCtx := logging.With(ctx, "instance", instanceID, "migration", mig.String())
|
||||
logging.Info(logCtx, "filter existing milestone events", "progress", fmt.Sprintf("%d/%d", i+1, len(order)))
|
||||
|
||||
// because each Push runs in a separate TX, we need to make sure that events
|
||||
// from a partially executed migration are pushed again.
|
||||
model := command.NewMilestonesReachedWriteModel(instanceID)
|
||||
if err := mig.eventstore.FilterToQueryReducer(ctx, model); err != nil {
|
||||
if err := mig.eventstore.FilterToQueryReducer(logCtx, model); err != nil {
|
||||
return fmt.Errorf("milestones filter: %w", err)
|
||||
}
|
||||
if model.InstanceCreated {
|
||||
logging.WithFields("instance_id", instanceID, "migration", mig.String()).Info("milestone events already migrated")
|
||||
logging.Info(logCtx, "milestone events already migrated")
|
||||
continue // This instance was migrated, skip
|
||||
}
|
||||
logging.WithFields("instance_id", instanceID, "migration", mig.String()).Info("push milestone events")
|
||||
logging.Info(logCtx, "push milestone events")
|
||||
|
||||
aggregate := milestone.NewInstanceAggregate(instanceID)
|
||||
|
||||
|
||||
+2
-3
@@ -5,8 +5,7 @@ import (
|
||||
_ "embed"
|
||||
"fmt"
|
||||
|
||||
"github.com/zitadel/logging"
|
||||
|
||||
"github.com/zitadel/zitadel/backend/v3/instrumentation/logging"
|
||||
"github.com/zitadel/zitadel/internal/eventstore"
|
||||
"github.com/zitadel/zitadel/internal/repository/instance"
|
||||
)
|
||||
@@ -34,7 +33,7 @@ func (mig *DeleteStaleOrgFields) Execute(ctx context.Context, _ eventstore.Event
|
||||
return err
|
||||
}
|
||||
for i, instance := range instances {
|
||||
logging.WithFields("instance_id", instance, "migration", mig.String(), "progress", fmt.Sprintf("%d/%d", i+1, len(instances))).Info("execute delete query")
|
||||
logging.Info(ctx, "execute delete query", "instance", instance, "migration", mig.String(), "progress", fmt.Sprintf("%d/%d", i+1, len(instances)))
|
||||
if _, err := mig.eventstore.Client().ExecContext(ctx, deleteStaleOrgFields, instance); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
+3
-4
@@ -10,8 +10,7 @@ import (
|
||||
"strings"
|
||||
"text/template"
|
||||
|
||||
"github.com/zitadel/logging"
|
||||
|
||||
"github.com/zitadel/zitadel/backend/v3/instrumentation/logging"
|
||||
"github.com/zitadel/zitadel/internal/database"
|
||||
"github.com/zitadel/zitadel/internal/eventstore"
|
||||
)
|
||||
@@ -39,7 +38,7 @@ func (mig *InitPushFunc) Execute(ctx context.Context, _ eventstore.Event) (err e
|
||||
}
|
||||
defer func() {
|
||||
closeErr := conn.Close()
|
||||
logging.OnError(closeErr).Debug("failed to release connection")
|
||||
logging.OnError(ctx, closeErr).Debug("failed to release connection")
|
||||
// Force the pool to reopen connections to apply the new types
|
||||
mig.dbClient.Pool.Reset()
|
||||
}()
|
||||
@@ -48,7 +47,7 @@ func (mig *InitPushFunc) Execute(ctx context.Context, _ eventstore.Event) (err e
|
||||
return err
|
||||
}
|
||||
for _, stmt := range statements {
|
||||
logging.WithFields("file", stmt.file, "migration", mig.String()).Info("execute statement")
|
||||
logging.Info(ctx, "execute statement", "file", stmt.file, "migration", mig.String())
|
||||
if _, err := conn.ExecContext(ctx, stmt.query); err != nil {
|
||||
return fmt.Errorf("%s %s: %w", mig.String(), stmt.file, err)
|
||||
}
|
||||
|
||||
+2
-3
@@ -5,8 +5,7 @@ import (
|
||||
"embed"
|
||||
"fmt"
|
||||
|
||||
"github.com/zitadel/logging"
|
||||
|
||||
"github.com/zitadel/zitadel/backend/v3/instrumentation/logging"
|
||||
"github.com/zitadel/zitadel/internal/database"
|
||||
"github.com/zitadel/zitadel/internal/eventstore"
|
||||
)
|
||||
@@ -26,7 +25,7 @@ func (mig *CreateFieldsDomainIndex) Execute(ctx context.Context, _ eventstore.Ev
|
||||
return err
|
||||
}
|
||||
for _, stmt := range statements {
|
||||
logging.WithFields("file", stmt.file, "migration", mig.String()).Info("execute statement")
|
||||
logging.Info(ctx, "execute statement", "file", stmt.file, "migration", mig.String())
|
||||
if _, err := mig.dbClient.ExecContext(ctx, stmt.query); err != nil {
|
||||
return fmt.Errorf("%s %s: %w", mig.String(), stmt.file, err)
|
||||
}
|
||||
|
||||
+2
-3
@@ -5,8 +5,7 @@ import (
|
||||
"embed"
|
||||
"fmt"
|
||||
|
||||
"github.com/zitadel/logging"
|
||||
|
||||
"github.com/zitadel/zitadel/backend/v3/instrumentation/logging"
|
||||
"github.com/zitadel/zitadel/internal/database"
|
||||
"github.com/zitadel/zitadel/internal/eventstore"
|
||||
)
|
||||
@@ -26,7 +25,7 @@ func (mig *ReplaceCurrentSequencesIndex) Execute(ctx context.Context, _ eventsto
|
||||
return err
|
||||
}
|
||||
for _, stmt := range statements {
|
||||
logging.WithFields("file", stmt.file, "migration", mig.String()).Info("execute statement")
|
||||
logging.Info(ctx, "execute statement", "file", stmt.file, "migration", mig.String())
|
||||
if _, err := mig.dbClient.ExecContext(ctx, stmt.query); err != nil {
|
||||
return fmt.Errorf("%s %s: %w", mig.String(), stmt.file, err)
|
||||
}
|
||||
|
||||
+3
-4
@@ -6,8 +6,7 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/zitadel/logging"
|
||||
|
||||
"github.com/zitadel/zitadel/backend/v3/instrumentation/logging"
|
||||
"github.com/zitadel/zitadel/internal/api/authz"
|
||||
"github.com/zitadel/zitadel/internal/eventstore"
|
||||
"github.com/zitadel/zitadel/internal/query/projection"
|
||||
@@ -42,7 +41,7 @@ func (mig *CorrectProjectOwners) Execute(ctx context.Context, _ eventstore.Event
|
||||
ctx = authz.SetCtxData(ctx, authz.CtxData{UserID: "SETUP"})
|
||||
for i, instance := range instances {
|
||||
ctx = authz.WithInstanceID(ctx, instance)
|
||||
logging.WithFields("instance_id", instance, "migration", mig.String(), "progress", fmt.Sprintf("%d/%d", i+1, len(instances))).Info("correct owners of projects")
|
||||
logging.Info(ctx, "correct owners of projects", "instance", instance, "migration", mig.String(), "progress", fmt.Sprintf("%d/%d", i+1, len(instances)))
|
||||
didCorrect, err := mig.correctInstanceProjects(ctx, instance)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -51,7 +50,7 @@ func (mig *CorrectProjectOwners) Execute(ctx context.Context, _ eventstore.Event
|
||||
continue
|
||||
}
|
||||
_, err = projection.ProjectGrantProjection.Trigger(ctx)
|
||||
logging.OnError(err).Debug("failed triggering project grant projection to update owners")
|
||||
logging.OnError(ctx, err).Debug("failed triggering project grant projection to update owners")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
+2
-3
@@ -5,8 +5,7 @@ import (
|
||||
"embed"
|
||||
"fmt"
|
||||
|
||||
"github.com/zitadel/logging"
|
||||
|
||||
"github.com/zitadel/zitadel/backend/v3/instrumentation/logging"
|
||||
"github.com/zitadel/zitadel/internal/database"
|
||||
"github.com/zitadel/zitadel/internal/eventstore"
|
||||
)
|
||||
@@ -26,7 +25,7 @@ func (mig *InitPermissionFunctions) Execute(ctx context.Context, _ eventstore.Ev
|
||||
return err
|
||||
}
|
||||
for _, stmt := range statements {
|
||||
logging.WithFields("file", stmt.file, "migration", mig.String()).Info("execute statement")
|
||||
logging.Info(ctx, "execute statement", "file", stmt.file, "migration", mig.String())
|
||||
if _, err := mig.eventstoreClient.ExecContext(ctx, stmt.query); err != nil {
|
||||
return fmt.Errorf("%s %s: %w", mig.String(), stmt.file, err)
|
||||
}
|
||||
|
||||
+2
-3
@@ -5,8 +5,7 @@ import (
|
||||
"embed"
|
||||
"fmt"
|
||||
|
||||
"github.com/zitadel/logging"
|
||||
|
||||
"github.com/zitadel/zitadel/backend/v3/instrumentation/logging"
|
||||
"github.com/zitadel/zitadel/internal/database"
|
||||
"github.com/zitadel/zitadel/internal/eventstore"
|
||||
)
|
||||
@@ -26,7 +25,7 @@ func (mig *InitPermittedOrgsFunction) Execute(ctx context.Context, _ eventstore.
|
||||
return err
|
||||
}
|
||||
for _, stmt := range statements {
|
||||
logging.WithFields("file", stmt.file, "migration", mig.String()).Info("execute statement")
|
||||
logging.Info(ctx, "execute statement", "file", stmt.file, "migration", mig.String())
|
||||
if _, err := mig.eventstoreClient.ExecContext(ctx, stmt.query); err != nil {
|
||||
return fmt.Errorf("%s %s: %w", mig.String(), stmt.file, err)
|
||||
}
|
||||
|
||||
+2
-3
@@ -5,8 +5,7 @@ import (
|
||||
"embed"
|
||||
"fmt"
|
||||
|
||||
"github.com/zitadel/logging"
|
||||
|
||||
"github.com/zitadel/zitadel/backend/v3/instrumentation/logging"
|
||||
"github.com/zitadel/zitadel/internal/database"
|
||||
"github.com/zitadel/zitadel/internal/eventstore"
|
||||
)
|
||||
@@ -24,7 +23,7 @@ func (mig *InitPermittedOrgsFunction53) Execute(ctx context.Context, _ eventstor
|
||||
return err
|
||||
}
|
||||
for _, stmt := range statements {
|
||||
logging.WithFields("file", stmt.file, "migration", mig.String()).Info("execute statement")
|
||||
logging.Info(ctx, "execute statement", "file", stmt.file, "migration", mig.String())
|
||||
if _, err := mig.dbClient.ExecContext(ctx, stmt.query); err != nil {
|
||||
return fmt.Errorf("%s %s: %w", mig.String(), stmt.file, err)
|
||||
}
|
||||
|
||||
+2
-3
@@ -6,8 +6,7 @@ import (
|
||||
"embed"
|
||||
"fmt"
|
||||
|
||||
"github.com/zitadel/logging"
|
||||
|
||||
"github.com/zitadel/zitadel/backend/v3/instrumentation/logging"
|
||||
"github.com/zitadel/zitadel/internal/database"
|
||||
"github.com/zitadel/zitadel/internal/eventstore"
|
||||
)
|
||||
@@ -36,7 +35,7 @@ func (mig *ReplaceLoginNames3View) Execute(ctx context.Context, _ eventstore.Eve
|
||||
return err
|
||||
}
|
||||
for _, stmt := range statements {
|
||||
logging.WithFields("file", stmt.file, "migration", mig.String()).Info("execute statement")
|
||||
logging.Info(ctx, "execute statement", "file", stmt.file, "migration", mig.String())
|
||||
if _, err := mig.dbClient.ExecContext(ctx, stmt.query); err != nil {
|
||||
return fmt.Errorf("%s %s: %w", mig.String(), stmt.file, err)
|
||||
}
|
||||
|
||||
+2
-3
@@ -4,8 +4,7 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/zitadel/logging"
|
||||
|
||||
"github.com/zitadel/zitadel/backend/v3/instrumentation/logging"
|
||||
"github.com/zitadel/zitadel/internal/api/authz"
|
||||
"github.com/zitadel/zitadel/internal/command"
|
||||
"github.com/zitadel/zitadel/internal/crypto"
|
||||
@@ -41,7 +40,7 @@ func (mig *SetupWebkeys) Execute(ctx context.Context, _ eventstore.Event) error
|
||||
|
||||
for _, instance := range instances {
|
||||
ctx := authz.WithInstanceID(ctx, instance)
|
||||
logging.Info("prepare initial webkeys for instance", "instance_id", instance, "migration", mig)
|
||||
logging.Info(ctx, "prepare initial webkeys for instance", "instance", instance, "migration", mig)
|
||||
if err := mig.commands.GenerateInitialWebKeys(ctx, conf); err != nil {
|
||||
return fmt.Errorf("%s generate initial webkeys: %w", mig, err)
|
||||
}
|
||||
|
||||
+24
-14
@@ -3,11 +3,12 @@ package setup
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
"github.com/zitadel/logging"
|
||||
|
||||
"github.com/zitadel/zitadel/backend/v3/instrumentation/logging"
|
||||
"github.com/zitadel/zitadel/internal/database"
|
||||
"github.com/zitadel/zitadel/internal/eventstore"
|
||||
old_es "github.com/zitadel/zitadel/internal/eventstore/repository/sql"
|
||||
@@ -21,39 +22,48 @@ func NewCleanup() *cobra.Command {
|
||||
Short: "cleans up migration if they got stuck",
|
||||
Long: `cleans up migration if they got stuck`,
|
||||
RunE: func(cmd *cobra.Command, args []string) (err error) {
|
||||
config, shutdown, err := NewConfig(cmd.Context(), viper.GetViper())
|
||||
defer func() {
|
||||
logging.OnError(cmd.Context(), err).Error("zitadel setup cleanup command failed")
|
||||
}()
|
||||
config, shutdown, err := NewConfig(cmd, viper.GetViper())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
err = errors.Join(err, shutdown(cmd.Context()))
|
||||
}()
|
||||
Cleanup(cmd.Context(), config)
|
||||
return nil
|
||||
return Cleanup(cmd.Context(), config)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func Cleanup(ctx context.Context, config *Config) {
|
||||
logging.Info("cleanup started")
|
||||
func Cleanup(ctx context.Context, config *Config) error {
|
||||
logging.Info(ctx, "cleanup started")
|
||||
|
||||
dbClient, err := database.Connect(config.Database, false)
|
||||
logging.OnError(err).Fatal("unable to connect to database")
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to connect to database: %w", err)
|
||||
}
|
||||
|
||||
config.Eventstore.Pusher = new_es.NewEventstore(dbClient)
|
||||
config.Eventstore.Querier = old_es.NewPostgres(dbClient)
|
||||
es := eventstore.NewEventstore(config.Eventstore)
|
||||
|
||||
step, err := migration.LastStuckStep(ctx, es)
|
||||
logging.OnError(err).Fatal("unable to query latest migration")
|
||||
|
||||
if step == nil {
|
||||
logging.Info("there is no stuck migration please run `zitadel setup`")
|
||||
return
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to query latest migration: %w", err)
|
||||
}
|
||||
|
||||
logging.WithFields("name", step.Name).Info("cleanup migration")
|
||||
if step == nil {
|
||||
logging.Info(ctx, "there is no stuck migration please run `zitadel setup`")
|
||||
return nil
|
||||
}
|
||||
|
||||
logging.Info(ctx, "cleanup migration", "name", step.Name)
|
||||
|
||||
err = migration.CancelStep(ctx, es, step)
|
||||
logging.OnError(err).Fatal("cleanup migration failed please retry")
|
||||
if err != nil {
|
||||
return fmt.Errorf("cleanup migration failed please retry: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
+18
-10
@@ -9,10 +9,12 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/mitchellh/mapstructure"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
"github.com/zitadel/logging"
|
||||
old_logging "github.com/zitadel/logging" //nolint:staticcheck
|
||||
|
||||
"github.com/zitadel/zitadel/backend/v3/instrumentation"
|
||||
"github.com/zitadel/zitadel/backend/v3/instrumentation/logging"
|
||||
"github.com/zitadel/zitadel/cmd/encryption"
|
||||
"github.com/zitadel/zitadel/cmd/hooks"
|
||||
"github.com/zitadel/zitadel/internal/actions"
|
||||
@@ -44,7 +46,7 @@ type Config struct {
|
||||
ExternalPort uint16
|
||||
ExternalSecure bool
|
||||
Instrumentation instrumentation.Config
|
||||
Log *logging.Config
|
||||
Log *old_logging.Config
|
||||
Metrics *instrumentation.LegacyMetricConfig
|
||||
EncryptionKeys *encryption.EncryptionKeyConfig
|
||||
DefaultInstance command.InstanceSetup
|
||||
@@ -70,7 +72,7 @@ type InitProjections struct {
|
||||
BulkLimit uint64
|
||||
}
|
||||
|
||||
func NewConfig(ctx context.Context, v *viper.Viper) (*Config, instrumentation.ShutdownFunc, error) {
|
||||
func NewConfig(cmd *cobra.Command, v *viper.Viper) (*Config, instrumentation.ShutdownFunc, error) {
|
||||
config := new(Config)
|
||||
err := v.Unmarshal(config,
|
||||
viper.DecodeHook(mapstructure.ComposeDecodeHookFunc(
|
||||
@@ -94,14 +96,16 @@ func NewConfig(ctx context.Context, v *viper.Viper) (*Config, instrumentation.Sh
|
||||
}
|
||||
|
||||
config.Instrumentation.Metric.SetLegacyConfig(config.Metrics)
|
||||
shutdown, err := instrumentation.Start(ctx, config.Instrumentation)
|
||||
config.Instrumentation.Log.SetLegacyConfig(config.Log)
|
||||
shutdown, err := instrumentation.Start(cmd.Context(), config.Instrumentation)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("unable to start instrumentation: %w", err)
|
||||
}
|
||||
cmd.SetContext(logging.NewCtx(cmd.Context(), logging.StreamReady))
|
||||
|
||||
err = config.Log.SetLogger()
|
||||
if err != nil {
|
||||
err = errors.Join(err, shutdown(ctx))
|
||||
err = errors.Join(err, shutdown(cmd.Context()))
|
||||
return nil, nil, fmt.Errorf("unable to set logger: %w", err)
|
||||
}
|
||||
|
||||
@@ -180,18 +184,20 @@ type Steps struct {
|
||||
s69CacheTablesLogged *CacheTablesLogged
|
||||
}
|
||||
|
||||
func MustNewSteps(v *viper.Viper) *Steps {
|
||||
func NewSteps(ctx context.Context, v *viper.Viper) (*Steps, error) {
|
||||
v.AutomaticEnv()
|
||||
v.SetEnvPrefix("ZITADEL")
|
||||
v.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
|
||||
v.SetConfigType("yaml")
|
||||
err := v.ReadConfig(bytes.NewBuffer(defaultSteps))
|
||||
logging.OnError(err).Fatal("unable to read setup steps")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to read default steps: %w", err)
|
||||
}
|
||||
|
||||
for _, file := range stepFiles {
|
||||
v.SetConfigFile(file)
|
||||
err := v.MergeInConfig()
|
||||
logging.WithFields("file", file).OnError(err).Warn("unable to read setup file")
|
||||
logging.OnError(ctx, err).Warn("unable to read setup file", "file", file)
|
||||
}
|
||||
|
||||
steps := new(Steps)
|
||||
@@ -205,6 +211,8 @@ func MustNewSteps(v *viper.Viper) *Steps {
|
||||
mapstructure.TextUnmarshallerHookFunc(),
|
||||
)),
|
||||
)
|
||||
logging.OnError(err).Fatal("unable to read steps")
|
||||
return steps
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to read steps: %w", err)
|
||||
}
|
||||
return steps, nil
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/muhlemmer/gu"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
@@ -238,10 +239,13 @@ Actions:
|
||||
}}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
c := &cobra.Command{}
|
||||
c.SetContext(t.Context())
|
||||
|
||||
v := viper.New()
|
||||
v.SetConfigType("yaml")
|
||||
require.NoError(t, v.ReadConfig(strings.NewReader(tt.args.yaml)))
|
||||
got, _, err := NewConfig(t.Context(), v)
|
||||
got, _, err := NewConfig(c, v)
|
||||
require.NoError(t, err)
|
||||
tt.want(t, got)
|
||||
})
|
||||
|
||||
+38
-38
@@ -6,7 +6,6 @@ import (
|
||||
_ "embed"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
@@ -17,8 +16,8 @@ import (
|
||||
"github.com/jackc/pgx/v5/pgconn"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
"github.com/zitadel/logging"
|
||||
|
||||
"github.com/zitadel/zitadel/backend/v3/instrumentation/logging"
|
||||
"github.com/zitadel/zitadel/cmd/build"
|
||||
"github.com/zitadel/zitadel/cmd/encryption"
|
||||
"github.com/zitadel/zitadel/cmd/key"
|
||||
@@ -64,9 +63,7 @@ Requirements:
|
||||
- postgreSQL`,
|
||||
RunE: func(cmd *cobra.Command, args []string) (err error) {
|
||||
defer func() {
|
||||
if err != nil {
|
||||
slog.Error("zitadel setup command failed", "err", err)
|
||||
}
|
||||
logging.OnError(cmd.Context(), err).Error("zitadel setup command failed")
|
||||
}()
|
||||
|
||||
err = tls.ModeFromFlag(cmd)
|
||||
@@ -84,7 +81,7 @@ Requirements:
|
||||
return fmt.Errorf("unable to bind \"for-mirror\" flag: %w", err)
|
||||
}
|
||||
|
||||
config, shutdown, err := NewConfig(cmd.Context(), viper.GetViper())
|
||||
config, shutdown, err := NewConfig(cmd, viper.GetViper())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -92,15 +89,16 @@ Requirements:
|
||||
err = errors.Join(err, shutdown(cmd.Context()))
|
||||
}()
|
||||
|
||||
steps := MustNewSteps(viper.New())
|
||||
steps, err := NewSteps(cmd.Context(), viper.New())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
masterKey, err := key.MasterKey(cmd)
|
||||
if err != nil {
|
||||
return fmt.Errorf("no master key provided: %w", err)
|
||||
}
|
||||
|
||||
Setup(cmd.Context(), config, steps, masterKey)
|
||||
return nil
|
||||
return Setup(cmd.Context(), config, steps, masterKey)
|
||||
},
|
||||
}
|
||||
|
||||
@@ -127,9 +125,8 @@ func bindForMirror(cmd *cobra.Command) error {
|
||||
return viper.BindPFlag("ForMirror", cmd.Flags().Lookup("for-mirror"))
|
||||
}
|
||||
|
||||
func Setup(ctx context.Context, config *Config, steps *Steps, masterKey string) {
|
||||
logging.Info("setup started")
|
||||
|
||||
func Setup(ctx context.Context, config *Config, steps *Steps, masterKey string) (err error) {
|
||||
logging.Info(ctx, "setup started")
|
||||
var setupErr error
|
||||
ctx, stop := signal.NotifyContext(ctx, os.Interrupt, syscall.SIGTERM)
|
||||
|
||||
@@ -137,15 +134,14 @@ func Setup(ctx context.Context, config *Config, steps *Steps, masterKey string)
|
||||
stop()
|
||||
|
||||
if setupErr == nil {
|
||||
logging.Info("setup completed")
|
||||
logging.Info(ctx, "setup completed")
|
||||
return
|
||||
}
|
||||
|
||||
if setupErr != nil && !errors.Is(setupErr, context.Canceled) {
|
||||
if !errors.Is(setupErr, context.Canceled) {
|
||||
// If Setup failed for some other reason than the context being cancelled,
|
||||
// then this could be a fatal error we should not retry
|
||||
logging.WithFields("error", setupErr).Fatal("setup failed, skipping cleanup")
|
||||
return
|
||||
logging.OnError(ctx, setupErr).Fatal("setup failed, skipping cleanup")
|
||||
}
|
||||
|
||||
// if we're in the middle of long-running setup, run cleanup before exiting
|
||||
@@ -155,12 +151,13 @@ func Setup(ctx context.Context, config *Config, steps *Steps, masterKey string)
|
||||
cleanupCtx, cleanupCancel := context.WithTimeout(context.WithoutCancel(ctx), 10*time.Second)
|
||||
defer cleanupCancel()
|
||||
|
||||
Cleanup(cleanupCtx, config)
|
||||
err = Cleanup(cleanupCtx, config)
|
||||
logging.OnError(ctx, err).Error("setup cleanup failed")
|
||||
}()
|
||||
|
||||
i18n.MustLoadSupportedLanguagesFromDir()
|
||||
dbClient, err := database.Connect(config.Database, false)
|
||||
logging.OnError(err).Fatal("unable to connect to database")
|
||||
logging.OnError(ctx, err).Fatal("unable to connect to database")
|
||||
|
||||
config.Eventstore.Querier = old_es.NewPostgres(dbClient)
|
||||
esV3 := new_es.NewEventstore(dbClient)
|
||||
@@ -168,7 +165,7 @@ func Setup(ctx context.Context, config *Config, steps *Steps, masterKey string)
|
||||
config.Eventstore.Searcher = esV3
|
||||
eventstoreClient := eventstore.NewEventstore(config.Eventstore)
|
||||
|
||||
logging.OnError(err).Fatal("unable to start eventstore")
|
||||
logging.OnError(ctx, err).Fatal("unable to start eventstore")
|
||||
eventstoreV4 := es_v4.NewEventstoreFromOne(es_v4_pg.New(dbClient, &es_v4_pg.Config{
|
||||
MaxRetries: config.Eventstore.MaxRetries,
|
||||
}))
|
||||
@@ -252,7 +249,9 @@ func Setup(ctx context.Context, config *Config, steps *Steps, masterKey string)
|
||||
steps.s69CacheTablesLogged = &CacheTablesLogged{dbClient: dbClient}
|
||||
|
||||
err = projection.Create(ctx, dbClient, eventstoreClient, config.Projections, nil, nil, nil)
|
||||
logging.OnError(err).Fatal("unable to start projections")
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to create projections: %w", err)
|
||||
}
|
||||
|
||||
for _, step := range []migration.Migration{
|
||||
steps.s14NewEventsTable,
|
||||
@@ -383,6 +382,7 @@ func Setup(ctx context.Context, config *Config, steps *Steps, masterKey string)
|
||||
return
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func executeMigration(ctx context.Context, eventstoreClient *eventstore.Eventstore, step migration.Migration, errorMsg string) error {
|
||||
@@ -403,8 +403,8 @@ func executeMigration(ctx context.Context, eventstoreClient *eventstore.Eventsto
|
||||
"hint", pgErr.Hint,
|
||||
)
|
||||
}
|
||||
logging.WithFields(logFields...).WithError(err).Error(errorMsg)
|
||||
return fmt.Errorf("%s: %w", errorMsg, err)
|
||||
logging.WithError(ctx, err).Error(errorMsg, logFields...)
|
||||
return err
|
||||
}
|
||||
|
||||
// readStmt reads a single file from the embedded FS,
|
||||
@@ -455,10 +455,10 @@ func startCommandsQueries(
|
||||
*auth_view.View,
|
||||
) {
|
||||
keyStorage, err := cryptoDB.NewKeyStorage(dbClient, masterKey)
|
||||
logging.OnError(err).Fatal("unable to start key storage")
|
||||
logging.OnError(ctx, err).Fatal("unable to start key storage")
|
||||
|
||||
keys, err := encryption.EnsureEncryptionKeys(ctx, config.EncryptionKeys, keyStorage)
|
||||
logging.OnError(err).Fatal("unable to ensure encryption keys")
|
||||
logging.OnError(ctx, err).Fatal("unable to ensure encryption keys")
|
||||
|
||||
err = projection.Create(
|
||||
ctx,
|
||||
@@ -473,13 +473,13 @@ func startCommandsQueries(
|
||||
keys.SAML,
|
||||
config.SystemAPIUsers,
|
||||
)
|
||||
logging.OnError(err).Fatal("unable to start projections")
|
||||
logging.OnError(ctx, err).Fatal("unable to start projections")
|
||||
|
||||
staticStorage, err := config.AssetStorage.NewStorage(dbClient.DB)
|
||||
logging.OnError(err).Fatal("unable to start asset storage")
|
||||
logging.OnError(ctx, err).Fatal("unable to start asset storage")
|
||||
|
||||
adminView, err := admin_view.StartView(dbClient)
|
||||
logging.OnError(err).Fatal("unable to start admin view")
|
||||
logging.OnError(ctx, err).Fatal("unable to start admin view")
|
||||
admin_handler.Register(ctx,
|
||||
admin_handler.Config{
|
||||
Client: dbClient,
|
||||
@@ -494,7 +494,7 @@ func startCommandsQueries(
|
||||
sessionTokenVerifier := internal_authz.SessionTokenVerifier(keys.OIDC)
|
||||
|
||||
cacheConnectors, err := connector.StartConnectors(config.Caches, dbClient)
|
||||
logging.OnError(err).Fatal("unable to start caches")
|
||||
logging.OnError(ctx, err).Fatal("unable to start caches")
|
||||
|
||||
queries, err := query.StartQueries(
|
||||
ctx,
|
||||
@@ -523,10 +523,10 @@ func startCommandsQueries(
|
||||
nil, // not needed for projections
|
||||
false,
|
||||
)
|
||||
logging.OnError(err).Fatal("unable to start queries")
|
||||
logging.OnError(ctx, err).Fatal("unable to start queries")
|
||||
|
||||
authView, err := auth_view.StartView(dbClient, keys.OIDC, queries, eventstoreClient)
|
||||
logging.OnError(err).Fatal("unable to start admin view")
|
||||
logging.OnError(ctx, err).Fatal("unable to start auth view")
|
||||
auth_handler.Register(ctx,
|
||||
auth_handler.Config{
|
||||
Client: dbClient,
|
||||
@@ -539,7 +539,7 @@ func startCommandsQueries(
|
||||
)
|
||||
|
||||
authZRepo, err := authz.Start(queries, eventstoreClient, dbClient, keys.OIDC, config.ExternalSecure)
|
||||
logging.OnError(err).Fatal("unable to start authz repo")
|
||||
logging.OnError(ctx, err).Fatal("unable to start authz repo")
|
||||
permissionCheck := func(ctx context.Context, permission, orgID, resourceID string) (err error) {
|
||||
return internal_authz.CheckPermission(ctx, authZRepo, config.SystemAuthZ.RolePermissionMappings, config.InternalAuthZ.RolePermissionMappings, permission, orgID, resourceID)
|
||||
}
|
||||
@@ -577,12 +577,12 @@ func startCommandsQueries(
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
logging.OnError(err).Fatal("unable to start commands")
|
||||
logging.OnError(ctx, err).Fatal("unable to start commands")
|
||||
|
||||
q, err := queue.NewQueue(&queue.Config{
|
||||
Client: dbClient,
|
||||
})
|
||||
logging.OnError(err).Fatal("unable to init queue")
|
||||
logging.OnError(ctx, err).Fatal("unable to init queue")
|
||||
|
||||
notify_handler.Register(
|
||||
ctx,
|
||||
@@ -616,28 +616,28 @@ func initProjections(
|
||||
) error {
|
||||
for _, p := range projection.Projections() {
|
||||
if err := migration.Migrate(ctx, eventstoreClient, p); err != nil {
|
||||
logging.WithFields("name", p.String()).OnError(err).Error("projection migration failed")
|
||||
logging.WithError(ctx, err).Error("projection migration failed", "name", p.String())
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
for _, p := range admin_handler.Projections() {
|
||||
if err := migration.Migrate(ctx, eventstoreClient, p); err != nil {
|
||||
logging.WithFields("name", p.String()).OnError(err).Error("admin schema migration failed")
|
||||
logging.WithError(ctx, err).Error("admin schema migration failed", "name", p.String())
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
for _, p := range auth_handler.Projections() {
|
||||
if err := migration.Migrate(ctx, eventstoreClient, p); err != nil {
|
||||
logging.WithFields("name", p.String()).OnError(err).Error("auth schema migration failed")
|
||||
logging.WithError(ctx, err).Error("auth schema migration failed", "name", p.String())
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
for _, p := range notify_handler.Projections() {
|
||||
if err := migration.Migrate(ctx, eventstoreClient, p); err != nil {
|
||||
logging.WithFields("name", p.String()).OnError(err).Error("notification migration failed")
|
||||
logging.WithError(ctx, err).Error("notification migration failed", "name", p.String())
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
+52
-24
@@ -12,11 +12,11 @@ Instrumentation:
|
||||
# "stdErr": Exports traces to standard error
|
||||
# "grpc": Exports traces using the OTEL gRPC exporter (recommended)
|
||||
# "http": Exports traces using the OTEL HTTP exporter
|
||||
# "google": Exports traces to Google Cloud Trace
|
||||
# "google": Exports traces to Google Cloud. Need to configure GoogleProjectID below!
|
||||
Type: "none" # ZITADEL_INSTRUMENTATION_TRACE_EXPORTER_TYPE
|
||||
# Endpoint of the OTEL collector for grpc and http exporters
|
||||
Endpoint: "" # ZITADEL_INSTRUMENTATION_TRACE_EXPORTER_ENDPOINT
|
||||
# Disable https for grpc and http exporters
|
||||
# Disable TLS for grpc and http exporters
|
||||
Insecure: false # ZITADEL_INSTRUMENTATION_TRACE_EXPORTER_INSECURE
|
||||
# Interval for batching traces before export
|
||||
BatchDuration: 1s # ZITADEL_INSTRUMENTATION_TRACE_EXPORTER_BATCHDURATION
|
||||
@@ -30,15 +30,15 @@ Instrumentation:
|
||||
# "stdErr": Exports metrics to standard error
|
||||
# "grpc": Exports metrics using the OTEL gRPC exporter (recommended)
|
||||
# "http": Exports metrics using the OTEL HTTP exporter
|
||||
# "google": Exports metrics to Google Cloud Trace
|
||||
# "google": Exports metrics to Google Cloud. Need to configure GoogleProjectID below!
|
||||
# "prometheus": Exposes metrics via an HTTP endpoint for Prometheus to scrape
|
||||
Type: "none" # ZITADEL_INSTRUMENTATION_METRIC_EXPORTER_TYPE
|
||||
# Endpoint of the OTEL collector for grpc and http exporters
|
||||
Endpoint: "" # ZITADEL_INSTRUMENTATION_METRIC_EXPORTER_ENDPOINT
|
||||
# Disable https for grpc and http exporters
|
||||
# Disable TLS for grpc and http exporters
|
||||
Insecure: false # ZITADEL_INSTRUMENTATION_METRIC_EXPORTER_INSECURE
|
||||
# Interval at which metrics are exported
|
||||
BatchDuration: 1s # ZITADEL_INSTRUMENTATION_METRIC_EXPORTER_BATCHDURATION
|
||||
BatchDuration: 1m # ZITADEL_INSTRUMENTATION_METRIC_EXPORTER_BATCHDURATION
|
||||
# Project ID for Google Cloud Trace exporter
|
||||
GoogleProjectID: "" # ZITADEL_INSTRUMENTATION_METRIC_EXPORTER_GOOGLEPROJECTID
|
||||
|
||||
@@ -46,39 +46,67 @@ Instrumentation:
|
||||
Log:
|
||||
# Log lines lower than this level are not emitted.
|
||||
Level: "INFO" # ZITADEL_INSTRUMENTATION_LOG_LEVEL
|
||||
# Streams enable logging for specific parts of the application.
|
||||
Streams: # ZITADEL_INSTRUMENTATION_LOG_STREAMS (comma separated list)
|
||||
- runtime # General runtime logs, such as startup and shutdown messages.
|
||||
- request # Logs for incoming API and HTTP requests.
|
||||
- event_handler # Logs for event handling in projections.
|
||||
- queue # Logs for the job queue processing.
|
||||
# - event_pusher # Logs for event pushing to the database. Warning: contains sensitive information.
|
||||
# Mask replaces sensitive information with Value in logs matched by Key
|
||||
Mask:
|
||||
# Keys are the attribute keys to be masked in logs.
|
||||
# Keys are unqualified attribute names and apply to all attributes with the specified name,
|
||||
# regardless of their position in the attribute hierarchy.
|
||||
# Eg. "some_key" matches "some_key" and "parent.some_key" etc.
|
||||
# If the matched log attribute is a nested object or array,
|
||||
# the entire structure is replaced with the specified Value.
|
||||
Keys: # ZITADEL_INSTRUMENTATION_LOG_MASK_KEYS (comma separated list)
|
||||
# - "first_name"
|
||||
# - "last_name"
|
||||
# Value is the string that replaces the original value of masked attributes.
|
||||
Value: "****" # ZITADEL_INSTRUMENTATION_LOG_MASK_VALUE
|
||||
# Enable printing structured logs to standard error in the specified format.
|
||||
# When disabled, the legacy Log configuration is used.
|
||||
# Important: when legacy Log is customized, please add a format and customize before upgrading to v5
|
||||
# The following formats are supported:
|
||||
# - "disabled": Disables logging to standard error
|
||||
# - "text": Logs are printed as human-readable text
|
||||
# - "json": Logs are printed as JSON objects
|
||||
# - "gcp": JSON formatted logs compatible with Google Cloud Platform logging
|
||||
StdErr: "text" # ZITADEL_INSTRUMENTATION_LOG_STDERR
|
||||
# - "disabled": Disables logging (or fallback to legacy Log config)
|
||||
# - "text": Logs are printed on StdErr as human-readable text
|
||||
# - "json": Logs are printed on StdErr as JSON objects
|
||||
# - "gcp": JSON formatted logs compatible with Google Cloud Platform logging.
|
||||
# - "gcp_error_reporting": JSON formatted logs compatible with Google Cloud Platform Error Reporting.
|
||||
Format: "disabled" # ZITADEL_INSTRUMENTATION_LOG_STDERR
|
||||
# Adds the source file and line number where the log line was emitted.
|
||||
# Not to be confused with the source of an error.
|
||||
AddSource: true # ZITADEL_INSTRUMENTATION_LOG_ADDSOURCE
|
||||
# Configure how errors are logged.
|
||||
Errors:
|
||||
# Adds the source file, line number and function where the error was created.
|
||||
ReportLocation: true # ZITADEL_INSTRUMENTATION_LOG_ERRORS_REPORTLOCATION
|
||||
# Adds stack traces to logged errors.
|
||||
StackTrace: false # ZITADEL_INSTRUMENTATION_LOG_ERRORS_STACKTRACE
|
||||
Exporter:
|
||||
# The following exporter types are supported:
|
||||
# - "none": Disables log exporting
|
||||
# - "stdOut": Exports logs to standard output
|
||||
# - "stdErr": Exports logs to standard error
|
||||
# - "grpc": Exports logs using the OTEL gRPC exporter (recommended)
|
||||
# - "http": Exports logs using the OTEL HTTP exporter
|
||||
# - "none": Disables OTEL log exporter
|
||||
# - "stdOut": Exports OTEL logs to standard output
|
||||
# - "stdErr": Exports OTEL logs to standard error
|
||||
# - "grpc": Exports OTEL logs using the OTEL gRPC exporter (recommended)
|
||||
# - "http": Exports OTEL logs using the OTEL HTTP exporter
|
||||
Type: "none" # ZITADEL_INSTRUMENTATION_LOG_EXPORTER_TYPE
|
||||
# Endpoint of the OTEL collector for grpc and http exporters
|
||||
Endpoint: "" # ZITADEL_INSTRUMENTATION_LOG_EXPORTER_ENDPOINT
|
||||
# Disable https for grpc and http exporters
|
||||
# Disable TLS for grpc and http exporters
|
||||
Insecure: false # ZITADEL_INSTRUMENTATION_LOG_EXPORTER_INSECURE
|
||||
# Interval at which metrics are exported
|
||||
BatchDuration: 1s # ZITADEL_INSTRUMENTATION_LOG_EXPORTER_BATCHDURATION
|
||||
# Project ID for Google Cloud Trace exporter
|
||||
GoogleProjectID: "" # ZITADEL_INSTRUMENTATION_LOG_EXPORTER_GOOGLEPROJECTID
|
||||
Profile:
|
||||
# The following profiler types are supported:
|
||||
# "none": Disables profiling
|
||||
# "google": Exports profiling data to Google Cloud Profiler
|
||||
Type: "none" # ZITADEL_INSTRUMENTATION_PROFILE_TYPE
|
||||
# Project ID for Google Cloud Profiler
|
||||
GoogleProjectID: "" # ZITADEL_INSTRUMENTATION_PROFILE_GOOGLEPROJECTID
|
||||
Exporter:
|
||||
# The following profiler types are supported:
|
||||
# "none": Disables profiling
|
||||
# "google": Exports profiling data to Google Cloud Profiler
|
||||
Type: "none" # ZITADEL_INSTRUMENTATION_PROFILE_TYPE
|
||||
# Project ID for Google Cloud Profiler
|
||||
GoogleProjectID: "" # ZITADEL_INSTRUMENTATION_PROFILE_GOOGLEPROJECTID
|
||||
|
||||
# By using the FirstInstance section, you can overwrite the DefaultInstance configuration for the first instance created by zitadel setup.
|
||||
FirstInstance:
|
||||
|
||||
@@ -5,8 +5,7 @@ import (
|
||||
_ "embed"
|
||||
"fmt"
|
||||
|
||||
"github.com/zitadel/logging"
|
||||
|
||||
"github.com/zitadel/zitadel/backend/v3/instrumentation/logging"
|
||||
"github.com/zitadel/zitadel/internal/api/authz"
|
||||
"github.com/zitadel/zitadel/internal/command"
|
||||
"github.com/zitadel/zitadel/internal/eventstore"
|
||||
@@ -23,6 +22,7 @@ type SyncRolePermissions struct {
|
||||
}
|
||||
|
||||
func (mig *SyncRolePermissions) Execute(ctx context.Context, _ eventstore.Event) error {
|
||||
ctx = logging.With(ctx, "migration", mig.String())
|
||||
if err := mig.executeSystem(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -30,12 +30,12 @@ func (mig *SyncRolePermissions) Execute(ctx context.Context, _ eventstore.Event)
|
||||
}
|
||||
|
||||
func (mig *SyncRolePermissions) executeSystem(ctx context.Context) error {
|
||||
logging.WithFields("migration", mig.String()).Info("prepare system role permission sync events")
|
||||
logging.Info(ctx, "prepare system role permission sync events")
|
||||
details, err := mig.commands.SynchronizeRolePermission(ctx, "SYSTEM", mig.rolePermissionMappings)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
logging.WithFields("migration", mig.String(), "sequence", details.Sequence).Info("pushed system role permission sync events")
|
||||
logging.Info(ctx, "pushed system role permission sync events", "sequence", details.Sequence)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -57,12 +57,12 @@ func (mig *SyncRolePermissions) executeInstances(ctx context.Context) error {
|
||||
return err
|
||||
}
|
||||
for i, instanceID := range instances {
|
||||
logging.WithFields("instance_id", instanceID, "migration", mig.String(), "progress", fmt.Sprintf("%d/%d", i+1, len(instances))).Info("prepare instance role permission sync events")
|
||||
logging.Info(ctx, "prepare instance role permission sync events", "instance", instanceID, "progress", fmt.Sprintf("%d/%d", i+1, len(instances)))
|
||||
details, err := mig.commands.SynchronizeRolePermission(ctx, instanceID, mig.rolePermissionMappings)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
logging.WithFields("instance_id", instanceID, "migration", mig.String(), "sequence", details.Sequence).Info("pushed instance role permission sync events")
|
||||
logging.Info(ctx, "pushed instance role permission sync events", "instance", instanceID, "sequence", details.Sequence)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user