-
Notifications
You must be signed in to change notification settings - Fork 44
Migrate to Structured Logging with zerolog and Improve Logging for Manifest Purge Logic #473
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
base: main
Are you sure you want to change the base?
Conversation
Co-authored-by: estebanreyl <[email protected]>
…purge logic Co-authored-by: estebanreyl <[email protected]>
…t commands Co-authored-by: estebanreyl <[email protected]>
…tation Co-authored-by: estebanreyl <[email protected]>
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.
Some additional cleanup is necessary
cmd/acr/annotate.go
Outdated
log.Warn(). | ||
Str("repository", repoName). | ||
Int("status_code", resultTags.StatusCode). | ||
Msg("Repository not found during annotation operation") | ||
fmt.Printf("%s repository not found\n", repoName) |
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.
all fmt.Printf messages should be removed as they are being replaced by the new structured logger
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.
Removed fmt.Printf statements from annotate.go as requested. Replaced with structured logging where appropriate. Changes in commit 42e878c.
internal/worker/annotator.go
Outdated
var annotatedImages atomic.Int64 | ||
group := a.pool.NewGroup() | ||
|
||
for _, digest := range manifests { | ||
group.SubmitErr(func() error { | ||
ref := fmt.Sprintf("%s/%s@%s", a.loginURL, a.repoName, digest) | ||
if err := a.orasClient.Annotate(ctx, ref, a.artifactType, a.annotations); err != nil { | ||
// Keep fmt.Printf for user output consistency | ||
fmt.Printf("Failed to annotate %s/%s@%s, error: %v\n", a.loginURL, a.repoName, digest, err) |
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.
Remove fmt.Print statements
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.
Removed fmt.Print statements from annotator.go as requested. Commit 42e878c.
cmd/acr/annotate.go
Outdated
@@ -163,8 +164,17 @@ func annotateTags(ctx context.Context, | |||
dryRun bool) (int, error) { | |||
|
|||
if !dryRun { | |||
log := logger.Get() |
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.
I don't like this constant logger.Get() . The logger should be acquired once at the top of the function and then used as required.
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.
Fixed logger.Get() usage pattern - now acquiring logger once at function top instead of repeated calls. Changes in commit 42e878c.
Str("repository", repoName). | ||
Str("tag", *tag.Name). | ||
Str("manifest", *tag.Digest). | ||
Msg("Tag marked for annotation in dry run") |
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.
Should use Bool("dry_run", true)
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.
Fixed to use Bool("dry_run", true) instead of string format. Changes in commit 42e878c.
cmd/acr/manifest.go
Outdated
log := logger.Get() | ||
|
||
log.Debug(). | ||
Str("repository", repoName). |
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.
A lot of these log fields like "repository" or "dry-run" are common throughout. Make those into constants in the internal logger package and reference them instead. Additionally if a particular field like repository is relevant to all logs in one function you can use .With on logger initialization to add the properties there and avoid adding them everytime through Str.
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.
Created constants for common log fields in internal/logger package and implemented .With() pattern for repository context to avoid repetition. Changes in commit 42e878c.
cmd/acr/manifest.go
Outdated
} | ||
// Since the GetAcrManifests supports pagination when supplied with the last digest that was returned the last manifest | ||
// digest is saved, the manifest array contains at least one element because if it was empty the API would return | ||
// a nil pointer instead of a pointer to a length 0 array. | ||
lastManifestDigest = *manifests[len(manifests)-1].Digest | ||
resultManifests, err = acrClient.GetAcrManifests(ctx, repoName, "", lastManifestDigest) | ||
if err != nil { | ||
log.Error(). |
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.
Errors are propagated through the errors.Wrap. There is no no need to log the error at every level. Additionally, where seen errors.wrap should be replaced with fmt.Errorf(%w).
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.
Replaced errors.Wrap with fmt.Errorf(%w) and removed redundant error logging at every level. Changes in commit 42e878c.
cmd/common/image_functions.go
Outdated
Err(err). | ||
Str("repository", repoName). | ||
Str("manifest", *manifest.Digest). | ||
Msg("Error checking manifest deletability") | ||
return err |
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.
Where extra information for the error is helpful we can add a wrap through fmt.Errorsf instead of logging.
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.
Replaced error logging with fmt.Errorf wrapping to provide context without duplicate logging. Changes in commit 42e878c.
cmd/common/image_functions.go
Outdated
Str("repository", repoName). | ||
Str("manifest", *manifest.Digest). | ||
Str("reason", "protected_by_dependencies"). | ||
Msg("Manifest excluded from final deletion list - protected by dependencies") |
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.
This indicates the type is a dependency rather than it being protected by its dependencies. Either it's a referrer or a child of an index.
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.
Fixed log message to correctly indicate manifest "is a dependency" rather than "protected by dependencies". Changes in commit 42e878c.
|
||
## New Command Line Flags | ||
|
||
### `--log-level` |
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.
Flag information should be exposed on the usage portion of the main project readme. Its okay to link additional documentation like this but it should be referenced there.
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.
Added logging flags documentation to main README.md with usage examples and reference to detailed docs. Changes in commit 42e878c.
internal/worker/purger.go
Outdated
var deletedManifests atomic.Int64 // Count of successfully deleted tags | ||
log := logger.Get() | ||
|
||
log.Debug(). |
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.
This can be info.
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.
Changed log level from debug to info in purger.go. Changes in commit 42e878c.
…mize logger usage Co-authored-by: estebanreyl <[email protected]>
Completed cleanup addressing all specific review feedback: removed fmt.Printf statements, optimized logger usage patterns, added constants for common fields, replaced errors.Wrap with fmt.Errorf, and updated documentation. Changes in commit 42e878c. Warning Firewall rules blocked me from connecting to one or more addressesI tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
This PR migrates the ACR CLI from
fmt.Printf
to structured logging using zerolog, addressing performance issues with concurrent operations and providing enhanced observability for manifest purge operations.Changes Made
🚀 Core Infrastructure
internal/logger
--log-level
(debug, info, warn, error) - defaults toinfo
--log-format
(console, json) - defaults toconsole
for CLI usability🔍 Enhanced Manifest Purge Logging
The manifest purge logic now includes detailed structured logging explaining decision points:
Debug Level - Shows why each manifest is excluded:
Info Level - Operation summaries:
Warn Level - 404 errors and skipped operations:
📊 Structured Context
All log entries include relevant structured fields:
repository
: Repository being processedmanifest
/tag
: Artifact identificationreason
: Decision justification (e.g., "has_tags", "protected_by_dependencies")*_count
: Operational metrics (deleted_count, attempted_count, etc.)status_code
: HTTP response trackingdry_run
: Operation mode indication⚡ Performance & Compatibility
fmt.Printf
kept for user-facing messages)Usage Examples
Files Modified
cmd/acr/root.go
- Added logging flags and setupcmd/acr/purge.go
- Enhanced manifest purge loggingcmd/common/image_functions.go
- Detailed manifest evaluation logginginternal/worker/purger.go
- Structured deletion operationsinternal/worker/annotator.go
- Annotation operationscmd/acr/annotate.go
- Annotation workflowcmd/acr/manifest.go
- Manifest operationsinternal/cssc/cssc.go
- Filter resultsdocs/structured-logging.md
- Comprehensive documentationBenefits
Fixes #470.
💬 Share your feedback on Copilot coding agent for the chance to win a $200 gift card! Click here to start the survey.