Skip to content

fix(telemetry): prevent PostHog errors from leaking to user output#1491

Merged
osterman merged 17 commits intomainfrom
feature/dev-3633-handle-telemetry-issues-with-posthog-to-avoid-user-impact
Sep 22, 2025
Merged

fix(telemetry): prevent PostHog errors from leaking to user output#1491
osterman merged 17 commits intomainfrom
feature/dev-3633-handle-telemetry-issues-with-posthog-to-avoid-user-impact

Conversation

@osterman
Copy link
Member

@osterman osterman commented Sep 22, 2025

what

  • Add custom PostHog logger adapter that integrates with Atmos's structured logging system
  • Route PostHog error messages to debug level instead of letting them print directly to stderr
  • Add configuration option (telemetry.posthog_logging) to control PostHog internal logging
  • Implement SilentLogger that completely suppresses PostHog messages when logging is disabled
  • Add comprehensive unit tests and documentation for the new telemetry logging features

why

  • PostHog errors (like "502 Bad Gateway") were appearing in user output and breaking CLI tests
  • PostHog was using its own internal logger that wrote directly to stderr, bypassing Atmos's logging controls
  • Telemetry failures should be transparent to users and not impact their experience
  • Users need ability to debug telemetry issues when setting up their own PostHog instances
  • Error messages need to follow Atmos's structured logging conventions for consistency

It was failing builds due to snapshots changing.

"/Users/runner/work/atmos/atmos/tests/snapshots/TestCLICommands_atmos_--help.stdout.golden":
        --- expected
        +++ actual
        @@ -1 +1,7 @@
        +posthog 2025/09/21 23:37:14 INFO: response 502 502 Bad Gateway – <html>

        +<head><title>502 Bad Gateway</title></head>

        +<body>

        +<center><h1>502 Bad Gateway</h1></center>

        +</body>

        +</html>

        +posthog 2025/09/21 23:37:14 ERROR: 1 messages dropped because they failed to be sent and the client was closed

Solution Details

Custom Logger System

Created two logger implementations:

  • PosthogLogger: Routes PostHog messages through Atmos's structured logging at DEBUG level
  • SilentLogger: Completely suppresses all PostHog internal messages (default behavior)

New Configuration Option

Added telemetry.posthog_logging setting:

  • false (default): Uses SilentLogger to suppress all PostHog internal messages
  • true: Uses PosthogLogger to route messages through Atmos logging at DEBUG level
  • Can be set via atmos.yaml or ATMOS_TELEMETRY_POSTHOG_LOGGING environment variable

Behavior at Different Log Levels

When posthog_logging: true:

  • Info Level (default): PostHog messages are hidden from users
  • Debug Level: PostHog messages appear with proper structured logging format

When posthog_logging: false (default):

  • All PostHog internal messages are completely suppressed regardless of log level

Test Coverage

Added comprehensive unit tests that verify:

  • Logger selection based on configuration
  • Logger methods work correctly with structured output
  • Errors only appear at debug level when logging is enabled
  • PostHog errors don't leak to stderr in production
  • SilentLogger suppresses all messages
  • Configuration loading from both file and environment variables

Documentation

Updated telemetry documentation to explain:

  • New posthog_logging configuration option
  • When to enable PostHog internal logging
  • How to configure via both atmos.yaml and environment variables

references

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Configurable internal telemetry logging with a PostHog logger and a silent/no-op mode; new telemetry Options include logging.
  • Bug Fixes

    • Prevented internal telemetry errors from leaking to stdout/stderr and reduced noise by adjusting log levels.
  • Improvements

    • Telemetry accepts structured options, enqueues events (sent on Close), uses safer client cleanup, and updates messaging to "enqueued".
  • Tests

    • Expanded coverage for logger selection, log-level behavior, env/config flag handling, enqueue/close paths, and no-stderr pollution.
  • Documentation

    • Added telemetry logging configuration docs and fixed a typo.

- Add custom PosthogLogger adapter to integrate with Atmos logging
- Redirect PostHog errors to debug level instead of stdout/stderr
- Ensure telemetry failures don't impact user experience
- Add unit tests to verify logger behavior
- Fix issue where PostHog was logging directly to stderr

This addresses the issue where PostHog errors like '502 Bad Gateway' were appearing
in user output and breaking CLI tests. Now all PostHog errors are properly handled
through our logging system and only appear at debug level.

Fixes DEV-3633

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
@osterman osterman requested a review from a team as a code owner September 22, 2025 03:24
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 22, 2025

📝 Walkthrough

Walkthrough

Adds PostHog and Silent loggers, threads a telemetry logging flag through config/schema/env into Telemetry via a new Options struct, updates NewTelemetry signature, routes PostHog internal logs through the selected logger at DEBUG, updates tests/snapshots, and documents the logging option.

Changes

