Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit0c50774

Browse files
authored
fix: avoid missed logs when streaming startup logs (#8029)
* feat(coderd,agent): send startup log eof at the end* fix(coderd): fix edge case in startup log pubsub* fix(coderd): ensure startup logs are closed on lifecycle state change (fallback)* fix(codersdk): fix startup log channel shared memory bug* fix(site): remove the EOF log line
1 parent247f8a9 commit0c50774

28 files changed

+658
-131
lines changed

‎agent/agent.go

Lines changed: 13 additions & 0 deletions
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
iferrors.As(err,&sdkErr) {
930930
ifsdkErr.StatusCode()==http.StatusRequestEntityTooLarge {
931931
a.logger.Warn(ctx,"startup logs too large, dropping logs")
932+
// Always send the EOF even if logs overflow.
933+
iflen(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+
iferr:=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
deferclose(logsFinished)
982995
logsFlushed.L.Lock()
983996
for {

‎agent/agent_test.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -905,8 +905,10 @@ func TestAgent_StartupScript(t *testing.T) {
905905
returnlen(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

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.

‎coderd/apidoc/swagger.json

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.

‎coderd/database/dbauthz/dbauthz.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1407,6 +1407,14 @@ func (q *querier) GetWorkspaceAgentStartupLogsAfter(ctx context.Context, arg dat
14071407
returnq.db.GetWorkspaceAgentStartupLogsAfter(ctx,arg)
14081408
}
14091409

1410+
func (q*querier)GetWorkspaceAgentStartupLogsEOF(ctx context.Context,agentID uuid.UUID) (bool,error) {
1411+
_,err:=q.GetWorkspaceAgentByID(ctx,agentID)
1412+
iferr!=nil {
1413+
returnfalse,err
1414+
}
1415+
returnq.db.GetWorkspaceAgentStartupLogsEOF(ctx,agentID)
1416+
}
1417+
14101418
func (q*querier)GetWorkspaceAgentStats(ctx context.Context,createdAfter time.Time) ([]database.GetWorkspaceAgentStatsRow,error) {
14111419
returnq.db.GetWorkspaceAgentStats(ctx,createdAfter)
14121420
}

‎coderd/database/dbfake/dbfake.go

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2722,14 +2722,30 @@ func (q *fakeQuerier) GetWorkspaceAgentStartupLogsAfter(_ context.Context, arg d
27222722
iflog.AgentID!=arg.AgentID {
27232723
continue
27242724
}
2725-
ifarg.CreatedAfter!=0&&log.ID<arg.CreatedAfter {
2725+
ifarg.CreatedAfter!=0&&log.ID<=arg.CreatedAfter {
27262726
continue
27272727
}
27282728
logs=append(logs,log)
27292729
}
27302730
returnlogs,nil
27312731
}
27322732

2733+
func (q*fakeQuerier)GetWorkspaceAgentStartupLogsEOF(_ context.Context,agentID uuid.UUID) (bool,error) {
2734+
q.mutex.RLock()
2735+
deferq.mutex.RUnlock()
2736+
2737+
varlastLog database.WorkspaceAgentStartupLog
2738+
for_,log:=rangeq.workspaceAgentLogs {
2739+
iflog.AgentID!=agentID {
2740+
continue
2741+
}
2742+
iflog.ID>lastLog.ID {
2743+
lastLog=log
2744+
}
2745+
}
2746+
returnlastLog.EOF,nil
2747+
}
2748+
27332749
func (q*fakeQuerier)GetWorkspaceAgentStats(_ context.Context,createdAfter time.Time) ([]database.GetWorkspaceAgentStatsRow,error) {
27342750
q.mutex.RLock()
27352751
deferq.mutex.RUnlock()
@@ -4013,7 +4029,7 @@ func (q *fakeQuerier) InsertWorkspaceAgentStartupLogs(_ context.Context, arg dat
40134029
deferq.mutex.Unlock()
40144030

40154031
logs:= []database.WorkspaceAgentStartupLog{}
4016-
id:=int64(1)
4032+
id:=int64(0)
40174033
iflen(q.workspaceAgentLogs)>0 {
40184034
id=q.workspaceAgentLogs[len(q.workspaceAgentLogs)-1].ID
40194035
}
@@ -4026,6 +4042,7 @@ func (q *fakeQuerier) InsertWorkspaceAgentStartupLogs(_ context.Context, arg dat
40264042
CreatedAt:arg.CreatedAt[index],
40274043
Level:arg.Level[index],
40284044
Output:output,
4045+
EOF:arg.EOF[index],
40294046
})
40304047
outputLength+=int32(len(output))
40314048
}

‎coderd/database/dbmetrics/dbmetrics.go

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.

‎coderd/database/dbmock/dbmock.go

Lines changed: 15 additions & 0 deletions
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.

‎coderd/database/dump.sql

Lines changed: 4 additions & 1 deletion
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ALTERTABLE workspace_agent_startup_logs DROP COLUMN eof;
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
ALTERTABLE workspace_agent_startup_logs ADD COLUMN eofbooleanNOT NULL DEFAULT false;
2+
3+
COMMENT ON COLUMN workspace_agent_startup_logs.eof IS'End of file reached';

‎coderd/database/models.go

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.

‎coderd/database/querier.go

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.

‎coderd/database/querier_test.go

Lines changed: 2 additions & 0 deletions
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

Lines changed: 30 additions & 5 deletions
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.

‎coderd/database/queries/workspaceagents.sql

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -146,18 +146,31 @@ WHERE
146146
id> @created_after
147147
)ORDER BY idASC;
148148

149+
-- name: GetWorkspaceAgentStartupLogsEOF :one
150+
SELECT CASE WHEN EXISTS (
151+
SELECT
152+
*
153+
FROM
154+
workspace_agent_startup_logs
155+
WHERE
156+
agent_id= $1
157+
AND eof= true
158+
LIMIT1
159+
) THEN TRUE ELSE FALSE END;
160+
149161
-- name: InsertWorkspaceAgentStartupLogs :many
150162
WITH new_lengthAS (
151163
UPDATE workspace_agentsSET
152164
startup_logs_length= startup_logs_length+ @output_lengthWHEREworkspace_agents.id= @agent_id
153165
)
154166
INSERT INTO
155-
workspace_agent_startup_logs (agent_id, created_at, output, level)
167+
workspace_agent_startup_logs (agent_id, created_at, output, level, eof)
156168
SELECT
157169
@agent_id :: uuidAS agent_id,
158170
unnest(@created_at ::timestamptz [ ])AS created_at,
159171
unnest(@output ::VARCHAR(1024) [ ])AS output,
160-
unnest(@level :: log_level [ ])AS level
172+
unnest(@level :: log_level [ ])AS level,
173+
unnest(@eof ::boolean [ ])AS eof
161174
RETURNING workspace_agent_startup_logs.*;
162175

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

‎coderd/database/sqlc.yaml

Lines changed: 1 addition & 0 deletions
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)

[8]ページ先頭

©2009-2025 Movatter.jp