Skip to content

Migrated logging and google calendar files to use slog - #40541

Merged
getvictor merged 5 commits into
mainfrom
victor/40054-slog-logging-writers
Feb 26, 2026
Merged

Migrated logging and google calendar files to use slog#40541
getvictor merged 5 commits into
mainfrom
victor/40054-slog-logging-writers

Conversation

@getvictor

@getvictor getvictor commented Feb 25, 2026

Copy link
Copy Markdown
Member

Related issue: Resolves #40540

Checklist for submitter

  • Changes file added for user-visible changes in changes/, orbit/changes/ or ee/fleetd-chrome/changes.
    • Changes present in previous PR

Testing

  • Added/updated automated tests
  • QA'd all new/changed functionality manually

Summary by CodeRabbit

  • Refactor

    • Switched the application logging to Go's standard slog with context-aware logging, improving structured logs and observability across services (status, audit, result, integrations).
    • Replaced legacy logging implementations and updated runtime wiring to propagate contextual loggers for more consistent, searchable log output.
  • Tests

    • Updated test suites to use the new slog discard/logger setup.

@getvictor

Copy link
Copy Markdown
Member Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Feb 25, 2026

Copy link
Copy Markdown
Contributor
✅ Actions performed

Full review triggered.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR continues the ongoing slog migration (part 3 of issue #40540), focusing on migrating the logging infrastructure in the server/logging package and its callers from go-kit/log to the standard library's slog package.

Changes:

  • Migrated all log writers in server/logging package to use *slog.Logger instead of *platformlogging.Logger
  • Added context.Context parameter to NewPubSubLogWriter and NewNatsLogWriter for client initialization
  • Updated all logging calls from level.Debug/Info/Error(logger).Log(...) to logger.DebugContext/InfoContext/ErrorContext(ctx, ...)

Reviewed changes

Copilot reviewed 16 out of 16 changed files in this pull request and generated no comments.

Show a summary per file
File Description
server/logging/filesystem.go Updated NewFilesystemLogWriter to accept *slog.Logger; migrated logging calls to slog
server/logging/filesystem_test.go Updated test logger initialization to use slog.New(slog.DiscardHandler)
server/logging/firehose.go Migrated firehoseLogWriter struct and functions to use *slog.Logger
server/logging/firehose_test.go Updated test logger initialization to use slog.New(slog.DiscardHandler)
server/logging/kinesis.go Migrated kinesisLogWriter struct and functions to use *slog.Logger
server/logging/kinesis_test.go Updated test logger initialization to use slog.New(slog.DiscardHandler)
server/logging/lambda.go Migrated lambdaLogWriter struct and functions to use *slog.Logger
server/logging/lambda_test.go Updated test logger initialization to use slog.New(slog.DiscardHandler)
server/logging/logging.go Updated NewJSONLogger to accept context.Context and *slog.Logger; passed context to PubSub and NATS constructors
server/logging/nats.go Added context.Context parameter to NewNatsLogWriter; migrated logging calls to slog
server/logging/nats_test.go Updated all test calls to pass context and use slog.New(slog.DiscardHandler)
server/logging/pubsub.go Added context.Context parameter to NewPubSubLogWriter; migrated logging calls to slog; removed context.Background() usage
server/logging/webhook.go Migrated webhookLogWriter struct and functions to use *slog.Logger
server/logging/webhook_test.go Updated test logger initialization to use slog.New(slog.DiscardHandler)
server/service/testing_utils.go Updated call to NewFilesystemLogWriter to use logger.SlogLogger() adapter
cmd/fleet/serve.go Updated all NewJSONLogger calls to pass cmd.Context() and use logger.SlogLogger() adapter

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@coderabbitai

coderabbitai Bot commented Feb 25, 2026

Copy link
Copy Markdown
Contributor

Walkthrough

This PR continues the migration from platform/go-kit logging to the standard library slog across the codebase. It changes logger types from the project-specific logger to *slog.Logger, adds context.Context parameters to several logging constructors (e.g., NewJSONLogger, NewNatsLogWriter, NewPubSubLogWriter), and replaces level-based calls with context-aware slog methods (InfoContext, DebugContext, ErrorContext). Tests and call sites (including cmd/fleet/serve.go and server/service/testing_utils.go) are updated to pass logger.SlogLogger() and the required context where applicable. No control-flow or error-handling logic was altered.

Possibly related PRs

  • fleetdm/fleet PR 40446: Modifies the same calendar/cron code paths and updates logging APIs to slog, including CreateUserCalendarFromConfig and GenerateCalendarEventBody call sites.
  • fleetdm/fleet PR 38751: Implements broad slog migration (logger type changes, signature updates, context propagation) that this PR builds upon.
  • fleetdm/fleet PR 40120: Updates cmd/fleet/serve.go and related logging call sites to use logger.SlogLogger() and align constructors with *slog.Logger and context parameters.
🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 10.34% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ⚠️ Warning PR description lacks required sections and detail. Missing changes file documentation, input validation notes, database migration checks, and other standard checklist items are unchecked or incomplete. Complete the PR description by: 1) Adding a 'Changes file added' section confirming whether changes files exist in changes/, orbit/changes/, or ee/fleetd-chrome/changes/; 2) Providing input validation and SQL safety details for backend changes; 3) Confirming database migration impact; 4) Documenting test coverage and manual QA results.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main objective of the changeset: migration of logging and Google Calendar files to use slog.
Linked Issues check ✅ Passed The changes comprehensively implement the slog migration objective from issue #40540 by converting all logging backends and Google Calendar integrations from platform logger to standard slog library.
Out of Scope Changes check ✅ Passed All changes are within scope: the PR consistently replaces platform logging with slog across logging packages, calendar implementations, and dependent call sites with no unrelated modifications.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch victor/40054-slog-logging-writers

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
server/logging/pubsub.go (1)

56-57: ⚠️ Potential issue | 🔴 Critical

Avoid nil-pointer panic when oversized logs are dropped.

On Line 56, results is sized to len(logs), but oversized entries continue on Line 85 without assigning results[i]. Then Line 98 calls result.Get(ctx) on nil and panics. Build results with append only for published messages.

🔧 Proposed fix
 func (w *pubSubLogWriter) Write(ctx context.Context, logs []json.RawMessage) error {
-	results := make([]*pubsub.PublishResult, len(logs))
+	results := make([]*pubsub.PublishResult, 0, len(logs))

 	// Add all of the messages to the global pubsub queue
-	for i, log := range logs {
+	for _, log := range logs {
 		data, err := log.MarshalJSON()
 		if err != nil {
 			return ctxerr.Wrap(ctx, err, "marshal message into JSON")
@@
 		message := &pubsub.Message{
 			Data:       data,
 			Attributes: attributes,
 		}

-		results[i] = w.topic.Publish(ctx, message)
+		results = append(results, w.topic.Publish(ctx, message))
 	}

Also applies to: 80-85, 97-99

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@server/logging/pubsub.go` around lines 56 - 57, The slice results is
pre-sized to len(logs) and later some log entries are skipped (continue),
leaving nil entries which cause a nil-pointer panic when calling Get on them;
change the code that creates and populates results so you only append a
PublishResult when you actually call pubsub.Publish (i.e., replace indexed
assignment results[i] = ... with results = append(results, res)), and when
iterating results call Get on every element (or check for nil before calling) to
avoid dereferencing nil; update any loops that assumed results length equals
len(logs) (e.g., the publish loop and the subsequent Get loop) to use the new
results slice.
🧹 Nitpick comments (1)
server/logging/filesystem.go (1)

56-63: context.TODO() in the SIGHUP goroutine is acceptable but could be improved.

Since the goroutine runs for the lifetime of the process with no cancellation path, context.TODO() is correct here. A minor improvement would be to thread in a context from NewFilesystemLogWriter and use it for both log calls and goroutine lifetime, but that is non-trivial and not required.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@server/logging/filesystem.go` around lines 56 - 63, The goroutine handling
SIGHUP currently uses context.TODO() for appLogger.ErrorContext and has no
cancellation; update NewFilesystemLogWriter to accept a context (or add a
context field to the filesystem log writer struct), store it on the fs writer,
and replace context.TODO() with that context when calling
appLogger.ErrorContext; also use that stored ctx in the goroutine loop (select
on ctx.Done() and <-sig) so the goroutine can exit if the parent context is
cancelled while still reacting to sig and calling fsLogger.Rotate() and
appLogger.ErrorContext as before (referencing NewFilesystemLogWriter,
fsLogger.Rotate, appLogger.ErrorContext, and sig).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@server/logging/pubsub.go`:
- Around line 56-57: The slice results is pre-sized to len(logs) and later some
log entries are skipped (continue), leaving nil entries which cause a
nil-pointer panic when calling Get on them; change the code that creates and
populates results so you only append a PublishResult when you actually call
pubsub.Publish (i.e., replace indexed assignment results[i] = ... with results =
append(results, res)), and when iterating results call Get on every element (or
check for nil before calling) to avoid dereferencing nil; update any loops that
assumed results length equals len(logs) (e.g., the publish loop and the
subsequent Get loop) to use the new results slice.

---

Nitpick comments:
In `@server/logging/filesystem.go`:
- Around line 56-63: The goroutine handling SIGHUP currently uses context.TODO()
for appLogger.ErrorContext and has no cancellation; update
NewFilesystemLogWriter to accept a context (or add a context field to the
filesystem log writer struct), store it on the fs writer, and replace
context.TODO() with that context when calling appLogger.ErrorContext; also use
that stored ctx in the goroutine loop (select on ctx.Done() and <-sig) so the
goroutine can exit if the parent context is cancelled while still reacting to
sig and calling fsLogger.Rotate() and appLogger.ErrorContext as before
(referencing NewFilesystemLogWriter, fsLogger.Rotate, appLogger.ErrorContext,
and sig).

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c44998b and 64a85c2.

📒 Files selected for processing (16)
  • cmd/fleet/serve.go
  • server/logging/filesystem.go
  • server/logging/filesystem_test.go
  • server/logging/firehose.go
  • server/logging/firehose_test.go
  • server/logging/kinesis.go
  • server/logging/kinesis_test.go
  • server/logging/lambda.go
  • server/logging/lambda_test.go
  • server/logging/logging.go
  • server/logging/nats.go
  • server/logging/nats_test.go
  • server/logging/pubsub.go
  • server/logging/webhook.go
  • server/logging/webhook_test.go
  • server/service/testing_utils.go

@codecov

codecov Bot commented Feb 25, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 55.10204% with 22 lines in your changes missing coverage. Please review.
✅ Project coverage is 66.30%. Comparing base (e0169fb) to head (a1bd35a).
⚠️ Report is 8 commits behind head on main.

Files with missing lines Patch % Lines
server/logging/logging.go 0.00% 5 Missing ⚠️
server/logging/nats.go 42.85% 4 Missing ⚠️
cmd/fleet/serve.go 0.00% 3 Missing ⚠️
server/logging/pubsub.go 0.00% 3 Missing ⚠️
server/logging/lambda.go 0.00% 2 Missing ⚠️
ee/server/calendar/google_calendar_load.go 0.00% 1 Missing ⚠️
ee/server/calendar/google_calendar_mock.go 85.71% 1 Missing ⚠️
server/logging/filesystem.go 50.00% 1 Missing ⚠️
server/logging/firehose.go 50.00% 1 Missing ⚠️
server/logging/kinesis.go 50.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #40541      +/-   ##
==========================================
+ Coverage   66.29%   66.30%   +0.01%     
==========================================
  Files        2466     2466              
  Lines      197559   197514      -45     
  Branches     8764     8742      -22     
==========================================
- Hits       130964   130963       -1     
+ Misses      54748    54704      -44     
  Partials    11847    11847              
Flag Coverage Δ
backend 68.18% <55.10%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@getvictor getvictor changed the title Migrated logging infrastructure to use slog Migrated logging and google calendar files to use slog Feb 25, 2026
@getvictor
getvictor requested a review from Copilot February 25, 2026 21:30
@getvictor

Copy link
Copy Markdown
Member Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Feb 25, 2026

Copy link
Copy Markdown
Contributor
✅ Actions performed

Full review triggered.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 24 out of 24 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
server/logging/pubsub.go (1)

80-85: ⚠️ Potential issue | 🔴 Critical

Potential panic when dropping oversized Pub/Sub logs.

At Line 83, string(log[:100]) can panic if payload is shorter than 100 bytes (the limit at Line 80 can be exceeded by attributes alone). Also, the continue at Line 85 leaves nil slots in results, and Line 98 can then dereference nil via result.Get(ctx).

🐛 Proposed fix
 func (w *pubSubLogWriter) Write(ctx context.Context, logs []json.RawMessage) error {
-	results := make([]*pubsub.PublishResult, len(logs))
+	results := make([]*pubsub.PublishResult, 0, len(logs))

 	// Add all of the messages to the global pubsub queue
-	for i, log := range logs {
+	for _, log := range logs {
 		data, err := log.MarshalJSON()
 		if err != nil {
 			return ctxerr.Wrap(ctx, err, "marshal message into JSON")
 		}
@@
 		if len(data)+estimateAttributeSize(attributes) > pubsub.MaxPublishRequestBytes {
+			previewLen := len(log)
+			if previewLen > 100 {
+				previewLen = 100
+			}
 			w.logger.InfoContext(ctx, "dropping log over 10MB PubSub limit",
 				"size", len(data),
-				"log", string(log[:100])+"...",
+				"log", string(log[:previewLen])+"...",
 			)
 			continue
 		}
@@
-		results[i] = w.topic.Publish(ctx, message)
+		results = append(results, w.topic.Publish(ctx, message))
 	}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@server/logging/pubsub.go` around lines 80 - 85, The code can panic when
building the preview string and leaves nil entries in results causing a nil
deref at result.Get(ctx); fix by (1) safely slicing the log preview (e.g., use
preview := string(log[:min(100, len(log))])) before calling w.logger.InfoContext
and (2) instead of continue, set results[i] to a completed failed publish result
so later result.Get(ctx) is safe (implement a small helper like
failedPublishResult(err) that returns a PublishResult whose Get(ctx) returns the
error and assign results[i] = failedPublishResult(fmt.Errorf("dropped oversized
log"))) so the loop never leaves nil in results. Ensure you reference the same
variables: data, attributes, log, results, and result.Get(ctx).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@server/logging/pubsub.go`:
- Around line 80-85: The code can panic when building the preview string and
leaves nil entries in results causing a nil deref at result.Get(ctx); fix by (1)
safely slicing the log preview (e.g., use preview := string(log[:min(100,
len(log))])) before calling w.logger.InfoContext and (2) instead of continue,
set results[i] to a completed failed publish result so later result.Get(ctx) is
safe (implement a small helper like failedPublishResult(err) that returns a
PublishResult whose Get(ctx) returns the error and assign results[i] =
failedPublishResult(fmt.Errorf("dropped oversized log"))) so the loop never
leaves nil in results. Ensure you reference the same variables: data,
attributes, log, results, and result.Get(ctx).

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c44998b and 174b472.

📒 Files selected for processing (24)
  • cmd/fleet/serve.go
  • ee/server/calendar/google_calendar.go
  • ee/server/calendar/google_calendar_integration_test.go
  • ee/server/calendar/google_calendar_load.go
  • ee/server/calendar/google_calendar_mock.go
  • ee/server/calendar/google_calendar_test.go
  • ee/server/service/calendar.go
  • server/cron/calendar_cron.go
  • server/logging/filesystem.go
  • server/logging/filesystem_test.go
  • server/logging/firehose.go
  • server/logging/firehose_test.go
  • server/logging/kinesis.go
  • server/logging/kinesis_test.go
  • server/logging/lambda.go
  • server/logging/lambda_test.go
  • server/logging/logging.go
  • server/logging/nats.go
  • server/logging/nats_test.go
  • server/logging/pubsub.go
  • server/logging/webhook.go
  • server/logging/webhook_test.go
  • server/service/calendar/calendar.go
  • server/service/testing_utils.go

Resolved conflict in server/logging/webhook.go where
PostJSONWithTimeout gained a logger parameter on main.
@getvictor
getvictor marked this pull request as ready for review February 25, 2026 22:15
@getvictor
getvictor requested a review from a team as a code owner February 25, 2026 22:15

@mostlikelee mostlikelee left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Looks good, just one comment around a TODO context

Comment thread server/logging/filesystem.go Outdated
<-sig // block on signal
if err := fsLogger.Rotate(); err != nil {
appLogger.Log("err", err)
appLogger.ErrorContext(context.TODO(), "log rotation error", "err", err)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

do we need to pass a context into the parent func signature?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Yes, that's an easy change. I'll make it.

@getvictor
getvictor merged commit 77eb458 into main Feb 26, 2026
49 checks passed
@getvictor
getvictor deleted the victor/40054-slog-logging-writers branch February 26, 2026 18:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

slog migration (3)

3 participants