Cohort / File(s) Summary
PostHog logger implementation
pkg/telemetry/posthog_logger.go
New PosthogLogger and SilentLogger types with constructors (NewPosthogLogger, NewSilentLogger) and methods Debugf/Logf/Warnf/Errorf/Infof/Printf to route PostHog internal logs through Atmos structured logging or discard them.
PostHog logger tests
pkg/telemetry/posthog_logger_test.go
Tests covering logger behavior, level-gating, posthog metadata inclusion, stderr-pollution checks, and SilentLogger no-op behavior.
Telemetry core
pkg/telemetry/telemetry.go
Adds Options struct, stores logging on Telemetry, changes NewTelemetry to accept Options, selects logger based on Options.Logging, downgrades some PostHog client logs to DEBUG, nil-safe deferred Close, and changes message to "Telemetry event enqueued".
Telemetry tests & selection
pkg/telemetry/telemetry_test.go, pkg/telemetry/telemetry_logger_selection_test.go
Tests updated to new NewTelemetry signature and gomock.Any() config expectations; new tests verify logger selection for logging enabled/disabled and constructor behaviors.
Telemetry utils & tests
pkg/telemetry/utils.go, pkg/telemetry/utils_test.go
Propagate logging from config/env into Options passed to NewTelemetry; add tests for ATMOS_TELEMETRY_LOGGING behavior and capture flows.
Config/schema changes
pkg/config/atmos.yaml, pkg/config/load.go, pkg/schema/schema.go
Adds settings.telemetry.logging to template, binds ATMOS_TELEMETRY_LOGGING env var, and adds Logging bool to TelemetrySettings schema.
Snapshots & docs
tests/snapshots/*, website/docs/cli/telemetry.mdx
Update snapshot expectations to "Telemetry event enqueued", add telemetry.logging: false to generated outputs, mask PostHog token in snapshots, fix typo and document telemetry logging config/env var.
Sanitization
tests/cli_test.go
Added masking of PostHog tokens (regex phc_[A-Za-z0-9_]+phc_TEST_TOKEN_PLACEHOLDER) in snapshot sanitization.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User
  participant CLI as Atmos CLI
  participant Telemetry as Telemetry Module
  participant PH as PostHog Client
  participant Logger as Selected Logger

  User->>CLI: run command
  CLI->>Telemetry: Capture(event)
  Telemetry->>PH: NewClient(token, Config{Logger: Logger})
  note right of Logger #E8F5E9: Logger = PosthogLogger (routes to Atmos log)\nor SilentLogger (no-op)
  PH->>Logger: emit internal logs
  Logger->>Telemetry: route messages (DEBUG, with posthog tags or no-op)
  Telemetry->>PH: Enqueue(event)
  CLI->>Telemetry: exit -> Close()
  Telemetry->>PH: Flush/send queued events
  PH->>Logger: emit send result logs
  Logger->>CLI: debug-level output only (if enabled)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested labels

minor

Suggested reviewers

  • aknysh

Pre-merge checks and finishing touches

✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title "fix(telemetry): prevent PostHog errors from leaking to user output" is concise and directly describes the primary change in the diff—preventing PostHog internal errors from appearing in CLI output—matching the added SilentLogger/PosthogLogger, config flag, and tests that suppress or reroute PostHog output. It is specific, uses a conventional scope prefix (fix(telemetry)), and avoids noisy details. A reviewer scanning history will understand the main intent from the title alone.
Linked Issues Check ✅ Passed The changes implement the coding objectives of DEV-3633: PostHog output is routed through Atmos logging or fully suppressed via the new PosthogLogger and SilentLogger, the telemetry constructor accepts an Options logging flag and uses the selected logger when creating the PostHog client, direct stderr writes were replaced with structured debug logging, and multiple tests (including PreventStderrPollution and logger-selection tests) verify suppression and debug-only visibility; documentation and snapshot updates accompany the change. These code-level measures address the linked issue's goals to prevent telemetry failures from leaking to users and tests while allowing diagnostic output at higher verbosity. One minor ambiguity remains around naming (PR text mentions posthog_logging / ATMOS_TELEMETRY_POSTHOG_LOGGING while code and docs show telemetry.logging / ATMOS_TELEMETRY_LOGGING); confirm naming consistency between code, docs, and issue text.
Out of Scope Changes Check ✅ Passed All modified files are related to telemetry, configuration, tests, docs, or test snapshot sanitization (masking PostHog tokens), so no unrelated subsystems were touched; the primary visible broader effect is the new Options type and the changed NewTelemetry signature, which are telemetry-scoped API adjustments rather than unrelated changes. Test and snapshot updates, plus the sanitizeOutput token masking, are appropriate for the objective of preventing leaks and keeping tests stable. Reviewers should still verify callers of NewTelemetry outside this patch are updated and that the signature change is documented if it affects consumers.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/dev-3633-handle-telemetry-issues-with-posthog-to-avoid-user-impact

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 0e0c5cb and 5ece89c.

📒 Files selected for processing (2)
  • tests/cli_test.go (1 hunks)
  • website/docs/cli/telemetry.mdx (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • tests/cli_test.go
  • website/docs/cli/telemetry.mdx
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: Build (ubuntu-latest, linux)
  • GitHub Check: Build (windows-latest, windows)
  • GitHub Check: Build (macos-latest, macos)
  • GitHub Check: Lint (golangci)
  • GitHub Check: Analyze (go)
  • GitHub Check: website-deploy-preview
  • GitHub Check: Summary

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.

@github-actions github-actions bot added the size/m Medium size PR label Sep 22, 2025
autofix-ci bot and others added 5 commits September 22, 2025 03:25
- Use log.With('component', 'posthog') to add context to all PostHog messages
- Remove redundant message prefixes since component context identifies the source
- Add 'posthog_level' field to preserve PostHog's original log level in errors
- Update tests to verify component context appears in all log messages
- Ensure logger instances are created after log level changes in tests

This improves on the previous fix by using proper structured logging context
instead of message prefixes, making logs more consistent with Atmos conventions.
- Replace log.With('component', 'posthog') with log.WithPrefix('posthog')
- Cleaner output format: 'DEBU posthog: message' instead of K/V pairs
- Fix misleading 'Telemetry event captured' message timing
- Change to 'Telemetry event enqueued' since actual send happens on Close()
- Update tests to verify prefix appears in log output

This provides cleaner, more readable log output while still clearly
identifying PostHog messages with the 'posthog:' prefix.
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Caution

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

⚠️ Outside diff range comments (4)
pkg/telemetry/telemetry_test.go (3)

316-375: Gate live PostHog integration test behind flag/env and avoid hardcoded token.

Avoid external calls in unit CI and don’t commit secrets. Skip unless explicitly enabled and read token from env.

Apply:

 func TestTelemetryPosthogIntegrationCaptureMethod(t *testing.T) {
-	// Use test PostHog integration token and valid endpoint.
-	token := TestPosthogIntegrationToken
+	if testing.Short() || os.Getenv("ATMOS_RUN_POSTHOG_INTEGRATION") != "1" {
+		t.Skipf("Skipping PostHog integration test (set ATMOS_RUN_POSTHOG_INTEGRRATION=1 to run).")
+	}
+	token := os.Getenv("POSTHOG_TEST_TOKEN")
+	if token == "" {
+		t.Skipf("Skipping: POSTHOG_TEST_TOKEN is not set.")
+	}
 	endpoint := "https://us.i.posthog.com/"

And add import:

 import (
 	"errors"
 	"fmt"
+	"os"
 	"math/rand/v2"
 	"runtime"
 	"testing"
 )

382-387: Same gating for wrong-endpoint integration test.

Mirror the guard and env handling here to prevent network calls by default.

 func TestTelemetryPosthogIntegrationWrongEndpointCaptureMethod(t *testing.T) {
-	// Use test PostHog integration token but with incorrect endpoint.
-	token := TestPosthogIntegrationToken
+	if testing.Short() || os.Getenv("ATMOS_RUN_POSTHOG_INTEGRATION") != "1" {
+		t.Skipf("Skipping PostHog integration test (set ATMOS_RUN_POSTHOG_INTEGRATION=1 to run).")
+	}
+	token := os.Getenv("POSTHOG_TEST_TOKEN")
+	if token == "" {
+		t.Skipf("Skipping: POSTHOG_TEST_TOKEN is not set.")
+	}

32-32: Add ctrl.Finish (use t.Cleanup) after creating gomock controllers

Unmet/overmet gomock expectations won't fail tests unless the controller is finished—add t.Cleanup(ctrl.Finish) (or defer ctrl.Finish) immediately after each controller creation.

  • Affected call sites (fix these):
    • pkg/telemetry/telemetry_test.go — lines: 32, 75, 121, 171, 222, 274, 326, 392
    • pkg/telemetry/utils_test.go — lines: 27, 65, 114, 155, 178, 214, 270, 326, 389, 419
  • Also convert inline uses like pager.NewMockPageCreator(gomock.NewController(t)) (e.g., internal/exec/describe_dependents_test.go at 132, 213, 261) to an assigned controller and finish it.

Apply this diff at each site:

 ctrl := gomock.NewController(t)
+ t.Cleanup(ctrl.Finish)
pkg/telemetry/telemetry.go (1)

54-56: Fix properties type mismatch (compile-time).

posthog.Capture.Properties is posthog.Properties; tests pass posthog.Properties. Current signature takes map[string]interface{}.

-// Capture sends a telemetry event to PostHog with the given event name and properties.
+// Capture sends a telemetry event to PostHog with the given event name and properties.
 func (t *Telemetry) Capture(eventName string, properties map[string]interface{}) bool {
+// Capture sends a telemetry event to PostHog with the given event name and properties.
+// properties must be posthog.Properties to match the PostHog client API.
+func (t *Telemetry) Capture(eventName string, properties posthog.Properties) bool {

Alternatively, cast at callsite:

-        Properties: properties,
+        Properties: posthog.Properties(properties),

Pick one approach and keep tests consistent (they already use posthog.Properties).

🧹 Nitpick comments (8)
pkg/telemetry/telemetry_test.go (2)

19-20: Remove hardcoded token constant.

Keep secrets out of VCS; rely on env as shown above.

-const (
-	TestPosthogIntegrationToken = "phc_7s7MrHWxPR2if1DHHDrKBRgx7SvlaoSM59fIiQueexS"
-)
+// Integration token is supplied via POSTHOG_TEST_TOKEN when tests are explicitly enabled.

26-31: Use deterministic randomness or seed.

Non-deterministic rand can complicate reproducing failures; either seed test-local RNG or use fixed values.

pkg/telemetry/telemetry.go (3)

72-77: Trap Close() errors at debug.

Silent ignore can mask flush failures; log them at debug without user impact.

-	defer func() {
-		// Ensure client close doesn't panic or output errors
-		if client != nil {
-			client.Close()
-		}
-	}()
+	defer func() {
+		// Ensure client close doesn't panic or output errors.
+		if client != nil {
+			if cerr := client.Close(); cerr != nil {
+				log.Debug("PostHog client close failed", "error", cerr)
+			}
+		}
+	}()

8-20: Deduplicate doc comments.

Two identical blocks above TelemetryClientProvider. Keep one concise godoc.

-// TelemetryClientProvider is a function type that creates a PostHog client
-// given a token and configuration. This allows for dependency injection
-// and easier testing by providing mock implementations.
-// TelemetryClientProvider is a function type that creates a PostHog client
-// given a token and configuration. The configuration is passed by pointer to
-// avoid copying large structs and to allow tests to modify it.
+// TelemetryClientProvider creates a PostHog client given a token and configuration.
+// The configuration is passed by pointer to avoid copying and to allow tests to modify it.

48-53: Godot: end comments with periods.

Several comment lines end without periods; golangci-lint (godot) will complain.

Also applies to: 79-81, 91-93

pkg/telemetry/posthog_logger_test.go (2)

84-103: Restore original log level in SilentLogger test.

Avoid cross-test level bleed.

 func TestSilentLogger(t *testing.T) {
-	defer log.SetOutput(io.Discard) // Reset output after test
+	defer log.SetOutput(io.Discard) // Reset output after test
+	orig := log.GetLevel()
+	defer log.SetLevel(orig)

105-127: Same: restore level in DiscardLogger test.

 func TestDiscardLogger(t *testing.T) {
-	defer log.SetOutput(io.Discard) // Reset output after test
+	defer log.SetOutput(io.Discard) // Reset output after test
+	orig := log.GetLevel()
+	defer log.SetLevel(orig)
pkg/telemetry/posthog_logger.go (1)

25-30: Godot: add periods to inline comments.

Several comment lines are missing trailing periods; fix to satisfy golangci-lint godot.

-	// Convert printf-style to structured logging
+	// Convert printf-style to structured logging.
-	// Convert printf-style to structured logging at debug level
-	// to avoid cluttering user output with telemetry info
+	// Convert printf-style to structured logging at debug level.
+	// To avoid cluttering user output with telemetry info.
-	// Convert printf-style to structured logging
+	// Convert printf-style to structured logging.
-	// Only log PostHog errors at debug level to avoid polluting user output.
-	// Telemetry failures should not impact the user experience.
+	// Only log PostHog errors at debug level to avoid polluting user output.
+	// Telemetry failures should not impact the user experience.

Also applies to: 36-40, 44-47, 52-56

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 3e2ed8a and de724ec.

📒 Files selected for processing (4)
  • pkg/telemetry/posthog_logger.go (1 hunks)
  • pkg/telemetry/posthog_logger_test.go (1 hunks)
  • pkg/telemetry/telemetry.go (2 hunks)
  • pkg/telemetry/telemetry_test.go (8 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.go

📄 CodeRabbit inference engine (.cursor/rules/atmos-rules.mdc)

**/*.go: Use Viper for managing configuration, environment variables, and flags
Use interfaces for external dependencies to facilitate mocking
All code must pass golangci-lint checks
Follow Go's error handling idioms
Use meaningful error messages
Wrap errors with context using fmt.Errorf("context: %w", err)
Consider using a custom error type for domain-specific errors
Follow standard Go coding style
Use gofmt and goimports to format code
Prefer short, descriptive variable names
Use snake_case for environment variables
Document all exported functions, types, and methods
Document complex logic with inline comments
Follow Go's documentation conventions
Use Viper for configuration management
Support configuration via files, environment variables, and flags
Follow the precedence order: flags > environment variables > config file > defaults

