Skip to content

overlord/changeslogger: add changes logger manager#16678

Open
asasine wants to merge 1 commit intocanonical:masterfrom
asasine:changes-logger
Open

overlord/changeslogger: add changes logger manager#16678
asasine wants to merge 1 commit intocanonical:masterfrom
asasine:changes-logger

Conversation

@asasine
Copy link

@asasine asasine commented Feb 26, 2026

https://bugs.launchpad.net/ubuntu/+source/snapd/+bug/1695934 has been open for nine years so I thought I'd take a chance at implementing it myself. The changes are sent to /var/log/snapd/changes.log and are formatted as below, separated by a blank line between each change:

Timestamp: 2026-02-26T10:31:00Z
ID: change-123
Kind: install
Summary: Install snap
Status: Done
SpawnTime: 2026-02-26T10:30:00Z
ReadyTime: 2026-02-26T10:31:00Z

I've added unit tests but was not entirely sure how to test this end-to-end.

@github-actions github-actions bot added the Needs Documentation -auto- Label automatically added which indicates the change needs documentation label Feb 26, 2026
@zyga zyga requested a review from Copilot February 26, 2026 08:27
@zyga
Copy link
Contributor

zyga commented Feb 26, 2026

@asasine wow, thank you so much! I will review this and ask my colleagues for opinions.

As for integration testing we can explore that together.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request adds a new changes logger manager to the snapd overlord that logs all state changes to /var/log/snapd/changes.log in a human-readable format. The feature implements a long-standing feature request (9 years old) to provide audit logging of snapd operations.

Changes:

  • Introduces a new overlord/changeslogger package that implements the StateManager interface to monitor and log changes
  • Updates packaging files across multiple distributions to create the /var/log/snapd directory
  • Adds infrastructure in the dirs package to define the new log file path
  • Updates snap CLI help text to inform users about the new log file

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
overlord/changeslogger/changeslogger.go Core implementation of the changes logger manager with Ensure() and StartUp() methods
overlord/changeslogger/changeslogger_test.go Unit tests verifying log creation, status change tracking, and directory creation
overlord/changeslogger/export_test.go Test helper to expose internal fields for testing
overlord/overlord.go Integration of the changes logger manager into the overlord
dirs/dirs.go Defines SnapdLogDir and SnapdChangesLog path variables
cmd/snap/cmd_changes.go Updates help text to reference the new log file
packaging/ubuntu-16.04/snapd.dirs Adds var/log/snapd directory creation
packaging/debian-sid/snapd.dirs Adds var/log/snapd directory creation
packaging/snapd.mk Adds var/log/snapd directory creation in makefile
packaging/opensuse/snapd.spec Adds var/log/snapd directory in RPM spec
packaging/fedora/snapd.spec Adds var/log/snapd directory in RPM spec, plus whitespace cleanup

mu sync.Mutex
seenChanges map[string]ChangeInfo
changeLogPath string
retryCount map[string]int
Copy link

Copilot AI Feb 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The retryCount field is defined but never incremented. Task retry counts are tracked internally by the state machine, not by changes themselves. Since this field is unused, it should be removed along with its references at lines 153-156 in the logChange method.

Copilot uses AI. Check for mistakes.
if stat, err := os.Stat(m.changeLogPath); err == nil {
logger.Debugf("Changes log file already exists at %q (size: %d)", m.changeLogPath, stat.Size())
}

Copy link

Copilot AI Feb 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Log files can grow unbounded without rotation. The PR does not include logrotate configuration or any mechanism to prevent the changes.log file from growing indefinitely. Consider adding a logrotate configuration file in the data/ directory or documenting the need for one.

Suggested change
// Note: this manager does not implement log rotation for the changes log.
// The file at dirs.SnapdChangesLog is expected to be managed by an external
// log rotation mechanism (for example, a logrotate configuration in the
// data/ directory) to prevent unbounded growth over time.

Copilot uses AI. Check for mistakes.
Copy link
Contributor

@zyga zyga left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a much welcome improvement to the long-standing problem of changes being recycled and an absence of a retention mechanism.

I can see the following high-level questions:

  1. The format of the file. We could make it YAML-readable by making a small tweak (suggested inline)

  2. Rotation of the log. At present, AFAIK, nothing would rotate the log. We might want to ship a configuration file to ensure the file does get rotated, on classic systems, over time.

  3. Ability to enable or disable. For some systems it might be desirable to not enable this feature. I think the directory itself can be created but change retention should be governed by a core configuration toggle, similar to persistent journal or ssh. This would allow making a device that ships with this feature disabled to avoid writing to disk more.

  4. Resilience to rm -rf /var/log/snapd. I think we ought to handle mkdir in ensure, not just on manager startup.

Separately to this we would need to write a few integration tests but I'm sure we can manage that in the team as the feature is fairly isolated.

type Manager struct {
state *state.State
mu sync.Mutex
seenChanges map[string]ChangeInfo
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
seenChanges map[string]ChangeInfo
seenChanges map[string]ChangeInfo // indexed by change ID

- interfaces/u2f-devices: add Nitrokey 3
- Update the ubuntu-image channel to candidate
- Allow hostnames up to 253 characters, with dot-delimited elements
- Allow hostnames up to 253 characters, with dot-delimited elements
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is unrelated but we can handle that separately.

}

// Write blank line separator between entries
if _, err := f.WriteString("\n"); err != nil {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we use the yaml --- record separator? We could then treat the whole file as a YAML and automatically be machine readable.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems reasonable to me. My goal was to keep the file as plain-texty as possible so it wouldn't require special tools to parse and would therefore be trivially scriptable with native tools that come bundled with most distributions.

Separating by --- seems reasonable to me but do you think it's fine to keep the extension as .log and the rest of the file simple (e.g., no nested mappings, sequences, or other YAML-isms)?

@zyga zyga added the Needs Samuele review Needs a review from Samuele before it can land label Feb 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Needs Documentation -auto- Label automatically added which indicates the change needs documentation Needs Samuele review Needs a review from Samuele before it can land

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants