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

Commitc86c2be

Browse files
committed
feat(coderd/database/dbpurge): add retention for workspace agent logs
Replace hardcoded 7-day retention for workspace agent logs with configurableretention from deployment settings. Falls back to global retention when notset, and skips deletion entirely when effective retention is 0.Depends on#21038Updates#20743
1 parentb1ce17f commitc86c2be

File tree

13 files changed

+208
-27
lines changed

13 files changed

+208
-27
lines changed

‎cli/testdata/coder_server_--help.golden‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -717,6 +717,11 @@ that data type.
717717
How long connection log entries are retained. Set to 0 to disable
718718
(keep indefinitely).
719719

720+
--workspace-agent-logs-retention duration, $CODER_WORKSPACE_AGENT_LOGS_RETENTION (default: 7d)
721+
How long workspace agent logs are retained. Logs from non-latest
722+
workspace builds are deleted after this period to free up storage
723+
space. Set to 0 to disable automatic deletion of workspace agent logs.
724+
720725
TELEMETRY OPTIONS:
721726
Telemetry is critical to our ability to improve Coder. We strip all personal
722727
information before sending data to our servers. Please only disable telemetry

‎cli/testdata/server-config.yaml.golden‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -761,3 +761,8 @@ retention:
761761
# an expired key. Set to 0 to disable automatic deletion of expired keys.
762762
# (default: 7d, type: duration)
763763
api_keys: 168h0m0s
764+
# How long workspace agent logs are retained. Logs from non-latest workspace
765+
# builds are deleted after this period to free up storage space. Set to 0 to
766+
# disable automatic deletion of workspace agent logs.
767+
# (default: 7d, type: duration)
768+
workspace_agent_logs: 168h0m0s

‎coderd/apidoc/docs.go‎

Lines changed: 4 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: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.

‎coderd/database/dbpurge/dbpurge.go‎

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,7 @@ import (
1818
)
1919

2020
const (
21-
delay=10*time.Minute
22-
maxAgentLogAge=7*24*time.Hour
21+
delay=10*time.Minute
2322
// Connection events are now inserted into the `connection_logs` table.
2423
// We'll slowly remove old connection events from the `audit_logs` table.
2524
// The `connection_logs` table is purged based on the configured retention.
@@ -67,9 +66,15 @@ func New(ctx context.Context, logger slog.Logger, db database.Store, vals *coder
6766
returnnil
6867
}
6968

70-
deleteOldWorkspaceAgentLogsBefore:=start.Add(-maxAgentLogAge)
71-
iferr:=tx.DeleteOldWorkspaceAgentLogs(ctx,deleteOldWorkspaceAgentLogsBefore);err!=nil {
72-
returnxerrors.Errorf("failed to delete old workspace agent logs: %w",err)
69+
workspaceAgentLogsRetention:=vals.Retention.WorkspaceAgentLogs.Value()
70+
ifworkspaceAgentLogsRetention==0 {
71+
workspaceAgentLogsRetention=vals.Retention.Global.Value()
72+
}
73+
ifworkspaceAgentLogsRetention>0 {
74+
deleteOldWorkspaceAgentLogsBefore:=start.Add(-workspaceAgentLogsRetention)
75+
iferr:=tx.DeleteOldWorkspaceAgentLogs(ctx,deleteOldWorkspaceAgentLogsBefore);err!=nil {
76+
returnxerrors.Errorf("failed to delete old workspace agent logs: %w",err)
77+
}
7378
}
7479
iferr:=tx.DeleteOldWorkspaceAgentStats(ctx);err!=nil {
7580
returnxerrors.Errorf("failed to delete old workspace agent stats: %w",err)

‎coderd/database/dbpurge/dbpurge_test.go‎

Lines changed: 97 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,11 @@ func TestDeleteOldWorkspaceAgentLogs(t *testing.T) {
246246
// After dbpurge completes, the ticker is reset. Trap this call.
247247

248248
done:=awaitDoTick(ctx,t,clk)
249-
closer:=dbpurge.New(ctx,logger,db,&codersdk.DeploymentValues{},clk)
249+
closer:=dbpurge.New(ctx,logger,db,&codersdk.DeploymentValues{
250+
Retention: codersdk.RetentionConfig{
251+
WorkspaceAgentLogs:serpent.Duration(7*24*time.Hour),
252+
},
253+
},clk)
250254
defercloser.Close()
251255
<-done// doTick() has now run.
252256

@@ -392,6 +396,98 @@ func mustCreateAgentLogs(ctx context.Context, t *testing.T, db database.Store, a
392396
require.NotEmpty(t,agentLogs,"agent logs must be present")
393397
}
394398

399+
funcTestDeleteOldWorkspaceAgentLogsRetention(t*testing.T) {
400+
t.Parallel()
401+
402+
now:=time.Date(2025,1,15,7,30,0,0,time.UTC)
403+
404+
testCases:= []struct {
405+
namestring
406+
retentionConfig codersdk.RetentionConfig
407+
logsAge time.Duration
408+
expectDeletedbool
409+
}{
410+
{
411+
name:"RetentionEnabled",
412+
retentionConfig: codersdk.RetentionConfig{
413+
WorkspaceAgentLogs:serpent.Duration(7*24*time.Hour),// 7 days
414+
},
415+
logsAge:8*24*time.Hour,// 8 days ago
416+
expectDeleted:true,
417+
},
418+
{
419+
name:"RetentionDisabled",
420+
retentionConfig: codersdk.RetentionConfig{
421+
WorkspaceAgentLogs:serpent.Duration(0),
422+
},
423+
logsAge:60*24*time.Hour,// 60 days ago
424+
expectDeleted:false,
425+
},
426+
{
427+
name:"GlobalRetentionFallback",
428+
retentionConfig: codersdk.RetentionConfig{
429+
Global:serpent.Duration(14*24*time.Hour),// 14 days global
430+
WorkspaceAgentLogs:serpent.Duration(0),// Not set, falls back to global
431+
},
432+
logsAge:15*24*time.Hour,// 15 days ago
433+
expectDeleted:true,
434+
},
435+
{
436+
name:"CustomRetention30Days",
437+
retentionConfig: codersdk.RetentionConfig{
438+
WorkspaceAgentLogs:serpent.Duration(30*24*time.Hour),// 30 days
439+
},
440+
logsAge:31*24*time.Hour,// 31 days ago
441+
expectDeleted:true,
442+
},
443+
}
444+
445+
for_,tc:=rangetestCases {
446+
t.Run(tc.name,func(t*testing.T) {
447+
t.Parallel()
448+
449+
ctx:=testutil.Context(t,testutil.WaitShort)
450+
clk:=quartz.NewMock(t)
451+
clk.Set(now).MustWait(ctx)
452+
453+
oldTime:=now.Add(-tc.logsAge)
454+
455+
db,_:=dbtestutil.NewDB(t,dbtestutil.WithDumpOnFailure())
456+
logger:=slogtest.Make(t,&slogtest.Options{IgnoreErrors:true})
457+
org:=dbgen.Organization(t,db, database.Organization{})
458+
user:=dbgen.User(t,db, database.User{})
459+
_=dbgen.OrganizationMember(t,db, database.OrganizationMember{UserID:user.ID,OrganizationID:org.ID})
460+
tv:=dbgen.TemplateVersion(t,db, database.TemplateVersion{OrganizationID:org.ID,CreatedBy:user.ID})
461+
tmpl:=dbgen.Template(t,db, database.Template{OrganizationID:org.ID,ActiveVersionID:tv.ID,CreatedBy:user.ID})
462+
463+
ws:=dbgen.Workspace(t,db, database.WorkspaceTable{Name:"test-ws",OwnerID:user.ID,OrganizationID:org.ID,TemplateID:tmpl.ID})
464+
wb1:=mustCreateWorkspaceBuild(t,db,org,tv,ws.ID,oldTime,1)
465+
wb2:=mustCreateWorkspaceBuild(t,db,org,tv,ws.ID,oldTime,2)
466+
agent1:=mustCreateAgent(t,db,wb1)
467+
agent2:=mustCreateAgent(t,db,wb2)
468+
mustCreateAgentLogs(ctx,t,db,agent1,&oldTime,"agent 1 logs")
469+
mustCreateAgentLogs(ctx,t,db,agent2,&oldTime,"agent 2 logs")
470+
471+
// Run the purge.
472+
done:=awaitDoTick(ctx,t,clk)
473+
closer:=dbpurge.New(ctx,logger,db,&codersdk.DeploymentValues{
474+
Retention:tc.retentionConfig,
475+
},clk)
476+
defercloser.Close()
477+
testutil.TryReceive(ctx,t,done)
478+
479+
// Verify results.
480+
iftc.expectDeleted {
481+
assertNoWorkspaceAgentLogs(ctx,t,db,agent1.ID)
482+
}else {
483+
assertWorkspaceAgentLogs(ctx,t,db,agent1.ID,"agent 1 logs")
484+
}
485+
// Latest build logs are always retained.
486+
assertWorkspaceAgentLogs(ctx,t,db,agent2.ID,"agent 2 logs")
487+
})
488+
}
489+
}
490+
395491
//nolint:paralleltest // It uses LockIDDBPurge.
396492
funcTestDeleteOldProvisionerDaemons(t*testing.T) {
397493
// TODO: must refactor DeleteOldProvisionerDaemons to allow passing in cutoff

‎codersdk/deployment.go‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -829,6 +829,9 @@ type RetentionConfig struct {
829829
// Keys are only deleted if they have been expired for at least this duration.
830830
// Defaults to 7 days to preserve existing behavior.
831831
APIKeys serpent.Duration`json:"api_keys" typescript:",notnull"`
832+
// WorkspaceAgentLogs controls how long workspace agent logs are retained.
833+
// Defaults to 7 days to preserve existing behavior.
834+
WorkspaceAgentLogs serpent.Duration`json:"workspace_agent_logs" typescript:",notnull"`
832835
}
833836

834837
typeNotificationsConfigstruct {
@@ -3420,6 +3423,17 @@ Write out the current server config as YAML to stdout.`,
34203423
YAML:"api_keys",
34213424
Annotations: serpent.Annotations{}.Mark(annotationFormatDuration,"true"),
34223425
},
3426+
{
3427+
Name:"Workspace Agent Logs Retention",
3428+
Description:"How long workspace agent logs are retained. Logs from non-latest workspace builds are deleted after this period to free up storage space. Set to 0 to disable automatic deletion of workspace agent logs.",
3429+
Flag:"workspace-agent-logs-retention",
3430+
Env:"CODER_WORKSPACE_AGENT_LOGS_RETENTION",
3431+
Value:&c.Retention.WorkspaceAgentLogs,
3432+
Default:"7d",
3433+
Group:&deploymentGroupRetention,
3434+
YAML:"workspace_agent_logs",
3435+
Annotations: serpent.Annotations{}.Mark(annotationFormatDuration,"true"),
3436+
},
34233437
{
34243438
Name:"Enable Authorization Recordings",
34253439
Description:"All api requests will have a header including all authorization calls made during the request. "+

‎docs/admin/setup/data-retention.md‎

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
#Data Retention
22

33
Coder supports configurable retention policies that automatically purge old
4-
Audit Logs, Connection Logs, and API keys. These policies help manage database
5-
growth by removing records older than a specified duration.
4+
Audit Logs, Connection Logs,Workspace Agent Logs,and API keys. These policies
5+
help manage databasegrowth by removing records older than a specified duration.
66

77
##Overview
88

@@ -16,7 +16,8 @@ Retention policies help you:
1616

1717
>[!NOTE]
1818
>Retention policies are disabled by default (set to`0`) to preserve existing
19-
>behavior. The only exception is API keys, which defaults to 7 days.
19+
>behavior. The exceptions are API keys and workspace agent logs, which default
20+
>to 7 days.
2021
2122
##Configuration
2223

@@ -25,11 +26,12 @@ a YAML configuration file.
2526

2627
###Settings
2728

28-
| Setting| CLI Flag| Environment Variable| Default| Description|
29-
|-----------------|-------------------------------|-----------------------------------|----------------|--------------------------------------|
30-
| Audit Logs|`--audit-logs-retention`|`CODER_AUDIT_LOGS_RETENTION`|`0` (disabled)| How long to retain Audit Log entries|
31-
| Connection Logs|`--connection-logs-retention`|`CODER_CONNECTION_LOGS_RETENTION`|`0` (disabled)| How long to retain Connection Logs|
32-
| API Keys|`--api-keys-retention`|`CODER_API_KEYS_RETENTION`|`7d`| How long to retain expired API keys|
29+
| Setting| CLI Flag| Environment Variable| Default| Description|
30+
|----------------------|------------------------------------|----------------------------------------|----------------|------------------------------------------|
31+
| Audit Logs|`--audit-logs-retention`|`CODER_AUDIT_LOGS_RETENTION`|`0` (disabled)| How long to retain Audit Log entries|
32+
| Connection Logs|`--connection-logs-retention`|`CODER_CONNECTION_LOGS_RETENTION`|`0` (disabled)| How long to retain Connection Logs|
33+
| API Keys|`--api-keys-retention`|`CODER_API_KEYS_RETENTION`|`7d`| How long to retain expired API keys|
34+
| Workspace Agent Logs|`--workspace-agent-logs-retention`|`CODER_WORKSPACE_AGENT_LOGS_RETENTION`|`7d`| How long to retain workspace agent logs|
3335

3436
###Duration Format
3537

@@ -48,7 +50,8 @@ Go duration units (`h`, `m`, `s`):
4850
coder server \
4951
--audit-logs-retention=365d \
5052
--connection-logs-retention=90d \
51-
--api-keys-retention=7d
53+
--api-keys-retention=7d \
54+
--workspace-agent-logs-retention=7d
5255
```
5356

5457
###Environment Variables Example
@@ -57,6 +60,7 @@ coder server \
5760
export CODER_AUDIT_LOGS_RETENTION=365d
5861
export CODER_CONNECTION_LOGS_RETENTION=90d
5962
export CODER_API_KEYS_RETENTION=7d
63+
export CODER_WORKSPACE_AGENT_LOGS_RETENTION=7d
6064
```
6165

6266
###YAML Configuration Example
@@ -66,6 +70,7 @@ retention:
6670
audit_logs:365d
6771
connection_logs:90d
6872
api_keys:7d
73+
workspace_agent_logs:7d
6974
```
7075
7176
## How Retention Works
@@ -100,6 +105,16 @@ ago. Active keys are never deleted by the retention policy.
100105
Keeping expired keys for a short period allows Coder to return a more helpful
101106
error message when users attempt to use an expired key.
102107

108+
### Workspace Agent Logs Behavior
109+
110+
Workspace agent logs are retained based on the retention period, but **logs from
111+
the latest build of each workspace are always retained** regardless of age. This
112+
ensures you can always debug issues with active workspaces.
113+
114+
Only logs from non-latest workspace builds that are older than the retention
115+
period are deleted. Setting `--workspace-agent-logs-retention=7d` keeps all logs
116+
from the latest build plus logs from previous builds for up to 7 days.
117+
103118
## Best Practices
104119

105120
### Recommended Starting Configuration
@@ -111,6 +126,7 @@ retention:
111126
audit_logs: 365d
112127
connection_logs: 90d
113128
api_keys: 7d
129+
workspace_agent_logs: 7d
114130
```
115131

116132
### Compliance Considerations
@@ -150,9 +166,10 @@ To keep data indefinitely for any data type, set its retention value to `0`:
150166

151167
```yaml
152168
retention:
153-
audit_logs: 0s # Keep audit logs forever
154-
connection_logs: 0s # Keep connection logs forever
155-
api_keys: 0s # Keep expired API keys forever
169+
audit_logs: 0s # Keep audit logs forever
170+
connection_logs: 0s # Keep connection logs forever
171+
api_keys: 0s # Keep expired API keys forever
172+
workspace_agent_logs: 0s # Keep workspace agent logs forever
156173
```
157174

158175
## Monitoring

‎docs/reference/api/general.md‎

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

‎docs/reference/api/schemas.md‎

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

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp