Skip to content

Commit b75c249

Browse files
feat: add trace retention policy
1 parent 41493dd commit b75c249

File tree

8 files changed

+112
-28
lines changed

8 files changed

+112
-28
lines changed

README.md

+6-3
Original file line numberDiff line numberDiff line change
@@ -106,15 +106,18 @@ healthcheck:
106106
# Run on startup
107107
startup: false
108108
109-
# Retention policy for envelopes and attachment files
109+
# Retention policy will delete resources that match the configured policy
110110
retention:
111-
# Retention policy for envelopes in database
111+
# Envelopes in database
112112
envelope_count: # (0, 100, 250, ...)
113113
envelope_age: # (5m, 5h45m, ...)
114114
115-
# Retention policy for attachment files on disk
115+
# Attachment files in file store
116116
attachment_size: # (100 MB, 1 GB, ...)
117117
118+
# Traces in database
119+
trace_age: 168h # 7 days (5m, 5h45m, ...)
120+
118121
# HTTP server
119122
http:
120123
disable: false # (false, true)

config/config.go

+13-1
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ type Raw struct {
6464
RetentionEnvelopeCount string `koanf:"retention.envelope_count"`
6565
RetentionEnvelopeAge string `koanf:"retention.envelope_age"`
6666
RetentionAttachmentSize string `koanf:"retention.attachment_size"`
67+
RetentionTraceAge string `koanf:"retention.trace_age"`
6768
HealthcheckURL string `koanf:"healthcheck.url"`
6869
HealthcheckInterval string `koanf:"healthcheck.interval"`
6970
HealthcheckStartup bool `koanf:"healthcheck.startup"`
@@ -111,13 +112,15 @@ var RawDefault = struct {
111112
SMTPPort uint16 `koanf:"smtp.port"`
112113
SMTPMaxPayloadSize string `koanf:"smtp.max_payload_size"`
113114
HTTPPort uint16 `koanf:"http.port"`
115+
RetentionTraceAge string `koanf:"retention.trace_age"`
114116
// IMAPPort uint16 `koanf:"imap.port"`
115117
}{
116118
HealthcheckInterval: "5m",
117119
TimeFormat: timeFormat12H,
118120
SMTPMaxPayloadSize: "25 MB",
119121
DataDirectory: "smtpbridge_data",
120122
PythonExecutable: "python3",
123+
RetentionTraceAge: "168h",
121124
SMTPPort: 1025,
122125
HTTPPort: 8080,
123126
// IMAPPort: 10143,
@@ -226,13 +229,22 @@ func (p Parser) Parse(raw Raw) (Config, error) {
226229
}
227230
envelopeAge = &age
228231
}
232+
var traceAge *time.Duration
233+
if raw.RetentionTraceAge != "" {
234+
age, err := time.ParseDuration(raw.RetentionTraceAge)
235+
if err != nil {
236+
return Config{}, err
237+
}
238+
traceAge = &age
239+
}
229240

230241
config = &models.Config{
231242
RetentionPolicy: models.ConfigRetentionPolicy{
243+
MinAge: 5 * time.Minute,
232244
EnvelopeCount: envelopeCount,
233245
AttachmentSize: attachmentsSize,
234246
EnvelopeAge: envelopeAge,
235-
MinAge: 5 * time.Minute,
247+
TraceAge: traceAge,
236248
},
237249
AuthSMTP: auth.New(
238250
raw.SMTPUsername,

internal/app/app.go

+7-1
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,8 @@ func (a App) TraceList(ctx context.Context, page pagination.Page, req models.DTO
354354
}
355355

356356
func (a App) TraceDrop(ctx context.Context) error {
357-
return repo.TraceDrop(ctx, a.db)
357+
_, err := repo.TraceDrop(ctx, a.db)
358+
return err
358359
}
359360

360361
func (a App) RetentionPolicyGet(ctx context.Context) models.ConfigRetentionPolicy {
@@ -385,6 +386,11 @@ func (a App) RetentionPolicyRun(ctx context.Context, tracer trace.Tracer) error
385386
return err
386387
}
387388

389+
_, err = retention.DeleteTraceByAge(ctx, tracer, a.db, a.config.RetentionPolicy)
390+
if err != nil {
391+
return err
392+
}
393+
388394
return nil
389395
}
390396

internal/models/models.go

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ type ConfigRetentionPolicy struct {
2121
EnvelopeCount *int
2222
EnvelopeAge *time.Duration
2323
AttachmentSize *int64
24+
TraceAge *time.Duration
2425
}
2526

2627
func (p ConfigRetentionPolicy) EnvelopeAgeTime() time.Time {

internal/repo/trace.go

+19-3
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package repo
33
import (
44
"context"
55
"fmt"
6+
"time"
67

78
"github.com/ItsNotGoodName/smtpbridge/internal/database"
89
. "github.com/ItsNotGoodName/smtpbridge/internal/jet/table"
@@ -103,10 +104,25 @@ func TraceList(ctx context.Context, db database.Querier, page pagination.Page, r
103104
}, nil
104105
}
105106

106-
func TraceDrop(ctx context.Context, db database.Querier) error {
107-
_, err := Traces.
107+
func TraceDrop(ctx context.Context, db database.Querier) (int64, error) {
108+
res, err := Traces.
108109
DELETE().
109110
WHERE(RawBool("1=1")).
110111
ExecContext(ctx, db)
111-
return err
112+
if err != nil {
113+
return 0, err
114+
}
115+
116+
return res.RowsAffected()
117+
}
118+
119+
func TraceTrim(ctx context.Context, db database.Querier, age time.Time) (int64, error) {
120+
res, err := Traces.
121+
DELETE().
122+
WHERE(Traces.CreatedAt.LT(RawTimestamp(muhTypeAffinity(models.NewTime(age))))).
123+
ExecContext(ctx, db)
124+
if err != nil {
125+
return 0, err
126+
}
127+
return res.RowsAffected()
112128
}

internal/retention/retention.go

+16
Original file line numberDiff line numberDiff line change
@@ -115,3 +115,19 @@ func DeleteOrphanAttachments(ctx context.Context, tracer trace.Tracer, db databa
115115
tracer.Trace(ctx, "retention.attachment.orphan.delete", trace.WithKV("count", len(atts)))
116116
}
117117
}
118+
119+
func DeleteTraceByAge(ctx context.Context, tracer trace.Tracer, db database.Querier, policy models.ConfigRetentionPolicy) (int64, error) {
120+
if policy.TraceAge == nil {
121+
return 0, nil
122+
}
123+
124+
age := time.Now().Add(-*policy.TraceAge)
125+
count, err := repo.TraceTrim(ctx, db, age)
126+
if err != nil {
127+
return 0, err
128+
}
129+
130+
tracer.Trace(ctx, "retention.trace.age.delete", trace.WithKV("count", count))
131+
132+
return count, nil
133+
}

web/pages/index.templ

+6
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,12 @@ templ indexView(m meta.Meta, props indexViewProps) {
6666
<td>{ helpers.BytesHumanize(*props.RetentionPolicy.AttachmentSize) }</td>
6767
</tr>
6868
}
69+
if props.RetentionPolicy.TraceAge != nil {
70+
<tr>
71+
<th>Maximum Trace Age</th>
72+
<td>{ props.RetentionPolicy.TraceAge.String() }</td>
73+
</tr>
74+
}
6975
</tbody>
7076
</table>
7177
</div>

web/pages/index_templ.go

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

0 commit comments

Comments
 (0)