Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve paho logging and debug logging in general #31

Merged
merged 5 commits into from
Nov 27, 2024
Merged

Conversation

eest
Copy link
Member

@eest eest commented Nov 27, 2024

Make it so we can tag messages from paho internal logging in the slog messages, so we can now what part of paho created the message.

This also resulted in using the slog Debug level properly. edm will now set the slog loglevel to debug if the --debug flag is passed. This also resulted in some cleanup of the more verbose debug messages left in the code so it is actuallu possible to run edm on a real system with --debug enabled without generating massive amount of log messages.

Summary by CodeRabbit

  • New Features

    • Enhanced logging functionality allows users to specify the logging level during command execution.
    • Introduced structured logging for improved clarity in log messages within the MQTT client configuration.
  • Bug Fixes

    • Removed unnecessary debug logging to reduce noise in log outputs.
  • Documentation

    • Updated method signatures to reflect the new logging level parameter for better clarity on usage.

Make it so we can tag messages from paho internal logging in the slog
messages, so we can now what part of paho created the message.

This also resulted in using the slog Debug level properly. edm will now
set the slog loglevel to debug if the --debug flag is passed. This also
resulted in some cleanup of the more verbose debug messages left in the code
so it is actuallu possible to run edm on a real system with --debug
enabled without generating massive amount of log messages.
@eest eest requested a review from a team as a code owner November 27, 2024 09:56
Copy link

coderabbitai bot commented Nov 27, 2024

Walkthrough

The changes introduced in this pull request primarily enhance the logging functionality across multiple files. A new variable edmLoggerLevel has been added to manage the logging level, and several function signatures have been updated to include this new parameter. The logging mechanism has been modified to utilize structured logging, particularly in the MQTT client configuration. Overall, these changes improve the flexibility and clarity of the logging system without altering the existing control flow or logic.

Changes

File Change Summary
cmd/root.go Added variable edmLoggerLevel *slog.LevelVar. Updated Execute method signature to include loggerLevel.
cmd/run.go Updated Run method signature to include edmLoggerLevel when calling runner.Run.
main.go Added variable loggerLevel *slog.LevelVar. Updated logger initialization and cmd.Execute call to include loggerLevel.
pkg/runner/mqtt.go Replaced log package with log/slog. Added pahoDebugLogger and pahoErrorLogger types for structured logging. Updated logging configuration in newAutoPahoClientConfig. Removed conditional logic for debug logging.
pkg/runner/runner.go Updated Run method signature to include loggerLevel *slog.LevelVar. Enhanced debug logging behavior based on the debug flag. Removed unnecessary debug logging statements.

Sequence Diagram(s)

sequenceDiagram
    participant Main
    participant Cmd
    participant Runner
    participant MQTT

    Main->>Cmd: Execute(logger, loggerLevel)
    Cmd->>Runner: Run(logger, loggerLevel)
    Runner->>MQTT: Configure logging with loggerLevel
    MQTT->>MQTT: Use structured logging
Loading

🐇 "In the land of hops and logs so bright,
A new level of logging brings delight.
With structured tales and messages clear,
Our rabbit friends will now cheer!
Hooray for changes, let's all rejoice,
For every log now has a voice!" 🐇

Warning

Rate limit exceeded

@eest has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 13 minutes and 28 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between f5c2cda and 21b09c7.


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@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

🧹 Outside diff range and nitpick comments (3)
cmd/root.go (1)

30-30: Consider adding documentation for the new parameter.

The function signature has been updated, but the documentation above it hasn't been updated to reflect the new loggerLevel parameter.

 // Execute adds all child commands to the root command and sets flags appropriately.
 // This is called by main.main(). It only needs to happen once to the rootCmd.
+// The loggerLevel parameter controls the global logging level for the application.
 func Execute(logger *slog.Logger, loggerLevel *slog.LevelVar) {
pkg/runner/mqtt.go (1)

25-31: Consider optimizing string formatting in logger methods

The current implementation uses fmt.Sprint* functions before passing to the logger, which creates an intermediate string allocation. Consider passing the format and arguments directly to the logger for better performance.

Example optimization for debug logger (similar changes for error logger):

func (pdl pahoDebugLogger) Println(v ...interface{}) {
-   pdl.logger.Debug(fmt.Sprintln(v...))
+   pdl.logger.Debug(fmt.Sprint(v...))
}

func (pdl pahoDebugLogger) Printf(format string, v ...interface{}) {
-   pdl.logger.Debug(fmt.Sprintf(format, v...))
+   pdl.logger.Debug(format, v...)
}

Also applies to: 37-43

cmd/run.go (1)

Line range hint 41-41: Consider grouping debug-related flags for better organization

The debug-related flags are scattered throughout the flag definitions. Consider grouping them together and adding a comment section to clearly separate debug options from operational flags.

Here's a suggested reorganization:

 	runCmd.Flags().Bool("disable-mqtt", false, "disable MQTT message sending")
 	runCmd.Flags().Bool("disable-mqtt-filequeue", false, "disable MQTT file based queue")
+
+	// Debug options
+	runCmd.Flags().Bool("debug", false, "print debug logging during operation")
+	runCmd.Flags().String("debug-dnstap-filename", "", "File for dumping unmodified (sensitive) JSON-formatted dnstap packets we are about to process, for debugging")
+	runCmd.Flags().Bool("debug-enable-blockprofiling", false, "Enable profiling of goroutine blocking events")
+	runCmd.Flags().Bool("debug-enable-mutexprofiling", false, "Enable profiling of mutex contention events")

Also applies to: 85-87

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between ccebbe9 and 69e532f.

📒 Files selected for processing (5)
  • cmd/root.go (2 hunks)
  • cmd/run.go (1 hunks)
  • main.go (2 hunks)
  • pkg/runner/mqtt.go (2 hunks)
  • pkg/runner/runner.go (2 hunks)
🔇 Additional comments (10)
main.go (3)

23-24: LGTM! Good practice using slog.LevelVar for dynamic level control

The introduction of loggerLevel as a slog.LevelVar allows for dynamic control of logging levels, which is essential for implementing the debug flag functionality.


26-26: LGTM! Proper integration of level control with structured logging

The logger initialization correctly incorporates the dynamic level control while maintaining JSON structured logging, which is crucial for log aggregation and analysis.


36-36: Verify the cmd.Execute signature change implementation

The modification to pass loggerLevel is correct, but let's verify the corresponding changes in the cmd package.

✅ Verification successful

Let me gather more information about the implementation details.


Execute signature change is properly implemented

The verification confirms that:

  • The Execute function in cmd/root.go correctly accepts both logger and loggerLevel parameters
  • The loggerLevel is properly stored in a global variable for use in the cmd package
  • The parameter is correctly utilized in pkg/runner/runner.go to set debug level when needed
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the Execute function signature change and its implementation

# Check the Execute function signature in cmd package
ast-grep --pattern 'func Execute($logger *slog.Logger, $level *slog.LevelVar)'

# Check how the loggerLevel is used in the cmd package
rg -l "loggerLevel" --type go

Length of output: 151


Script:

#!/bin/bash
# Check the Execute function implementation in cmd/root.go
ast-grep --pattern 'func Execute($$$)'

# Check how loggerLevel is used in cmd/root.go
rg "loggerLevel" -A 3 -B 3 cmd/root.go

# Check how loggerLevel is used in pkg/runner/runner.go
rg "loggerLevel" -A 3 -B 3 pkg/runner/runner.go

Length of output: 1221

cmd/root.go (2)

12-14: LGTM! Well-structured logging configuration.

The addition of edmLoggerLevel as a package-level variable is a clean approach to managing dynamic log levels across the application.


30-33: LGTM! Clean implementation of logger level initialization.

The function properly initializes both the logger and its level while maintaining clean error handling.

pkg/runner/mqtt.go (3)

8-8: LGTM: Appropriate use of structured logging package

The switch to log/slog aligns with the PR objective to improve logging capabilities.


19-23: LGTM: Well-structured logger implementations

The implementation of separate debug and error loggers with structured logging capabilities aligns well with the PR objectives. The design properly encapsulates the slog.Logger and provides a clean interface for Paho integration.


61-64: LGTM: Well-structured logging configuration with clear categorization

The configuration properly implements structured logging with clear categorization using "paho_log_type". This will help in identifying the source of Paho-related log messages.

Let's verify if any existing log consumers depend on the previous logging format:

✅ Verification successful

Let me gather more context about the logging changes by checking the previous implementation and any log-related tests.


Based on the git history, I can now see that the previous implementation used paholog.NOOPLogger{} and log.Default() for different logging scenarios. Let me check one more thing to ensure there are no log format dependencies in the tests.


Let me check the custom logger implementation in mqtt.go to understand how it handles the log output.


The logging changes are safe and improve observability

The changes are verified to be safe because:

  1. Previous implementation used NOOPLogger and log.Default(), which didn't provide structured logging context
  2. New implementation properly wraps Paho's logging interface with structured logging, maintaining the same method signatures
  3. No existing log consumers depend on the previous format, as the log parsing found in the codebase is only for application-specific messages
  4. Custom logger implementations (pahoDebugLogger and pahoErrorLogger) properly handle the format conversion between Paho's interface and structured logging

The addition of "paho_log_type" context improves log categorization without breaking existing functionality.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for log parsing or processing logic in the codebase
rg -g '!vendor/*' -g '!*.log' -A 3 'log\.' | grep -E 'parse|process|handle|consume'

Length of output: 1140


Script:

#!/bin/bash
# Check git history for the specific file to see previous logging implementation
git show HEAD~1:pkg/runner/mqtt.go 2>/dev/null || echo "File not found in previous commit"

# Search for any test files that might be verifying log output
fd -e test.go -x rg -l "paho.*log" {}

Length of output: 4259


Script:

#!/bin/bash
# Search for any test assertions on log output
rg -g '*.test.go' -A 3 'assert.*log|expect.*log'

# Check for any custom logger implementations
rg -l 'type.*Logger'

Length of output: 241


Script:

#!/bin/bash
# Check the logger implementation in mqtt.go
rg -A 10 'type.*Logger' pkg/runner/mqtt.go

Length of output: 579

pkg/runner/runner.go (2)

759-761: LGTM! Clean implementation of debug logging setup.

The code correctly sets the log level to debug when the debug flag is enabled, which aligns with the PR objective to improve debug logging behavior.


744-744: Verify all callers of the Run function have been updated.

The function signature change looks good but requires updates in calling code.

✅ Verification successful

Based on the rg results, I can generate the final response as we have found all the callers of the Run function:

Function signature change is properly handled

The Run function is only called once in cmd/run.go and it correctly passes both required parameters: edmLogger and edmLoggerLevel.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify all callers of the Run function have been updated to pass the loggerLevel parameter.

# Search for function calls to Run
rg -A 2 "Run\(" --type go

Length of output: 458

cmd/run.go Show resolved Hide resolved
Copy link

@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

🧹 Outside diff range and nitpick comments (2)
pkg/runner/mqtt.go (2)

19-43: Add documentation for exported types

While the implementation is solid, these exported types should have proper documentation comments (GoDoc) explaining their purpose and interface implementation.

Consider adding documentation like this:

+// pahoDebugLogger implements paho/log.Logger interface for debug-level logging
 type pahoDebugLogger struct {
     logger *slog.Logger
 }

+// pahoErrorLogger implements paho/log.Logger interface for error-level logging
 type pahoErrorLogger struct {
     logger *slog.Logger
 }

61-64: LGTM: Well-structured logging configuration

The implementation effectively tags Paho logs with their source, which directly addresses the PR objective. The use of With() to add context is a good practice.

Consider extracting the log type strings as constants to prevent typos and enable reuse:

+const (
+    pahoLogTypeDebug      = "debug"
+    pahoLogTypeErrors     = "errors"
+    pahoLogTypePahoDebug  = "paho_debug"
+    pahoLogTypePahoErrors = "paho_errors"
+)

 cliCfg := autopaho.ClientConfig{
-    Debug:      pahoDebugLogger{logger: edm.log.With("paho_log_type", "debug")},
-    Errors:     pahoErrorLogger{logger: edm.log.With("paho_log_type", "errors")},
-    PahoDebug:  pahoDebugLogger{logger: edm.log.With("paho_log_type", "paho_debug")},
-    PahoErrors: pahoErrorLogger{logger: edm.log.With("paho_log_type", "paho_errors")},
+    Debug:      pahoDebugLogger{logger: edm.log.With("paho_log_type", pahoLogTypeDebug)},
+    Errors:     pahoErrorLogger{logger: edm.log.With("paho_log_type", pahoLogTypeErrors)},
+    PahoDebug:  pahoDebugLogger{logger: edm.log.With("paho_log_type", pahoLogTypePahoDebug)},
+    PahoErrors: pahoErrorLogger{logger: edm.log.With("paho_log_type", pahoLogTypePahoErrors)},
 }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 46dcf11 and 0d4cfd0.

📒 Files selected for processing (1)
  • pkg/runner/mqtt.go (2 hunks)
🔇 Additional comments (1)
pkg/runner/mqtt.go (1)

8-8: LGTM: Good upgrade to structured logging

The switch to log/slog is a positive change that enables structured logging, which will improve log parsing and filtering capabilities.

Copy link

@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

🧹 Outside diff range and nitpick comments (2)
pkg/runner/mqtt.go (2)

26-50: Consider optimizing logger implementations.

While the implementation is clean and functional, consider these improvements:

  1. The logger types could be unexported since they're package-internal
  2. Method receivers could use pointers to avoid copying the logger struct
-type pahoDebugLogger struct {
+type pahoDebugLogger struct {
 	logger *slog.Logger
 }
 
-func (pdl pahoDebugLogger) Println(v ...interface{}) {
+func (pdl *pahoDebugLogger) Println(v ...interface{}) {
 	pdl.logger.Debug(fmt.Sprint(v...))
 }
 
-func (pdl pahoDebugLogger) Printf(format string, v ...interface{}) {
+func (pdl *pahoDebugLogger) Printf(format string, v ...interface{}) {
 	pdl.logger.Debug(fmt.Sprintf(format, v...))
 }

-type pahoErrorLogger struct {
+type pahoErrorLogger struct {
 	logger *slog.Logger
 }
 
-func (pel pahoErrorLogger) Println(v ...interface{}) {
+func (pel *pahoErrorLogger) Println(v ...interface{}) {
 	pel.logger.Error(fmt.Sprint(v...))
 }
 
-func (pel pahoErrorLogger) Printf(format string, v ...interface{}) {
+func (pel *pahoErrorLogger) Printf(format string, v ...interface{}) {
 	pel.logger.Error(fmt.Sprintf(format, v...))
 }

68-71: Consider reducing logger initialization repetition.

The current implementation works well but contains repeated logger initialization patterns. Consider introducing a helper function to reduce this repetition.

+func newPahoLogger(logger *slog.Logger, logType string, isDebug bool) interface{} {
+    l := logger.With("paho_log_type", logType)
+    if isDebug {
+        return &pahoDebugLogger{logger: l}
+    }
+    return &pahoErrorLogger{logger: l}
+}

 cliCfg := autopaho.ClientConfig{
     // ... other config ...
-    Debug:          pahoDebugLogger{logger: edm.log.With("paho_log_type", pahoLogTypeDebug)},
-    Errors:         pahoErrorLogger{logger: edm.log.With("paho_log_type", pahoLogTypeErrors)},
-    PahoDebug:      pahoDebugLogger{logger: edm.log.With("paho_log_type", pahoLogTypePahoDebug)},
-    PahoErrors:     pahoErrorLogger{logger: edm.log.With("paho_log_type", pahoLogTypePahoErrors)},
+    Debug:          newPahoLogger(edm.log, pahoLogTypeDebug, true),
+    Errors:         newPahoLogger(edm.log, pahoLogTypeErrors, false),
+    PahoDebug:      newPahoLogger(edm.log, pahoLogTypePahoDebug, true),
+    PahoErrors:     newPahoLogger(edm.log, pahoLogTypePahoErrors, false),
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between f5c2cda and 21b09c7.

📒 Files selected for processing (1)
  • pkg/runner/mqtt.go (2 hunks)
🔇 Additional comments (1)
pkg/runner/mqtt.go (1)

19-24: Well-structured logging constants!

The new constants provide clear categorization for different types of log messages, making it easier to identify the source of Paho-related logs. This aligns well with the PR's objective of improving log message identification.

@eest eest merged commit 001a6a7 into main Nov 27, 2024
2 checks passed
@eest eest deleted the improve-debug-logging branch November 27, 2024 11:03
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.

1 participant