-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Css 4824/expire audit logs #1007
Changes from 14 commits
b90c377
ed03a3a
8e751ec
00c6807
abb312e
b0f6a2d
8e6eeb9
251a63d
88364dd
7229fea
6dacbaf
100e147
5659d23
eafd833
9a3e467
a74276d
7cc7ea8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,6 +8,7 @@ import ( | |
|
||
"github.com/canonical/jimm/internal/dbmodel" | ||
"github.com/canonical/jimm/internal/errors" | ||
"github.com/canonical/jimm/internal/servermon" | ||
) | ||
|
||
// AddAuditLogEntry adds a new entry to the audit log. | ||
|
@@ -103,3 +104,17 @@ func (d *Database) ForEachAuditLogEntry(ctx context.Context, filter AuditLogFilt | |
} | ||
return nil | ||
} | ||
|
||
// CleanupAuditLogs cleans up audit logs after the auditLogRetentionPeriodInDays, | ||
// HARD deleting them from the database. | ||
func (d *Database) CleanupAuditLogs(ctx context.Context, auditLogRetentionPeriodInDays int) (int64, error) { | ||
retentionDate := time.Now().AddDate(0, 0, -(auditLogRetentionPeriodInDays)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we might run into problems testing because time is calculated here.. would be better to pass in the cut-off date.. better for testability There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This function is present in both this and #1008 so please discuss and align them |
||
duration := time.Since(time.Now()) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this doesn't work.. instead
|
||
tx := d.DB. | ||
WithContext(ctx). | ||
Unscoped(). | ||
Where("time < ?", retentionDate). | ||
Delete(&dbmodel.AuditLogEntry{}) | ||
servermon.QueryTimeAuditLogCleanUpHistogram.Observe(duration.Seconds()) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. then
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed aha |
||
return tx.RowsAffected, tx.Error | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,6 +15,7 @@ import ( | |
"github.com/juju/zaputil/zapctx" | ||
"go.uber.org/zap" | ||
|
||
"github.com/canonical/jimm/internal/db" | ||
"github.com/canonical/jimm/internal/dbmodel" | ||
"github.com/canonical/jimm/internal/servermon" | ||
) | ||
|
@@ -127,3 +128,75 @@ func (o recorder) HandleReply(r rpc.Request, header *rpc.Header, body interface{ | |
servermon.WebsocketRequestDuration.WithLabelValues(r.Type, r.Action).Observe(float64(d) / float64(time.Second)) | ||
return o.logger.LogResponse(r, header, body) | ||
} | ||
|
||
// AuditLogCleanupService is a service capable of cleaning up audit logs | ||
// on a defined retention period. The retention period is in DAYS. | ||
type auditLogCleanupService struct { | ||
auditLogRetentionPeriodInDays int | ||
db db.Database | ||
} | ||
|
||
// pollTimeOfDay holds the time hour, minutes and seconds to poll at. | ||
type pollTimeOfDay struct { | ||
Hours int | ||
Minutes int | ||
Seconds int | ||
} | ||
|
||
var pollDuration = pollTimeOfDay{ | ||
Hours: 9, | ||
} | ||
|
||
// NewAuditLogCleanupService returns a service capable of cleaning up audit logs | ||
// on a defined retention period. The retention period is in DAYS. | ||
func NewAuditLogCleanupService(db db.Database, auditLogRetentionPeriodInDays int) *auditLogCleanupService { | ||
return &auditLogCleanupService{ | ||
auditLogRetentionPeriodInDays: auditLogRetentionPeriodInDays, | ||
db: db, | ||
} | ||
} | ||
|
||
// Start starts a routine which checks daily for any logs | ||
// needed to be cleaned up. | ||
func (a *auditLogCleanupService) Start(ctx context.Context) { | ||
go a.poll(ctx) | ||
} | ||
|
||
// poll is designed to be run in a routine where it can be cancelled safely | ||
// from the service's context. It calculates the poll duration at 9am each day | ||
// UTC. | ||
func (a *auditLogCleanupService) poll(ctx context.Context) { | ||
for { | ||
select { | ||
case <-time.After(calculateNextPollDuration(time.Now().UTC())): | ||
deleted, err := a.db.CleanupAuditLogs(ctx, a.auditLogRetentionPeriodInDays) | ||
if err != nil { | ||
zapctx.Error(ctx, "failed to cleanup audit logs", zap.Error(err)) | ||
continue | ||
} | ||
zapctx.Debug(ctx, "audit log cleanup run successfully", zap.Int64("count", deleted)) | ||
case <-ctx.Done(): | ||
zapctx.Debug(ctx, "exiting audit log cleanup polling") | ||
return | ||
ale8k marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
} | ||
} | ||
|
||
// calculateNextPollDuration returns the next duration to poll on. | ||
// We recalculate each time and not rely on running every 24 hours | ||
// for absolute consistency within ns apart. | ||
func calculateNextPollDuration(startingTime time.Time) time.Duration { | ||
now := startingTime | ||
nineAM := time.Date(now.Year(), now.Month(), now.Day(), pollDuration.Hours, 0, 0, 0, time.UTC) | ||
alesstimec marked this conversation as resolved.
Show resolved
Hide resolved
|
||
nineAMDuration := nineAM.Sub(now) | ||
d := time.Hour | ||
// If 9am is behind the current time, i.e., 1pm | ||
if nineAMDuration < 0 { | ||
// Add 24 hours, flip it to an absolute duration, i.e., -10h == 10h | ||
// and subtract it from 24 hours to calculate 9am tomorrow | ||
d = time.Hour*24 - nineAMDuration.Abs() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is the same as |
||
} else { | ||
d = nineAMDuration.Abs() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We don't need the |
||
} | ||
return d | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
new line, please?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doing this now