From ed3a7e853943317d7d32d623d2c5d4ab8df5756c Mon Sep 17 00:00:00 2001 From: Ben Schumacher Date: Wed, 21 Jan 2026 11:31:05 +0100 Subject: [PATCH] Add trigger field to command execution logs (#34950) Co-authored-by: Claude Opus 4.5 --- server/channels/api4/system.go | 4 ++-- server/channels/app/command.go | 3 ++- server/channels/app/compliance.go | 2 +- server/channels/app/file.go | 4 ++-- server/channels/app/plugin_commands.go | 2 ++ server/channels/app/plugin_requests.go | 4 +--- server/channels/app/post.go | 2 +- server/channels/app/scheduled_post_job.go | 2 +- server/public/shared/request/context.go | 6 ++++++ 9 files changed, 18 insertions(+), 11 deletions(-) diff --git a/server/channels/api4/system.go b/server/channels/api4/system.go index fce0819847e..27084799e10 100644 --- a/server/channels/api4/system.go +++ b/server/channels/api4/system.go @@ -703,7 +703,7 @@ func pushNotificationAck(c *Context, w http.ResponseWriter, r *http.Request) { } } - c.AppContext.WithLogger(c.AppContext.Logger().With( + c.AppContext = c.AppContext.WithLogFields( mlog.String("type", model.NotificationTypePush), mlog.String("ack_id", ack.Id), mlog.String("push_type", ack.NotificationType), @@ -711,7 +711,7 @@ func pushNotificationAck(c *Context, w http.ResponseWriter, r *http.Request) { mlog.String("ack_type", ack.NotificationType), mlog.String("device_type", ack.ClientPlatform), mlog.Int("received_at", ack.ClientReceivedAt), - )) + ) err := c.App.SendAckToPushProxy(c.AppContext, &ack) if ack.IsIdLoaded { if err != nil { diff --git a/server/channels/app/command.go b/server/channels/app/command.go index e7768d1b590..e55013a9ab0 100644 --- a/server/channels/app/command.go +++ b/server/channels/app/command.go @@ -220,6 +220,7 @@ func (a *App) ExecuteCommand(rctx request.CTX, args *model.CommandArgs) (*model. if !strings.HasPrefix(trigger, "/") { return nil, model.NewAppError("command", "api.command.execute_command.format.app_error", map[string]any{"Trigger": trigger}, "", http.StatusBadRequest) } + trigger = strings.TrimPrefix(trigger, "/") clientTriggerId, triggerId, appErr := model.GenerateTriggerId(args.UserId, a.AsymmetricSigningKey()) @@ -470,7 +471,7 @@ func (a *App) tryExecuteCustomCommand(rctx request.CTX, args *model.CommandArgs, return nil, nil, nil } - rctx.Logger().Debug("Executing command", mlog.String("command", trigger), mlog.String("user_id", args.UserId)) + rctx = rctx.WithLogFields(mlog.String("command_id", cmd.Id)) p := url.Values{} p.Set("token", cmd.Token) diff --git a/server/channels/app/compliance.go b/server/channels/app/compliance.go index 0d35607ae16..03a55582e52 100644 --- a/server/channels/app/compliance.go +++ b/server/channels/app/compliance.go @@ -34,7 +34,7 @@ func (a *App) SaveComplianceReport(rctx request.CTX, job *model.Compliance) (*mo job.Type = model.ComplianceTypeAdhoc - rctx = rctx.WithLogger(rctx.Logger().With(job.LoggerFields()...)) + rctx = rctx.WithLogFields(job.LoggerFields()...) job, err := a.Srv().Store().Compliance().Save(job) if err != nil { diff --git a/server/channels/app/file.go b/server/channels/app/file.go index db07d36b170..f9ec9b5de01 100644 --- a/server/channels/app/file.go +++ b/server/channels/app/file.go @@ -788,11 +788,11 @@ func (a *App) UploadFileX(rctx request.CTX, channelID, name string, input io.Rea o(t) } - rctx = rctx.WithLogger(rctx.Logger().With( + rctx = rctx.WithLogFields( mlog.String("file_name", name), mlog.String("channel_id", channelID), mlog.String("user_id", t.UserId), - )) + ) if *a.Config().FileSettings.DriverName == "" { return nil, t.newAppError("api.file.upload_file.storage.app_error", http.StatusNotImplemented) diff --git a/server/channels/app/plugin_commands.go b/server/channels/app/plugin_commands.go index 980cce30249..3595e85cb84 100644 --- a/server/channels/app/plugin_commands.go +++ b/server/channels/app/plugin_commands.go @@ -137,6 +137,8 @@ func (a *App) tryExecutePluginCommand(rctx request.CTX, args *model.CommandArgs) return nil, nil, nil } + rctx = rctx.WithLogFields(mlog.String("plugin_id", matched.PluginId)) + pluginsEnvironment := a.GetPluginsEnvironment() if pluginsEnvironment == nil { return nil, nil, nil diff --git a/server/channels/app/plugin_requests.go b/server/channels/app/plugin_requests.go index 440bea9c43f..52e25f17aea 100644 --- a/server/channels/app/plugin_requests.go +++ b/server/channels/app/plugin_requests.go @@ -247,9 +247,7 @@ func (ch *Channels) servePluginRequest(w http.ResponseWriter, r *http.Request, h r.Header.Del(model.HeaderAuth) rctx = rctx. - WithLogger(rctx.Logger().With( - mlog.String("user_id", session.UserId), - )). + WithLogFields(mlog.String("user_id", session.UserId)). WithSession(session) // If MFA is required and user has not activated it, treat it as unauthenticated diff --git a/server/channels/app/post.go b/server/channels/app/post.go index 98f0c6d37be..cb5276d11f4 100644 --- a/server/channels/app/post.go +++ b/server/channels/app/post.go @@ -2522,7 +2522,7 @@ func (a *App) SetPostReminder(rctx request.CTX, postID, userID string, targetTim } func (a *App) CheckPostReminders(rctx request.CTX) { - rctx = rctx.WithLogger(rctx.Logger().With(mlog.String("component", "post_reminders"))) + rctx = rctx.WithLogFields(mlog.String("component", "post_reminders")) systemBot, appErr := a.GetSystemBot(rctx) if appErr != nil { rctx.Logger().Error("Failed to get system bot", mlog.Err(appErr)) diff --git a/server/channels/app/scheduled_post_job.go b/server/channels/app/scheduled_post_job.go index f1316b52cfa..e2fa02ebf54 100644 --- a/server/channels/app/scheduled_post_job.go +++ b/server/channels/app/scheduled_post_job.go @@ -23,7 +23,7 @@ const ( ) func (a *App) ProcessScheduledPosts(rctx request.CTX) { - rctx = rctx.WithLogger(rctx.Logger().With(mlog.String("component", "scheduled_post_job"))) + rctx = rctx.WithLogFields(mlog.String("component", "scheduled_post_job")) if !*a.Config().ServiceSettings.ScheduledPosts { return diff --git a/server/public/shared/request/context.go b/server/public/shared/request/context.go index 2450b1aaab3..ab96e180a1d 100644 --- a/server/public/shared/request/context.go +++ b/server/public/shared/request/context.go @@ -168,6 +168,11 @@ func (c *Context) WithLogger(logger mlog.LoggerIFace) CTX { return rctx } +// WithLogFields returns a new context with the given fields added to the logger. +func (c *Context) WithLogFields(fields ...mlog.Field) CTX { + return c.WithLogger(c.logger.With(fields...)) +} + func (c *Context) With(f func(ctx CTX) CTX) CTX { return f(c) } @@ -194,6 +199,7 @@ type CTX interface { WithUserAgent(string) CTX WithAcceptLanguage(string) CTX WithLogger(mlog.LoggerIFace) CTX + WithLogFields(fields ...mlog.Field) CTX WithContext(ctx context.Context) CTX With(func(ctx CTX) CTX) CTX }