Skip to content

Commit d445fa1

Browse files
fix: suppress excessive reaper logging and update reaper query (#832)
This change contains two fixes related to the gram functions reaper. ## fix: suppress logging to user deployment logs This change modifies the function reaping process to reduce noise in user deployment logs by suppressing routine informational messages. ## fix: scope app reaper query to project id This change updates the database query to list reapable fly apps so that it can be scoped to a specific project ID. This allows project-scoped reaping. Previously, the project-scoped reaper was not passing the project ID to the query and it was acting as a global reaper.
1 parent b0875f8 commit d445fa1

File tree

8 files changed

+42
-6
lines changed

8 files changed

+42
-6
lines changed

.changeset/lucky-corners-tie.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"server": patch
3+
---
4+
5+
Modified the function reaping process to reduce noise in user deployment logs by suppressing routine informational messages.

.changeset/weak-beans-retire.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"server": patch
3+
---
4+
5+
Updated the database query to list reapable fly apps so that it can be scoped to a specific project ID. This allows project-scoped reaping. Previously, the project-scoped reaper was not passing the project ID to the query and it was acting as a global reaper.

server/internal/attr/conventions.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ const (
153153
ResourceURIKey = attribute.Key("gram.resource.uri")
154154
ToolsetIDKey = attribute.Key("gram.toolset.id")
155155
ToolsetSlugKey = attribute.Key("gram.toolset.slug")
156+
VisibilityKey = attribute.Key("gram.visibility")
156157

157158
PaginationTsStartKey = attribute.Key("gram.pagination.ts_start")
158159
PaginationTsEndKey = attribute.Key("gram.pagination.ts_end")
@@ -164,6 +165,10 @@ const (
164165
ClickhouseQueryDurationMsKey = attribute.Key("gram.clickhouse.query_duration_ms")
165166
)
166167

168+
const (
169+
VisibilityInternalValue = "internal"
170+
)
171+
167172
func Error(v error) attribute.KeyValue { return ErrorMessageKey.String(v.Error()) }
168173
func SlogError(v error) slog.Attr { return slog.String(string(ErrorMessageKey), v.Error()) }
169174

@@ -627,6 +632,13 @@ func SlogToolCallDuration(v time.Duration) slog.Attr {
627632
return slog.Float64(string(ToolCallDurationKey), v.Seconds())
628633
}
629634

635+
func VisibilityInternal() attribute.KeyValue {
636+
return VisibilityKey.String(VisibilityInternalValue)
637+
}
638+
func SlogVisibilityInternal() slog.Attr {
639+
return slog.String(string(VisibilityKey), VisibilityInternalValue)
640+
}
641+
630642
func PaginationTsStart(v time.Time) attribute.KeyValue {
631643
return PaginationTsStartKey.String(v.Format(time.RFC3339))
632644
}

server/internal/background/activities/reap_functions.go

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,13 +75,14 @@ func (r *ReapFlyApps) Do(ctx context.Context, req ReapFlyAppsRequest) (*ReapFlyA
7575
// Starting with a small batch size for now and we'll increase later on
7676
// after some observation.
7777
BatchSize: pgtype.Int8{Int64: 50, Valid: true},
78+
79+
ProjectID: req.ProjectID,
7880
})
7981
if err != nil {
8082
return nil, oops.E(oops.CodeUnexpected, err, "failed to query apps to reap").Log(ctx, logger)
8183
}
8284

8385
if len(appsToReap) == 0 {
84-
logger.InfoContext(ctx, "no apps to reap")
8586
return &ReapFlyAppsResult{
8687
Reaped: 0,
8788
Errors: 0,
@@ -103,8 +104,6 @@ func (r *ReapFlyApps) Do(ctx context.Context, req ReapFlyAppsRequest) (*ReapFlyA
103104
attr.SlogDeploymentFunctionsID(app.FunctionID.String()),
104105
)
105106

106-
appLogger.InfoContext(ctx, "reaping fly app")
107-
108107
if err := r.deployer.Reap(ctx, functions.ReapRequest{
109108
ProjectID: app.ProjectID,
110109
DeploymentID: app.DeploymentID,
@@ -116,7 +115,7 @@ func (r *ReapFlyApps) Do(ctx context.Context, req ReapFlyAppsRequest) (*ReapFlyA
116115
}
117116

118117
result.Reaped++
119-
appLogger.InfoContext(ctx, "successfully reaped fly app")
118+
appLogger.InfoContext(ctx, "successfully reaped fly app", attr.SlogVisibilityInternal())
120119
}
121120

122121
r.metrics.RecordFlyAppReaperReapCount(ctx, int64(result.Reaped), int64(result.Errors))

server/internal/deployments/events/log.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,13 +53,16 @@ func (l *LogHandler) Enabled(ctx context.Context, level slog.Level) bool {
5353
}
5454

5555
func (l *LogHandler) Handle(ctx context.Context, record slog.Record) error {
56+
internal := false
5657
event := l.attrEvent
5758
projectID := l.attrProjectID
5859
deploymentID := l.attrDeploymentID
5960
openAPIAssetID := l.attrOpenAPIAssetID
6061

6162
record.Attrs(func(a slog.Attr) bool {
6263
switch {
64+
case a.Key == string(attr.VisibilityKey) && a.Value.Kind() == slog.KindString:
65+
internal = a.Value.String() == attr.VisibilityInternalValue
6366
case a.Key == string(attr.EventKey) && a.Value.Kind() == slog.KindString:
6467
event = a.Value.String()
6568
case a.Key == string(attr.ProjectIDKey) && a.Value.Kind() == slog.KindString:
@@ -79,6 +82,10 @@ func (l *LogHandler) Handle(ctx context.Context, record slog.Record) error {
7982
return true
8083
})
8184

85+
if internal {
86+
return nil
87+
}
88+
8289
if event == "" {
8390
event = fmt.Sprintf("log:%s", strings.ToLower(record.Level.String()))
8491
}

server/internal/functions/deploy_fly.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ type FlyRunnerOptions struct {
5757

5858
type FlyRunner struct {
5959
logger *slog.Logger
60+
tracer trace.Tracer
6061
db *pgxpool.Pool
6162
assetStorage assets.BlobStore
6263
client *fly.Client
@@ -116,6 +117,7 @@ func NewFlyRunner(
116117

117118
return &FlyRunner{
118119
logger: logger.With(attr.SlogComponent("flyio-orchestrator")),
120+
tracer: tracerProvider.Tracer("github.com/speakeasy-api/gram/server/internal/functions"),
119121
db: db,
120122
assetStorage: assetStorage,
121123
client: c,
@@ -507,7 +509,11 @@ func (f *FlyRunner) Deploy(ctx context.Context, req RunnerDeployRequest) (res *R
507509
}
508510

509511
func (f *FlyRunner) Reap(ctx context.Context, req ReapRequest) error {
512+
ctx, span := f.tracer.Start(ctx, "FlyRunner.Reap")
513+
defer span.End()
514+
510515
logger := f.logger.With(
516+
attr.SlogVisibilityInternal(),
511517
attr.SlogProjectID(req.ProjectID.String()),
512518
attr.SlogDeploymentID(req.DeploymentID.String()),
513519
attr.SlogDeploymentFunctionsID(req.FunctionID.String()),
@@ -530,7 +536,6 @@ func (f *FlyRunner) reap(ctx context.Context, logger *slog.Logger, appsRepo *rep
530536
})
531537
switch {
532538
case errors.Is(err, sql.ErrNoRows):
533-
logger.InfoContext(ctx, "no existing app found")
534539
return nil
535540
case err != nil:
536541
return fmt.Errorf("get existing app name: %w", err)

server/internal/functions/queries.sql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ WITH ranked_deployments AS (
102102
INNER JOIN deployments d ON d.id = fa.deployment_id
103103
WHERE
104104
fa.status = 'ready'
105+
AND (@project_id::uuid IS NULL OR fa.project_id = @project_id)
105106
AND fa.reaped_at IS NULL
106107
)
107108
SELECT

server/internal/functions/repo/queries.sql.go

Lines changed: 3 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)