**/*.go: All comments in Go code must end with periods (enforced by golangci-lint godot).
Wrap all returned errors using static errors from the errors package; never return dynamic errors directly.
Always bind environment variables with viper.BindEnv() and provide ATMOS_ alternatives for each external var.
Separate structured logging from UI output: use stderr for prompts/errors to user; stdout only for data; never use logging for UI.
Most text UI must go to stderr; only data/results to stdout. Prefer utils.PrintfMessageToTUI for UI messages.
For non-standard execution paths, capture telemetry with telemetry.CaptureCmd or telemetry.CaptureCmdString and never capture user data.
Ensure cross-platform compatibility: prefer SDKs to external binaries, use filepath/os/runtime for portability, and add build constraints when needed.

Files:

  • pkg/telemetry/posthog_logger_test.go
  • pkg/telemetry/telemetry.go
  • pkg/telemetry/posthog_logger.go
  • pkg/telemetry/telemetry_test.go
**/*_test.go

📄 CodeRabbit inference engine (.cursor/rules/atmos-rules.mdc)

**/*_test.go: Every new feature must include comprehensive unit tests
Test both happy paths and error conditions
Use table-driven tests for testing multiple scenarios
Include integration tests for command flows
Test CLI end-to-end when possible
Use test fixtures for complex inputs
Consider using testify/mock for creating mock implementations

**/*_test.go: Always use t.Skipf() with a reason for skipped tests; never use t.Skip() or reasonless t.Skipf().
Test files must mirror implementation structure and naming (e.g., aws_ssm_store_test.go).
Use table-driven unit tests and mock interfaces for external dependencies; target >80% coverage.

Files:

  • pkg/telemetry/posthog_logger_test.go
  • pkg/telemetry/telemetry_test.go
pkg/**/*_test.go

📄 CodeRabbit inference engine (CLAUDE.md)

Unit tests reside under pkg/ alongside implementations.

Files:

  • pkg/telemetry/posthog_logger_test.go
  • pkg/telemetry/telemetry_test.go
🧠 Learnings (4)
📚 Learning: 2025-07-01T02:22:25.901Z
Learnt from: CR
PR: cloudposse/atmos#0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-07-01T02:22:25.901Z
Learning: Applies to **/*_test.go : Every new feature must include comprehensive unit tests

Applied to files:

  • pkg/telemetry/posthog_logger_test.go
📚 Learning: 2025-07-01T02:22:25.901Z
Learnt from: CR
PR: cloudposse/atmos#0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-07-01T02:22:25.901Z
Learning: Applies to **/*_test.go : Test both happy paths and error conditions

Applied to files:

  • pkg/telemetry/posthog_logger_test.go
📚 Learning: 2025-07-01T02:22:25.901Z
Learnt from: CR
PR: cloudposse/atmos#0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-07-01T02:22:25.901Z
Learning: Applies to **/*_test.go : Consider using testify/mock for creating mock implementations

Applied to files:

  • pkg/telemetry/telemetry_test.go
📚 Learning: 2025-09-07T15:13:17.831Z
Learnt from: CR
PR: cloudposse/atmos#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-07T15:13:17.831Z
Learning: Applies to **/*_test.go : Use table-driven unit tests and mock interfaces for external dependencies; target >80% coverage.

Applied to files:

  • pkg/telemetry/telemetry_test.go
🧬 Code graph analysis (3)
pkg/telemetry/posthog_logger_test.go (1)
pkg/telemetry/posthog_logger.go (3)
  • NewPosthogLogger (19-23)
  • NewSilentLogger (63-65)
  • NewDiscardLogger (90-92)
pkg/telemetry/telemetry.go (1)
pkg/telemetry/posthog_logger.go (1)
  • NewPosthogLogger (19-23)
pkg/telemetry/posthog_logger.go (1)
pkg/logger/logger.go (1)
  • Logger (32-35)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: Build (ubuntu-latest, linux)
  • GitHub Check: Build (windows-latest, windows)
  • GitHub Check: Analyze (go)
  • GitHub Check: Lint (golangci)
  • GitHub Check: Summary
🔇 Additional comments (8)
pkg/telemetry/telemetry_test.go (2)

39-39: Good swap to gomock.Any() for config arg.

This decouples tests from posthog.Config internals while keeping call counts precise.

Also applies to: 82-83, 128-128, 178-178, 229-229, 281-281, 333-333, 399-399


3-15: Confirmed — go.mod declares go 1.24.6 (>=1.22). math/rand/v2 is supported; no change required.

pkg/telemetry/telemetry.go (1)

61-66: Nice: inject custom PostHog logger.

This prevents stderr pollution and respects global log levels.

Confirm whether PostHog emits network issues via Warnf; if so, consider demoting Warnf to Debug to keep default/info clean.

pkg/telemetry/posthog_logger_test.go (2)

12-49: Solid coverage of log methods.

Assertions catch prefix and error-level tagging.


129-171: Great: validates no stderr pollution at INFO, visible at DEBUG with metadata.

Matches PR objectives.

pkg/telemetry/posthog_logger.go (3)

20-23: Prefix-based default logger is fine.

Works with global level/output and keeps messages scoped.


33-40: Consider demoting Warnf to Debug (verify first).

If PostHog uses Warnf for transient network issues, these would surface at default/info. Demote to Debug if that happens in practice.


58-66: No-op loggers look good.

Silent/Discard implementations are simple and safe. Keep.

Also applies to: 94-108

coderabbitai[bot]
coderabbitai bot previously approved these changes Sep 22, 2025
… logging

- Add `logging` field to TelemetrySettings to control PostHog SDK logging
- Default to false for cleaner user experience
- PostHog SDK uses SilentLogger when logging=false (default)
- PostHog SDK uses PosthogLogger when logging=true
- Support environment variable ATMOS_TELEMETRY_LOGGING
- Remove omitempty tag from logging field to ensure consistent serialization
- Add comprehensive tests for logging configuration
- Telemetry collection remains independent of logging setting

This allows users to keep telemetry enabled while suppressing PostHog's
internal debug messages (network errors, buffer status, etc.) that can
clutter logs. Users can enable PostHog logging when debugging telemetry
issues by setting telemetry.logging=true or ATMOS_TELEMETRY_LOGGING=true.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
@github-actions github-actions bot added size/l Large size PR and removed size/m Medium size PR labels Sep 22, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (9)
pkg/schema/schema.go (1)

253-254: Make logging tag consistent with other telemetry fields.

To avoid emitting logging: false on marshal and to match neighboring tags, add omitempty.

-   Logging  bool   `yaml:"logging" json:"logging" mapstructure:"logging"`
+   Logging  bool   `yaml:"logging,omitempty" json:"logging,omitempty" mapstructure:"logging"`
pkg/telemetry/telemetry_logger_selection_test.go (2)

16-40: Deduplicate the two subtests to satisfy dupl lint and reduce noise.

Refactor into a small helper; keep assertions unchanged.

 func TestTelemetryLoggerSelectionBasedOnFlag(t *testing.T) {
-	// Test with logging enabled - should use PosthogLogger
-	t.Run("LoggingEnabled", func(t *testing.T) {
-		ctrl := gomock.NewController(t)
-		defer ctrl.Finish()
-
-		// Create a custom mock provider to inspect the config
-		var capturedConfig *posthog.Config
-		mockProvider := func(token string, config *posthog.Config) (posthog.Client, error) {
-			capturedConfig = config
-			mockClient := mock_telemetry.NewMockClient(ctrl)
-			mockClient.EXPECT().Enqueue(gomock.Any()).Return(nil).Times(1)
-			mockClient.EXPECT().Close().Return(nil).Times(1)
-			return mockClient, nil
-		}
-
-		// Create telemetry with logging enabled
-		telemetry := NewTelemetry(true, "test-token", "https://test.com", "test-id", true, mockProvider)
-		success := telemetry.Capture("test", map[string]interface{}{})
-
-		assert.True(t, success)
-		assert.NotNil(t, capturedConfig)
-		assert.NotNil(t, capturedConfig.Logger)
-		// Verify it's a PosthogLogger by checking type
-		_, isPosthogLogger := capturedConfig.Logger.(*PosthogLogger)
-		assert.True(t, isPosthogLogger, "Should use PosthogLogger when logging is enabled")
-	})
-
-	// Test with logging disabled - should use SilentLogger
-	t.Run("LoggingDisabled", func(t *testing.T) {
-		ctrl := gomock.NewController(t)
-		defer ctrl.Finish()
-
-		// Create a custom mock provider to inspect the config
-		var capturedConfig *posthog.Config
-		mockProvider := func(token string, config *posthog.Config) (posthog.Client, error) {
-			capturedConfig = config
-			mockClient := mock_telemetry.NewMockClient(ctrl)
-			mockClient.EXPECT().Enqueue(gomock.Any()).Return(nil).Times(1)
-			mockClient.EXPECT().Close().Return(nil).Times(1)
-			return mockClient, nil
-		}
-
-		// Create telemetry with logging disabled
-		telemetry := NewTelemetry(true, "test-token", "https://test.com", "test-id", false, mockProvider)
-		success := telemetry.Capture("test", map[string]interface{}{})
-
-		assert.True(t, success)
-		assert.NotNil(t, capturedConfig)
-		assert.NotNil(t, capturedConfig.Logger)
-		// Verify it's a SilentLogger by checking type
-		_, isSilentLogger := capturedConfig.Logger.(*SilentLogger)
-		assert.True(t, isSilentLogger, "Should use SilentLogger when logging is disabled")
-	})
+	run := func(name string, logging bool) {
+		t.Run(name, func(t *testing.T) {
+			t.Helper()
+			ctrl := gomock.NewController(t)
+			defer ctrl.Finish()
+			var capturedConfig *posthog.Config
+			mockProvider := func(token string, config *posthog.Config) (posthog.Client, error) {
+				capturedConfig = config
+				mockClient := mock_telemetry.NewMockClient(ctrl)
+				mockClient.EXPECT().Enqueue(gomock.Any()).Return(nil).Times(1)
+				mockClient.EXPECT().Close().Return(nil).Times(1)
+				return mockClient, nil
+			}
+			telemetry := NewTelemetry(true, "test-token", "https://test.com", "test-id", logging, mockProvider)
+			success := telemetry.Capture("test", map[string]interface{}{})
+			assert.True(t, success)
+			assert.NotNil(t, capturedConfig)
+			assert.NotNil(t, capturedConfig.Logger)
+			if logging {
+				_, isPosthogLogger := capturedConfig.Logger.(*PosthogLogger)
+				assert.True(t, isPosthogLogger, "Should use PosthogLogger when logging is enabled.")
+			} else {
+				_, isSilentLogger := capturedConfig.Logger.(*SilentLogger)
+				assert.True(t, isSilentLogger, "Should use SilentLogger when logging is disabled.")
+			}
+		})
+	}
+	run("LoggingEnabled", true)
+	run("LoggingDisabled", false)
 }

Also applies to: 43-67


12-14: Fix comment periods to satisfy godot.

End sentences with periods.

-// TestTelemetryLoggerSelectionBasedOnFlag tests that the correct logger is selected
-// based on the logging flag during client creation.
+// TestTelemetryLoggerSelectionBasedOnFlag tests that the correct logger is selected.
+// It is based on the logging flag during client creation.
-// Verify it's a PosthogLogger by checking type
+// Verify it's a PosthogLogger by checking type.
-// Verify it's a SilentLogger by checking type
+// Verify it's a SilentLogger by checking type.
-// TestTelemetryConstructorWithLogging tests that the telemetry constructor correctly
-// handles the logging parameter.
+// TestTelemetryConstructorWithLogging tests that the telemetry constructor correctly.
+// It handles the logging parameter.

Also applies to: 38-38, 65-65, 70-72

pkg/telemetry/telemetry.go (2)

8-14: Remove duplicate doc comments.

Two identical comment blocks for both the type and provider are repeated back‑to‑back.

-// TelemetryClientProvider is a function type that creates a PostHog client
-// given a token and configuration. This allows for dependency injection
-// and easier testing by providing mock implementations.
-// TelemetryClientProvider is a function type that creates a PostHog client
-// given a token and configuration. The configuration is passed by pointer to
-// avoid copying large structs and to allow tests to modify it.
+// TelemetryClientProvider is a function type that creates a PostHog client given a token and configuration.
+// The configuration is passed by pointer to avoid copying and to allow tests to inspect/modify it.
 type TelemetryClientProvider func(string, *posthog.Config) (posthog.Client, error)
 
-// PosthogClientProvider is the default implementation of TelemetryClientProvider
-// that creates a real PostHog client using the provided token and configuration.
-// PosthogClientProvider is the default implementation of TelemetryClientProvider
-// that creates a real PostHog client using the provided token and configuration.
+// PosthogClientProvider is the default implementation of TelemetryClientProvider that creates a real PostHog client.
 func PosthogClientProvider(token string, config *posthog.Config) (posthog.Client, error) {

Also applies to: 16-22


63-71: Tighten comments for godot and log close errors at debug.

End sentences with periods and surface Close errors at debug without leaking to users.

-	// Create PostHog client using the provided client provider with custom logger
-	// This ensures PostHog errors don't leak to stdout/stderr
-	// Select logger based on logging configuration
+	// Create PostHog client using the provided client provider with a custom logger.
+	// This ensures PostHog errors don't leak to stdout/stderr.
+	// Select logger based on logging configuration.
 	var logger posthog.Logger
 	if t.logging {
-		logger = NewPosthogLogger() // Use our custom logger adapter that routes to Atmos logging
+		logger = NewPosthogLogger() // Use our custom logger adapter that routes to Atmos logging.
 	} else {
-		logger = NewSilentLogger() // Completely suppress PostHog internal logging
+		logger = NewSilentLogger() // Completely suppress PostHog internal logging.
 	}
@@
-	defer func() {
-		// Ensure client close doesn't panic or output errors
+	defer func() {
+		// Ensure client close doesn't panic or output errors.
 		if client != nil {
-			client.Close()
+			if cerr := client.Close(); cerr != nil {
+				log.Debug("Could not close PostHog client", "error", cerr)
+			}
 		}
 	}()
@@
-		// Log at debug level to avoid polluting user output with telemetry errors
+		// Log at debug level to avoid polluting user output with telemetry errors.
 		log.Debug("Could not enqueue event", "error", err)
 		return false
 	}
-	// Note: Event is only sent when client.Close() is called in the deferred function
-	log.Debug("Telemetry event enqueued")
+	// Note: Event is only sent when client.Close() is called in the deferred function.
+	log.Debug("Telemetry event enqueued")

Also applies to: 82-87, 97-103

pkg/telemetry/utils_test.go (2)

537-563: Consolidate logging config tests + restore env var safely.

These three tests are near-identical and can be table‑driven. Also, preserve/restore ATMOS_TELEMETRY_LOGGING to avoid cross‑test leakage.

Apply this diff to replace the three tests with one table‑driven test that restores the original env var:

-// TestGetTelemetryFromConfigWithLoggingEnabled tests that logging can be enabled via environment variable.
-func TestGetTelemetryFromConfigWithLoggingEnabled(t *testing.T) {
-  currentEnvVars := PreserveCIEnvVars()
-  defer RestoreCIEnvVars(currentEnvVars)
-
-  ctrl := gomock.NewController(t)
-  mockClientProvider := mock_telemetry.NewMockTelemetryClientProviderMock(ctrl)
-  mockClient := mock_telemetry.NewMockClient(ctrl)
-
-  // Expect no client creation since we're just testing config loading.
-  mockClientProvider.EXPECT().NewMockClient(gomock.Any(), gomock.Any()).Return(mockClient, nil).Times(0)
-  mockClient.EXPECT().Enqueue(gomock.Any()).Return(nil).Times(0)
-  mockClient.EXPECT().Close().Return(nil).Times(0)
-
-  // Enable logging via environment variable.
-  os.Setenv("ATMOS_TELEMETRY_LOGGING", "true")
-  defer os.Unsetenv("ATMOS_TELEMETRY_LOGGING")
-
-  // Get telemetry configuration.
-  telemetry := getTelemetryFromConfig(mockClientProvider.NewMockClient)
-
-  // Verify logging is enabled.
-  assert.NotNil(t, telemetry)
-  assert.True(t, telemetry.logging, "Logging should be enabled when ATMOS_TELEMETRY_LOGGING=true")
-}
-
-// TestGetTelemetryFromConfigWithLoggingDisabled tests that logging can be disabled via environment variable.
-func TestGetTelemetryFromConfigWithLoggingDisabled(t *testing.T) {
-  currentEnvVars := PreserveCIEnvVars()
-  defer RestoreCIEnvVars(currentEnvVars)
-
-  ctrl := gomock.NewController(t)
-  mockClientProvider := mock_telemetry.NewMockTelemetryClientProviderMock(ctrl)
-  mockClient := mock_telemetry.NewMockClient(ctrl)
-
-  // Expect no client creation since we're just testing config loading.
-  mockClientProvider.EXPECT().NewMockClient(gomock.Any(), gomock.Any()).Return(mockClient, nil).Times(0)
-  mockClient.EXPECT().Enqueue(gomock.Any()).Return(nil).Times(0)
-  mockClient.EXPECT().Close().Return(nil).Times(0)
-
-  // Explicitly disable logging via environment variable.
-  os.Setenv("ATMOS_TELEMETRY_LOGGING", "false")
-  defer os.Unsetenv("ATMOS_TELEMETRY_LOGGING")
-
-  // Get telemetry configuration.
-  telemetry := getTelemetryFromConfig(mockClientProvider.NewMockClient)
-
-  // Verify logging is disabled.
-  assert.NotNil(t, telemetry)
-  assert.False(t, telemetry.logging, "Logging should be disabled when ATMOS_TELEMETRY_LOGGING=false")
-}
-
-// TestGetTelemetryFromConfigWithLoggingDefault tests the default logging configuration.
-func TestGetTelemetryFromConfigWithLoggingDefault(t *testing.T) {
-  currentEnvVars := PreserveCIEnvVars()
-  defer RestoreCIEnvVars(currentEnvVars)
-
-  ctrl := gomock.NewController(t)
-  mockClientProvider := mock_telemetry.NewMockTelemetryClientProviderMock(ctrl)
-  mockClient := mock_telemetry.NewMockClient(ctrl)
-
-  // Expect no client creation since we're just testing config loading.
-  mockClientProvider.EXPECT().NewMockClient(gomock.Any(), gomock.Any()).Return(mockClient, nil).Times(0)
-  mockClient.EXPECT().Enqueue(gomock.Any()).Return(nil).Times(0)
-  mockClient.EXPECT().Close().Return(nil).Times(0)
-
-  // Ensure ATMOS_TELEMETRY_LOGGING is not set.
-  os.Unsetenv("ATMOS_TELEMETRY_LOGGING")
-
-  // Get telemetry configuration.
-  telemetry := getTelemetryFromConfig(mockClientProvider.NewMockClient)
-
-  // Verify logging defaults to false (as configured in atmos.yaml).
-  assert.NotNil(t, telemetry)
-  assert.False(t, telemetry.logging, "Logging should default to false")
-}
+func TestGetTelemetryFromConfigLoggingVariants(t *testing.T) {
+  currentEnvVars := PreserveCIEnvVars()
+  defer RestoreCIEnvVars(currentEnvVars)
+
+  ctrl := gomock.NewController(t)
+  defer ctrl.Finish()
+
+  mockClientProvider := mock_telemetry.NewMockTelemetryClientProviderMock(ctrl)
+  mockClient := mock_telemetry.NewMockClient(ctrl)
+
+  // No client creation; config‑only.
+  mockClientProvider.EXPECT().NewMockClient(gomock.Any(), gomock.Any()).Return(mockClient, nil).Times(0)
+  mockClient.EXPECT().Enqueue(gomock.Any()).Return(nil).Times(0)
+  mockClient.EXPECT().Close().Return(nil).Times(0)
+
+  cases := []struct {
+    name   string
+    hasEnv bool
+    envVal string
+    want   bool
+  }{
+    {"enabled", true, "true", true},
+    {"disabled", true, "false", false},
+    {"default", false, "", false}, // atmos.yaml default is false.
+  }
+
+  for _, tc := range cases {
+    t.Run(tc.name, func(t *testing.T) {
+      const key = "ATMOS_TELEMETRY_LOGGING"
+      old, had := os.LookupEnv(key)
+      if tc.hasEnv {
+        os.Setenv(key, tc.envVal)
+      } else {
+        os.Unsetenv(key)
+      }
+      t.Cleanup(func() {
+        if had {
+          os.Setenv(key, old)
+        } else {
+          os.Unsetenv(key)
+        }
+      })
+
+      telemetry := getTelemetryFromConfig(mockClientProvider.NewMockClient)
+      assert.NotNil(t, telemetry)
+      assert.Equal(t, tc.want, telemetry.logging, "unexpected logging value for case %q", tc.name)
+    })
+  }
+}

Also applies to: 565-589, 590-614


543-546: Finish gomock controllers.

Add deferred ctrl.Finish() to assert expectations promptly.

 ctrl := gomock.NewController(t)
+defer ctrl.Finish()

Also applies to: 569-572, 595-598, 620-623, 642-645

pkg/telemetry/telemetry_test.go (2)

333-339: Gate the networked integration test.

This creates a real client and will hit the network. Gate behind an env flag or testing.Short to avoid flaky CI.

Add at the top of the test:

if testing.Short() || os.Getenv("RUN_POSTHOG_INTEGRATION") == "" {
  t.Skipf("Skipping PostHog integration test; set RUN_POSTHOG_INTEGRATION=1 to enable.")
}

399-406: Also gate the wrong-endpoint integration test.

Same concern; guard to keep CI green when offline.

Use the same guard as suggested for the other integration test.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between de724ec and fc050e0.

📒 Files selected for processing (8)
  • pkg/config/atmos.yaml (1 hunks)
  • pkg/config/load.go (1 hunks)
  • pkg/schema/schema.go (1 hunks)
  • pkg/telemetry/telemetry.go (3 hunks)
  • pkg/telemetry/telemetry_logger_selection_test.go (1 hunks)
  • pkg/telemetry/telemetry_test.go (17 hunks)
  • pkg/telemetry/utils.go (2 hunks)
  • pkg/telemetry/utils_test.go (1 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
**/*.go

📄 CodeRabbit inference engine (.cursor/rules/atmos-rules.mdc)

**/*.go: Use Viper for managing configuration, environment variables, and flags
Use interfaces for external dependencies to facilitate mocking
All code must pass golangci-lint checks
Follow Go's error handling idioms
Use meaningful error messages
Wrap errors with context using fmt.Errorf("context: %w", err)
Consider using a custom error type for domain-specific errors
Follow standard Go coding style
Use gofmt and goimports to format code
Prefer short, descriptive variable names
Use snake_case for environment variables
Document all exported functions, types, and methods
Document complex logic with inline comments
Follow Go's documentation conventions
Use Viper for configuration management
Support configuration via files, environment variables, and flags
Follow the precedence order: flags > environment variables > config file > defaults

**/*.go: All comments in Go code must end with periods (enforced by golangci-lint godot).
Wrap all returned errors using static errors from the errors package; never return dynamic errors directly.
Always bind environment variables with viper.BindEnv() and provide ATMOS_ alternatives for each external var.
Separate structured logging from UI output: use stderr for prompts/errors to user; stdout only for data; never use logging for UI.
Most text UI must go to stderr; only data/results to stdout. Prefer utils.PrintfMessageToTUI for UI messages.
For non-standard execution paths, capture telemetry with telemetry.CaptureCmd or telemetry.CaptureCmdString and never capture user data.
Ensure cross-platform compatibility: prefer SDKs to external binaries, use filepath/os/runtime for portability, and add build constraints when needed.

Files:

  • pkg/schema/schema.go
  • pkg/telemetry/telemetry_logger_selection_test.go
  • pkg/config/load.go
  • pkg/telemetry/telemetry.go
  • pkg/telemetry/utils.go
  • pkg/telemetry/telemetry_test.go
  • pkg/telemetry/utils_test.go
**/*.{yaml,yml}

📄 CodeRabbit inference engine (CLAUDE.md)

YAML configs should support Go templating using provided template functions.

Files:

  • pkg/config/atmos.yaml
**/*_test.go

📄 CodeRabbit inference engine (.cursor/rules/atmos-rules.mdc)

**/*_test.go: Every new feature must include comprehensive unit tests
Test both happy paths and error conditions
Use table-driven tests for testing multiple scenarios
Include integration tests for command flows
Test CLI end-to-end when possible
Use test fixtures for complex inputs
Consider using testify/mock for creating mock implementations

**/*_test.go: Always use t.Skipf() with a reason for skipped tests; never use t.Skip() or reasonless t.Skipf().
Test files must mirror implementation structure and naming (e.g., aws_ssm_store_test.go).
Use table-driven unit tests and mock interfaces for external dependencies; target >80% coverage.

Files:

  • pkg/telemetry/telemetry_logger_selection_test.go
  • pkg/telemetry/telemetry_test.go
  • pkg/telemetry/utils_test.go
pkg/**/*_test.go

📄 CodeRabbit inference engine (CLAUDE.md)

Unit tests reside under pkg/ alongside implementations.

Files:

  • pkg/telemetry/telemetry_logger_selection_test.go
  • pkg/telemetry/telemetry_test.go
  • pkg/telemetry/utils_test.go
🧠 Learnings (7)
📚 Learning: 2025-08-29T20:57:35.423Z
Learnt from: osterman
PR: cloudposse/atmos#1433
File: cmd/theme_list.go:33-36
Timestamp: 2025-08-29T20:57:35.423Z
Learning: In the Atmos codebase, avoid using viper.SetEnvPrefix("ATMOS") with viper.AutomaticEnv() because canonical environment variable names are not exclusive to Atmos and could cause conflicts. Instead, use selective environment variable binding through the setEnv function in pkg/config/load.go with bindEnv(v, "config.key", "ENV_VAR_NAME") for specific environment variables.

Applied to files:

  • pkg/config/load.go
📚 Learning: 2025-09-07T15:13:17.831Z
Learnt from: CR
PR: cloudposse/atmos#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-07T15:13:17.831Z
Learning: Applies to **/*.go : Always bind environment variables with viper.BindEnv() and provide ATMOS_ alternatives for each external var.

Applied to files:

  • pkg/config/load.go
📚 Learning: 2025-04-10T20:48:22.687Z
Learnt from: samtholiya
PR: cloudposse/atmos#1147
File: pkg/config/load.go:0-0
Timestamp: 2025-04-10T20:48:22.687Z
Learning: In the `bindEnv` function in `pkg/config/load.go`, panic is used deliberately instead of returning errors because errors from `BindEnv` would only occur due to developer mistakes. Using panic helps with early detection of these developer errors during initialization.

Applied to files:

  • pkg/config/load.go
📚 Learning: 2025-04-23T15:02:50.246Z
Learnt from: osterman
PR: cloudposse/atmos#1202
File: pkg/utils/yaml_func_exec.go:104-104
Timestamp: 2025-04-23T15:02:50.246Z
Learning: In the Atmos codebase, direct calls to `os.Getenv` should be avoided. Instead, use `viper.BindEnv` for environment variable access. This provides a consistent approach to configuration management across the codebase.

Applied to files:

  • pkg/config/load.go
📚 Learning: 2025-07-01T02:22:25.901Z
Learnt from: CR
PR: cloudposse/atmos#0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-07-01T02:22:25.901Z
Learning: Applies to **/*.go : Use Viper for managing configuration, environment variables, and flags

Applied to files:

  • pkg/config/load.go
📚 Learning: 2025-07-01T02:22:25.901Z
Learnt from: CR
PR: cloudposse/atmos#0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-07-01T02:22:25.901Z
Learning: Applies to **/*.go : Use Viper for configuration management

Applied to files:

  • pkg/config/load.go
📚 Learning: 2025-09-07T15:13:17.831Z
Learnt from: CR
PR: cloudposse/atmos#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-07T15:13:17.831Z
Learning: Applies to **/*.go : For non-standard execution paths, capture telemetry with telemetry.CaptureCmd or telemetry.CaptureCmdString and never capture user data.

Applied to files:

  • pkg/telemetry/utils_test.go
🧬 Code graph analysis (5)
pkg/telemetry/telemetry_logger_selection_test.go (4)
pkg/telemetry/mock/mock_posthog_client.go (1)
  • NewMockClient (32-36)
pkg/telemetry/telemetry.go (1)
  • NewTelemetry (39-48)
pkg/telemetry/posthog_logger.go (2)
  • PosthogLogger (14-16)
  • SilentLogger (60-60)
pkg/telemetry/mock/mock_telemetry_provider.go (1)
  • NewMockTelemetryClientProviderMock (32-36)
pkg/telemetry/telemetry.go (2)
pkg/logger/logger.go (1)
  • Logger (32-35)
pkg/telemetry/posthog_logger.go (2)
  • NewPosthogLogger (19-23)
  • NewSilentLogger (63-65)
pkg/telemetry/utils.go (1)
pkg/telemetry/telemetry.go (2)
  • Telemetry (27-34)
  • NewTelemetry (39-48)
pkg/telemetry/telemetry_test.go (3)
pkg/telemetry/mock/mock_posthog_client.go (1)
  • NewMockClient (32-36)
pkg/telemetry/telemetry.go (1)
  • NewTelemetry (39-48)
pkg/telemetry/mock/mock_telemetry_provider.go (1)
  • NewMockTelemetryClientProviderMock (32-36)
pkg/telemetry/utils_test.go (3)
pkg/telemetry/ci.go (2)
  • PreserveCIEnvVars (86-115)
  • RestoreCIEnvVars (124-129)
pkg/telemetry/mock/mock_telemetry_provider.go (1)
  • NewMockTelemetryClientProviderMock (32-36)
pkg/telemetry/mock/mock_posthog_client.go (1)
  • NewMockClient (32-36)
🪛 GitHub Check: golangci-lint
pkg/telemetry/telemetry_logger_selection_test.go

[failure] 16-16:
16-40 lines are duplicate of pkg/telemetry/telemetry_logger_selection_test.go:43-67


[failure] 43-43:
43-67 lines are duplicate of pkg/telemetry/telemetry_logger_selection_test.go:16-40

pkg/telemetry/telemetry.go

[failure] 39-39:
argument-limit: maximum number of arguments per function exceeded; max 5 but got 6

pkg/telemetry/telemetry_test.go

[failure] 441-441:
441-477 lines are duplicate of pkg/telemetry/telemetry_test.go:481-517


[failure] 481-481:
481-517 lines are duplicate of pkg/telemetry/telemetry_test.go:441-477

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Build (windows-latest, windows)
  • GitHub Check: Summary
🔇 Additional comments (7)
pkg/config/load.go (1)

123-124: Env binding added correctly.

Binding settings.telemetry.logging to ATMOS_TELEMETRY_LOGGING follows our selective BindEnv pattern and long‑term learnings. LGTM.

pkg/config/atmos.yaml (1)

15-15: Default logging: false is appropriate.

Keeps PostHog internal logs quiet at info level by default. LGTM.

pkg/telemetry/utils.go (1)

76-77: Approve — logging plumbed into Telemetry.
All NewTelemetry call sites include the new logging bool (verified in pkg/telemetry/utils.go:93 and the tests).

pkg/telemetry/utils_test.go (2)

615-636: LGTM: capture with logging enabled.

Good coverage for the captureCmdString path with logging enabled.


637-658: LGTM: capture with logging disabled.

Happy path and closure expectations look right.

pkg/telemetry/telemetry_test.go (2)

39-39: LGTM: expectations updated to new constructor shape.

Mocks align with NewTelemetry’s new signature; no issues.

Also applies to: 82-82, 128-128, 144-144, 229-229, 281-281, 295-295, 420-420


473-474: Incorrect — telemetry.Capture accepts map[string]interface{}; no change required.

Capture is defined as func (t *Telemetry) Capture(eventName string, properties map[string]interface{}) bool in pkg/telemetry/telemetry.go, and the tests in pkg/telemetry/telemetry_test.go (around lines 473–474 and 513–514) that pass a map are correct.

Likely an incorrect or invalid review comment.

coderabbitai[bot]
coderabbitai bot previously approved these changes Sep 22, 2025
@osterman osterman added the minor New features that do not break anything label Sep 22, 2025
- Add Infof and Printf methods to PosthogLogger, SilentLogger, and DiscardLogger for interface completeness
- Refactor NewTelemetry to use Options struct to comply with golangci-lint max params rule
- Convert duplicate logging tests to table-driven TestTelemetryLogging for better maintainability
- Update test snapshots to reflect new logging field in configuration
- Route all PostHog log messages to Debug level to avoid cluttering user output

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
osterman and others added 2 commits September 22, 2025 09:11
…proach

- Fix linter duplication warning by converting TestTelemetryLoggerSelectionBasedOnFlag to table-driven test
- Reduces code duplication while maintaining same test coverage
- Improves test maintainability and readability

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Remove DiscardLogger implementation as it duplicates SilentLogger functionality
- Keep SilentLogger as the single no-op logger implementation
- Update telemetry documentation with new posthog_logging configuration option
- Document how to enable PostHog internal logging for debugging
- Simplify test coverage by removing DiscardLogger tests

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Update snapshots to include new `logging: false` field in telemetry config
- Update snapshots to reflect "Telemetry event enqueued" message change
- Regenerated snapshots for tests affected by telemetry improvements

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
coderabbitai[bot]
coderabbitai bot previously approved these changes Sep 22, 2025
- Update additional snapshots that were missed in previous commit
- Update atmos_describe_config tests to include logging: false field
- Update logging-related tests for "Telemetry event enqueued" message
- Ensure all snapshots are now consistent with telemetry improvements

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🧹 Nitpick comments (4)
tests/snapshots/TestCLICommands_Valid_log_file_in_env_should_be_priortized_over_config.stdout.golden (2)

6-7: Duplicate ENV log lines.

The repeated “Found ENV variable ATMOS_VERSION_CHECK_ENABLED=false” suggests init is running twice or logging isn’t deduped. Worth tightening to reduce snapshot brittleness.


1-1: Typo in filename: “priortized” → “prioritized”.

Recommend renaming test/snapshot to avoid future search misses and minor papercuts.

tests/snapshots/TestCLICommands_Valid_log_level_in_flag_should_be_priortized_over_env_and_config.stderr.golden (2)

2-4: Reduce duplicated ENV logs (non-blocking)

Same line logged thrice adds noise to snapshots; consider consolidating detection logs or logging once per variable.

If helpful, I can draft a tiny helper that memoizes ENV discovery logs to avoid repeats.


1-1: Fix typo: "priortized" → "prioritized" in test case names

  • tests/test-cases/log-level-validation.yaml:103 — "Valid log level in env should be priortized over config"
  • tests/test-cases/log-level-validation.yaml:122 — "Valid log level in flag should be priortized over env and config"
  • tests/test-cases/log-level-validation.yaml:143 — "Valid log file in env should be priortized over config"
  • tests/test-cases/log-level-validation.yaml:164 — "Valid log file in flag should be priortized over env and config"

Rename "priortized" → "prioritized" in those test names and regenerate snapshots for consistency.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 745f501 and c4ed6d0.

📒 Files selected for processing (7)
  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Environment_Variable.stderr.golden (1 hunks)
  • tests/snapshots/TestCLICommands_Valid_log_file_in_env_should_be_priortized_over_config.stdout.golden (1 hunks)
  • tests/snapshots/TestCLICommands_Valid_log_file_in_flag_should_be_priortized_over_env_and_config.stdout.golden (1 hunks)
  • tests/snapshots/TestCLICommands_Valid_log_level_in_env_should_be_priortized_over_config.stderr.golden (1 hunks)
  • tests/snapshots/TestCLICommands_Valid_log_level_in_flag_should_be_priortized_over_env_and_config.stderr.golden (1 hunks)
  • tests/snapshots/TestCLICommands_atmos_describe_config.stdout.golden (1 hunks)
  • tests/snapshots/TestCLICommands_atmos_describe_config_-f_yaml.stdout.golden (1 hunks)
✅ Files skipped from review due to trivial changes (2)
  • tests/snapshots/TestCLICommands_Valid_log_file_in_flag_should_be_priortized_over_env_and_config.stdout.golden
  • tests/snapshots/TestCLICommands_Valid_log_level_in_env_should_be_priortized_over_config.stderr.golden
🧰 Additional context used
🪛 Gitleaks (8.28.0)
tests/snapshots/TestCLICommands_atmos_describe_config.stdout.golden

[high] 142-142: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: Build (windows-latest, windows)
  • GitHub Check: Build (macos-latest, macos)
  • GitHub Check: Build (ubuntu-latest, linux)
  • GitHub Check: website-deploy-preview
  • GitHub Check: Lint (golangci)
  • GitHub Check: Analyze (go)
  • GitHub Check: Summary
🔇 Additional comments (2)
tests/snapshots/TestCLICommands_Valid_Log_Level_in_Environment_Variable.stderr.golden (1)

5-5: 'captured' → 'enqueued' snapshot update looks right

Matches the new enqueue flow and keeps debug-only visibility.

Stale snapshot found: tests/snapshots/TestCLICommands_atmos_vendor_pull_custom_detector_credentials_leakage.stderr.golden:93 contains "DEBU Telemetry event captured" — change to "DEBU Telemetry event enqueued" and re-run the snapshot/leak checks. Verification note: the script failed to complete the non-debug scan ("/dev/fd/63: No such file or directory"); re-run in an environment that supports /dev/fd or adjust the script to avoid process substitution.

tests/snapshots/TestCLICommands_atmos_describe_config.stdout.golden (1)

143-143: Good: new telemetry.logging surfaced in CLI output

Presence of "logging": false matches the new default and PR intent to suppress PostHog chatter by default.

@codecov
Copy link

codecov bot commented Sep 22, 2025

Codecov Report

❌ Patch coverage is 86.56716% with 9 lines in your changes missing coverage. Please review.
✅ Project coverage is 56.25%. Comparing base (77ad2dd) to head (5ece89c).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
pkg/telemetry/posthog_logger.go 76.92% 9 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1491      +/-   ##
==========================================
+ Coverage   56.10%   56.25%   +0.14%     
==========================================
  Files         277      278       +1     
  Lines       29158    29214      +56     
==========================================
+ Hits        16360    16433      +73     
+ Misses      11004    10985      -19     
- Partials     1794     1796       +2     
Flag Coverage Δ
unittests 56.25% <86.56%> (+0.14%) ⬆️

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.

- Add PostHog token masking to sanitizeOutput function in cli_test.go
- Replace all real PostHog tokens in golden snapshots with phc_TEST_TOKEN_PLACEHOLDER
- Ensures no real telemetry tokens appear in test snapshots
- Real tokens remain in config files where they're needed for functionality

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
tests/cli_test.go (2)

348-352: Precompile regex at package scope; optional pattern hardening.

Minor perf/readability win: compile once and reuse. Optionally add word boundaries and a loose length to reduce accidental overmatches.

Apply this diff here:

-	posthogTokenRegex := regexp.MustCompile(`phc_[a-zA-Z0-9_]+`)
-	result = posthogTokenRegex.ReplaceAllString(result, "phc_TEST_TOKEN_PLACEHOLDER")
+	result = rePosthogToken.ReplaceAllString(result, "phc_TEST_TOKEN_PLACEHOLDER")

And add near the top of the file (package scope):

var rePosthogToken = regexp.MustCompile(`\bphc_[A-Za-z0-9_]{10,64}\b`)

If you prefer to keep the original character class, retain it but still precompile.


348-352: Masking implemented; no PostHog tokens found in snapshots.
Scan of tests/snapshots returned no phc_ tokens besides phc_TEST_TOKEN_PLACEHOLDER.

  • Optional: centralize this masking in sanitizeOutput for consistency.
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between c4ed6d0 and 0e0c5cb.

📒 Files selected for processing (7)
  • pkg/config/load.go (1 hunks)
  • tests/cli_test.go (1 hunks)
  • tests/snapshots/TestCLICommands_atmos_describe_config.stdout.golden (1 hunks)
  • tests/snapshots/TestCLICommands_atmos_describe_config_-f_yaml.stdout.golden (1 hunks)
  • tests/snapshots/TestCLICommands_atmos_describe_config_imports.stdout.golden (1 hunks)
  • tests/snapshots/TestCLICommands_atmos_describe_configuration.stdout.golden (1 hunks)
  • tests/snapshots/TestCLICommands_indentation.stdout.golden (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (5)
  • tests/snapshots/TestCLICommands_atmos_describe_configuration.stdout.golden
  • pkg/config/load.go
  • tests/snapshots/TestCLICommands_atmos_describe_config_imports.stdout.golden
  • tests/snapshots/TestCLICommands_indentation.stdout.golden
  • tests/snapshots/TestCLICommands_atmos_describe_config_-f_yaml.stdout.golden
🧰 Additional context used
📓 Path-based instructions (3)
**/*.go

📄 CodeRabbit inference engine (.cursor/rules/atmos-rules.mdc)

**/*.go: Use Viper for managing configuration, environment variables, and flags
Use interfaces for external dependencies to facilitate mocking
All code must pass golangci-lint checks
Follow Go's error handling idioms
Use meaningful error messages
Wrap errors with context using fmt.Errorf("context: %w", err)
Consider using a custom error type for domain-specific errors
Follow standard Go coding style
Use gofmt and goimports to format code
Prefer short, descriptive variable names
Use snake_case for environment variables
Document all exported functions, types, and methods
Document complex logic with inline comments
Follow Go's documentation conventions
Use Viper for configuration management
Support configuration via files, environment variables, and flags
Follow the precedence order: flags > environment variables > config file > defaults

**/*.go: All comments in Go code must end with periods (enforced by golangci-lint godot).
Wrap all returned errors using static errors from the errors package; never return dynamic errors directly.
Always bind environment variables with viper.BindEnv() and provide ATMOS_ alternatives for each external var.
Separate structured logging from UI output: use stderr for prompts/errors to user; stdout only for data; never use logging for UI.
Most text UI must go to stderr; only data/results to stdout. Prefer utils.PrintfMessageToTUI for UI messages.
For non-standard execution paths, capture telemetry with telemetry.CaptureCmd or telemetry.CaptureCmdString and never capture user data.
Ensure cross-platform compatibility: prefer SDKs to external binaries, use filepath/os/runtime for portability, and add build constraints when needed.

Files:

  • tests/cli_test.go
**/*_test.go

📄 CodeRabbit inference engine (.cursor/rules/atmos-rules.mdc)

**/*_test.go: Every new feature must include comprehensive unit tests
Test both happy paths and error conditions
Use table-driven tests for testing multiple scenarios
Include integration tests for command flows
Test CLI end-to-end when possible
Use test fixtures for complex inputs
Consider using testify/mock for creating mock implementations

**/*_test.go: Always use t.Skipf() with a reason for skipped tests; never use t.Skip() or reasonless t.Skipf().
Test files must mirror implementation structure and naming (e.g., aws_ssm_store_test.go).
Use table-driven unit tests and mock interfaces for external dependencies; target >80% coverage.

Files:

  • tests/cli_test.go
tests/**/*_test.go

📄 CodeRabbit inference engine (CLAUDE.md)

Integration tests reside under tests/ using fixtures in tests/test-cases/.

Files:

  • tests/cli_test.go
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: Build (windows-latest, windows)
  • GitHub Check: Build (ubuntu-latest, linux)
  • GitHub Check: Analyze (go)
  • GitHub Check: Lint (golangci)
  • GitHub Check: website-deploy-preview
  • GitHub Check: Summary
🔇 Additional comments (1)
tests/snapshots/TestCLICommands_atmos_describe_config.stdout.golden (1)

142-143: Good call on the token redaction.

The change to use phc_TEST_TOKEN_PLACEHOLDER addresses the security scanner concerns raised in prior reviews. PostHog project API keys (phc_ prefix) are safe to be public, but using clearly fake placeholders in tests avoids triggering leak detection tools and maintains clean compliance practices.

The addition of the logging: false field correctly reflects the new telemetry configuration option introduced in this PR.

coderabbitai[bot]
coderabbitai bot previously approved these changes Sep 22, 2025
@aknysh aknysh added no-release Do not create a new release (wait for additional code changes) and removed minor New features that do not break anything labels Sep 22, 2025
aknysh and others added 2 commits September 22, 2025 17:25
- Add missing periods to comments in cli_test.go to satisfy godot linter
- Fix documentation to use correct field name `telemetry.logging` instead of `telemetry.posthog_logging`
- Update environment variable in docs from ATMOS_TELEMETRY_POSTHOG_LOGGING to ATMOS_TELEMETRY_LOGGING
- Documentation now matches actual implementation in code and test snapshots

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
@osterman osterman merged commit 4e34c0c into main Sep 22, 2025
52 checks passed
@osterman osterman deleted the feature/dev-3633-handle-telemetry-issues-with-posthog-to-avoid-user-impact branch September 22, 2025 21:57
osterman added a commit that referenced this pull request Sep 23, 2025
…1491)

* fix(telemetry): prevent PostHog errors from leaking to user output

- Add custom PosthogLogger adapter to integrate with Atmos logging
- Redirect PostHog errors to debug level instead of stdout/stderr
- Ensure telemetry failures don't impact user experience
- Add unit tests to verify logger behavior
- Fix issue where PostHog was logging directly to stderr

This addresses the issue where PostHog errors like '502 Bad Gateway' were appearing
in user output and breaking CLI tests. Now all PostHog errors are properly handled
through our logging system and only appear at debug level.

Fixes DEV-3633

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

* [autofix.ci] apply automated fixes

* feat(telemetry): improve PostHog logger with structured context

- Use log.With('component', 'posthog') to add context to all PostHog messages
- Remove redundant message prefixes since component context identifies the source
- Add 'posthog_level' field to preserve PostHog's original log level in errors
- Update tests to verify component context appears in all log messages
- Ensure logger instances are created after log level changes in tests

This improves on the previous fix by using proper structured logging context
instead of message prefixes, making logs more consistent with Atmos conventions.

* [autofix.ci] apply automated fixes

* refactor(telemetry): use WithPrefix for PostHog logger context

- Replace log.With('component', 'posthog') with log.WithPrefix('posthog')
- Cleaner output format: 'DEBU posthog: message' instead of K/V pairs
- Fix misleading 'Telemetry event captured' message timing
- Change to 'Telemetry event enqueued' since actual send happens on Close()
- Update tests to verify prefix appears in log output

This provides cleaner, more readable log output while still clearly
identifying PostHog messages with the 'posthog:' prefix.

* [autofix.ci] apply automated fixes

* feat(telemetry): add configuration option to control PostHog internal logging

- Add `logging` field to TelemetrySettings to control PostHog SDK logging
- Default to false for cleaner user experience
- PostHog SDK uses SilentLogger when logging=false (default)
- PostHog SDK uses PosthogLogger when logging=true
- Support environment variable ATMOS_TELEMETRY_LOGGING
- Remove omitempty tag from logging field to ensure consistent serialization
- Add comprehensive tests for logging configuration
- Telemetry collection remains independent of logging setting

This allows users to keep telemetry enabled while suppressing PostHog's
internal debug messages (network errors, buffer status, etc.) that can
clutter logs. Users can enable PostHog logging when debugging telemetry
issues by setting telemetry.logging=true or ATMOS_TELEMETRY_LOGGING=true.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

* [autofix.ci] apply automated fixes

* refactor(telemetry): improve logger interfaces and update test snapshots

- Add Infof and Printf methods to PosthogLogger, SilentLogger, and DiscardLogger for interface completeness
- Refactor NewTelemetry to use Options struct to comply with golangci-lint max params rule
- Convert duplicate logging tests to table-driven TestTelemetryLogging for better maintainability
- Update test snapshots to reflect new logging field in configuration
- Route all PostHog log messages to Debug level to avoid cluttering user output

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor(telemetry): convert logger selection test to table-driven approach

- Fix linter duplication warning by converting TestTelemetryLoggerSelectionBasedOnFlag to table-driven test
- Reduces code duplication while maintaining same test coverage
- Improves test maintainability and readability

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: remove redundant DiscardLogger and update telemetry docs

- Remove DiscardLogger implementation as it duplicates SilentLogger functionality
- Keep SilentLogger as the single no-op logger implementation
- Update telemetry documentation with new posthog_logging configuration option
- Document how to enable PostHog internal logging for debugging
- Simplify test coverage by removing DiscardLogger tests

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

* test: update golden snapshots for telemetry changes

- Update snapshots to include new `logging: false` field in telemetry config
- Update snapshots to reflect "Telemetry event enqueued" message change
- Regenerated snapshots for tests affected by telemetry improvements

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

* test: update remaining golden snapshots for telemetry changes

- Update additional snapshots that were missed in previous commit
- Update atmos_describe_config tests to include logging: false field
- Update logging-related tests for "Telemetry event enqueued" message
- Ensure all snapshots are now consistent with telemetry improvements

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: mask PostHog tokens in test snapshots

- Add PostHog token masking to sanitizeOutput function in cli_test.go
- Replace all real PostHog tokens in golden snapshots with phc_TEST_TOKEN_PLACEHOLDER
- Ensures no real telemetry tokens appear in test snapshots
- Real tokens remain in config files where they're needed for functionality

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: correct comment periods and documentation field names

- Add missing periods to comments in cli_test.go to satisfy godot linter
- Fix documentation to use correct field name `telemetry.logging` instead of `telemetry.posthog_logging`
- Update environment variable in docs from ATMOS_TELEMETRY_POSTHOG_LOGGING to ATMOS_TELEMETRY_LOGGING
- Documentation now matches actual implementation in code and test snapshots

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Andriy Knysh <aknysh@users.noreply.github.com>
@github-actions
Copy link

These changes were released in v1.191.0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

no-release Do not create a new release (wait for additional code changes) size/l Large size PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants