Skip to content

Commit 624e367

Browse files
committed
fix: Send startup log EOF and prevent lost messages
1 parent df842b3 commit 624e367

19 files changed

+300
-83
lines changed

agent/agent.go

+13
Original file line numberDiff line numberDiff line change
@@ -929,6 +929,11 @@ func (a *agent) trackScriptLogs(ctx context.Context, reader io.Reader) (chan str
929929
if errors.As(err, &sdkErr) {
930930
if sdkErr.StatusCode() == http.StatusRequestEntityTooLarge {
931931
a.logger.Warn(ctx, "startup logs too large, dropping logs")
932+
// Always send the EOF even if logs overflow.
933+
if len(logsToSend) > 1 && logsToSend[len(logsToSend)-1].EOF {
934+
logsToSend = logsToSend[len(logsToSend)-1:]
935+
continue
936+
}
932937
break
933938
}
934939
}
@@ -978,6 +983,14 @@ func (a *agent) trackScriptLogs(ctx context.Context, reader io.Reader) (chan str
978983
Output: scanner.Text(),
979984
})
980985
}
986+
if err := scanner.Err(); err != nil {
987+
a.logger.Error(ctx, "scan startup logs", slog.Error(err))
988+
}
989+
queueLog(agentsdk.StartupLog{
990+
CreatedAt: database.Now(),
991+
Output: "",
992+
EOF: true,
993+
})
981994
defer close(logsFinished)
982995
logsFlushed.L.Lock()
983996
for {

agent/agent_test.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -905,8 +905,10 @@ func TestAgent_StartupScript(t *testing.T) {
905905
return len(got) > 0 && got[len(got)-1] == codersdk.WorkspaceAgentLifecycleReady
906906
}, testutil.WaitShort, testutil.IntervalMedium)
907907

908-
require.Len(t, client.getStartupLogs(), 1)
908+
require.Len(t, client.getStartupLogs(), 2)
909909
require.Equal(t, output, client.getStartupLogs()[0].Output)
910+
require.False(t, client.getStartupLogs()[0].EOF)
911+
require.True(t, client.getStartupLogs()[1].EOF)
910912
})
911913
// This ensures that even when coderd sends back that the startup
912914
// script has written too many lines it will still succeed!

coderd/apidoc/docs.go

+3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/apidoc/swagger.json

+3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/dbfake/dbfake.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -2722,7 +2722,7 @@ func (q *fakeQuerier) GetWorkspaceAgentStartupLogsAfter(_ context.Context, arg d
27222722
if log.AgentID != arg.AgentID {
27232723
continue
27242724
}
2725-
if arg.CreatedAfter != 0 && log.ID < arg.CreatedAfter {
2725+
if arg.CreatedAfter != 0 && log.ID <= arg.CreatedAfter {
27262726
continue
27272727
}
27282728
logs = append(logs, log)
@@ -4026,6 +4026,7 @@ func (q *fakeQuerier) InsertWorkspaceAgentStartupLogs(_ context.Context, arg dat
40264026
CreatedAt: arg.CreatedAt[index],
40274027
Level: arg.Level[index],
40284028
Output: output,
4029+
EOF: arg.EOF[index],
40294030
})
40304031
outputLength += int32(len(output))
40314032
}

coderd/database/dump.sql

+4-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ALTER TABLE workspace_agent_startup_logs DROP COLUMN eof;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
ALTER TABLE workspace_agent_startup_logs ADD COLUMN eof boolean NOT NULL DEFAULT false;
2+
3+
COMMENT ON COLUMN workspace_agent_startup_logs.eof IS 'End of file reached';

coderd/database/models.go

+2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/querier_test.go

+2
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ func TestInsertWorkspaceAgentStartupLogs(t *testing.T) {
114114
CreatedAt: []time.Time{database.Now()},
115115
Output: []string{"first"},
116116
Level: []database.LogLevel{database.LogLevelInfo},
117+
EOF: []bool{false},
117118
// 1 MB is the max
118119
OutputLength: 1 << 20,
119120
})
@@ -125,6 +126,7 @@ func TestInsertWorkspaceAgentStartupLogs(t *testing.T) {
125126
CreatedAt: []time.Time{database.Now()},
126127
Output: []string{"second"},
127128
Level: []database.LogLevel{database.LogLevelInfo},
129+
EOF: []bool{false},
128130
OutputLength: 1,
129131
})
130132
require.True(t, database.IsStartupLogsLimitError(err))

coderd/database/queries.sql.go

+10-5
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/queries/workspaceagents.sql

+3-2
Original file line numberDiff line numberDiff line change
@@ -152,12 +152,13 @@ WITH new_length AS (
152152
startup_logs_length = startup_logs_length + @output_length WHERE workspace_agents.id = @agent_id
153153
)
154154
INSERT INTO
155-
workspace_agent_startup_logs (agent_id, created_at, output, level)
155+
workspace_agent_startup_logs (agent_id, created_at, output, level, eof)
156156
SELECT
157157
@agent_id :: uuid AS agent_id,
158158
unnest(@created_at :: timestamptz [ ]) AS created_at,
159159
unnest(@output :: VARCHAR(1024) [ ]) AS output,
160-
unnest(@level :: log_level [ ]) AS level
160+
unnest(@level :: log_level [ ]) AS level,
161+
unnest(@eof :: boolean [ ]) AS eof
161162
RETURNING workspace_agent_startup_logs.*;
162163

163164
-- If an agent hasn't connected in the last 7 days, we purge it's logs.

coderd/database/sqlc.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ overrides:
5555
uuid: UUID
5656
failure_ttl: FailureTTL
5757
inactivity_ttl: InactivityTTL
58+
eof: EOF
5859

5960
sql:
6061
- schema: "./dump.sql"

0 commit comments

Comments
 (0)