-
Notifications
You must be signed in to change notification settings - Fork 11
[Feat] Use standard Elixir logger #64
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
Merged
Merged
Changes from 7 commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
56be8c1
Add Logger support to Honey Potion
4dedcc9
Add Logger.warning support for Elixir 1.15+ compatibility
31420d0
Update Logger documentation to reflect current capabilities
dfd2dea
chore: make interpolation work
036f979
Merge branch 'main' into feat/use-default-logger
af5f0ef
doc: adjustments to match the code
00ffdc8
remove unascessary files
60072df
chore: code review adjustments
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,137 @@ | ||
| # Logger Support in Honey Potion | ||
|
|
||
| Honey Potion now supports Elixir's standard `Logger` module for logging in eBPF programs. This provides a more familiar and organized way to handle logging compared to raw `bpf_printk` calls. | ||
|
|
||
| ## Current Status | ||
|
|
||
| **Fully Supported**: | ||
| - All Logger levels with automatic prefixes | ||
| - Simple string messages | ||
| - Logger.warn/warning compatibility | ||
|
|
||
| **Planned for Future**: | ||
| - Multiple arguments to Logger functions | ||
|
|
||
| ## Supported Logger Functions | ||
|
|
||
| The following Logger functions are supported: | ||
|
|
||
| - `Logger.debug/1` and `Logger.debug/2` | ||
| - `Logger.info/1` and `Logger.info/2` | ||
| - `Logger.warn/1` and `Logger.warn/2` (deprecated, use `warning`) | ||
| - `Logger.warning/1` and `Logger.warning/2` | ||
| - `Logger.error/1` and `Logger.error/2` | ||
|
|
||
| **Note**: Both `Logger.warn` and `Logger.warning` are supported for compatibility, but `Logger.warning` is preferred as `Logger.warn` is deprecated in newer Elixir versions. | ||
|
|
||
| ## Usage Examples | ||
|
|
||
| ### Basic Logging | ||
|
|
||
| ```elixir | ||
| defmodule MyBPF do | ||
| def main(ctx) do | ||
| Logger.info("Program started") | ||
| Logger.debug("Debug information") | ||
| Logger.warning("Warning message") # Preferred | ||
| Logger.warn("Warning message") # Deprecated but supported | ||
| Logger.error("Error occurred") | ||
|
|
||
| Honey.XDP.pass() | ||
| end | ||
| end | ||
| ``` | ||
|
|
||
| ### Logging with Variables | ||
|
|
||
| ```elixir | ||
| defmodule MyBPF do | ||
| def main(ctx) do | ||
| pid = Honey.BpfHelpers.bpf_get_current_pid_tgid() | ||
|
|
||
| Logger.info("Processing PID: #{pid}") | ||
| Logger.debug("Current context: #{ctx}") | ||
|
|
||
| if pid > 1000 do | ||
| Logger.warning("High PID detected: #{pid}") | ||
| end | ||
|
|
||
| Honey.XDP.pass() | ||
| end | ||
| end | ||
| ``` | ||
|
|
||
| ### Log Levels and Prefixes | ||
|
|
||
| Each Logger function automatically adds an appropriate prefix to the output: | ||
|
|
||
| - `Logger.debug("message")` → `"[DEBUG] message"` | ||
| - `Logger.info("message")` → `"[INFO] message"` | ||
| - `Logger.warn("message")` → `"[WARN] message"` (deprecated) | ||
| - `Logger.warning("message")` → `"[WARN] message"` (preferred) | ||
| - `Logger.error("message")` → `"[ERROR] message"` | ||
|
|
||
| ### Generated C Code | ||
|
|
||
| The Logger calls are translated to `bpf_printk` calls with prefixes. For example: | ||
|
|
||
| ```elixir | ||
| Logger.info("Processing packet") | ||
| ``` | ||
|
|
||
| Becomes: | ||
|
|
||
| ```c | ||
| bpf_printk("[INFO] Processing packet"); | ||
| ``` | ||
|
|
||
| ### String Interpolation (Future) | ||
|
|
||
| Currently, string interpolation like `"PID: #{pid}"` is not supported. This feature is planned for future releases. For now, use descriptive messages without variables: | ||
|
|
||
| ```elixir | ||
| # urrent approach | ||
| pid = Honey.BpfHelpers.bpf_get_current_pid_tgid() | ||
| if pid > 1000 do | ||
| Logger.warning("High PID detected") | ||
| end | ||
|
|
||
| # Future feature (not yet supported) | ||
| Logger.warning("High PID detected: #{pid}") | ||
| ``` | ||
|
|
||
| ## Advantages over bpf_printk | ||
|
|
||
| 1. **Familiar Syntax**: Uses Elixir's standard Logger, familiar to Elixir developers | ||
| 2. **Automatic Prefixes**: Log levels are automatically prefixed to messages | ||
| 3. **Better Organization**: Different log levels help categorize output | ||
| 4. **Code Clarity**: Intent is clearer than raw bpf_printk calls | ||
|
|
||
| ### Migration from bpf_printk | ||
|
|
||
| Old code: | ||
| ```elixir | ||
| Honey.BpfHelpers.bpf_printk("Debug: PID = %d", pid) | ||
| Honey.BpfHelpers.bpf_printk("Error: Invalid packet") | ||
| ``` | ||
|
|
||
| New code: | ||
| ```elixir | ||
| Logger.debug("PID = #{pid}") | ||
| Logger.error("Invalid packet") | ||
| ``` | ||
|
|
||
| ## Limitations | ||
|
|
||
| 1. **String Interpolation**: String interpolation (`"PID: #{pid}"`) is partially supported. For now, it's recommended to use simple string messages without interpolation. Full interpolation support is planned for future releases. | ||
|
|
||
| 2. **Complex Data Structures**: Only basic types (integers, strings) are supported as arguments. | ||
|
|
||
| 3. **Logger Configuration**: eBPF context doesn't support Logger backends, filters, or other configuration options. | ||
|
|
||
| 4. **Metadata**: Logger metadata and structured logging features are not available in eBPF context. | ||
|
|
||
|
|
||
| ## Complete Example | ||
|
|
||
| See `examples/logger_example.ex` for a complete working example demonstrating Logger usage in an eBPF program. | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| defmodule Examples.LoggerExample do | ||
| @moduledoc """ | ||
| Example demonstrating Logger usage in Honey Potion eBPF programs. | ||
|
|
||
| This example shows how to use Elixir's Logger instead of raw bpf_printk calls. | ||
| The Logger calls are automatically translated to bpf_printk with appropriate | ||
| log level prefixes. | ||
| """ | ||
| require Logger | ||
|
|
||
| def main(ctx) do | ||
| Logger.info("Starting packet processing") | ||
|
|
||
| # Get current process PID | ||
| pid = Honey.BpfHelpers.bpf_get_current_pid_tgid() | ||
| Logger.debug("Processing packet for current PID") | ||
|
|
||
| # Decision logic with different log levels | ||
| cond do | ||
| pid < 100 -> | ||
| Logger.warning("Suspicious low PID detected") | ||
| Logger.error("Dropping packet due to security policy") | ||
| Honey.XDP.drop() | ||
|
|
||
| pid > 50000 -> | ||
| Logger.warning("Very high PID detected") | ||
| Logger.info("Allowing packet but flagging for review") | ||
| Honey.XDP.pass() | ||
|
|
||
| true -> | ||
| Logger.debug("Normal PID range, allowing packet") | ||
| Logger.info("Packet processed successfully") | ||
| Honey.XDP.pass() | ||
| end | ||
| end | ||
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| defmodule LoggerInterpolationExample do | ||
| @moduledoc """ | ||
| Example showing Logger with string interpolation support. | ||
| This demonstrates how the new interpolation feature works in practice. | ||
| """ | ||
|
|
||
| def main() do | ||
| pid = 1234 | ||
| user_id = 9876 | ||
|
|
||
| # Simple interpolation | ||
| Logger.info("Process PID: #{pid}") | ||
|
|
||
| # Multiple interpolations | ||
| Logger.debug("User #{user_id} started process #{pid}") | ||
|
|
||
| # Mixed with other log levels | ||
| Logger.error("Critical error in PID #{pid}") | ||
|
|
||
| # Regular string (should still work) | ||
| Logger.warning("This is a regular warning") | ||
|
|
||
| 0 | ||
| end | ||
| end |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have yet to merge this into main even once, so we can remove the deprecated versions before they even get to exist! (take this opportunity now or it might be a bother later)
I tend to run Honey Potion on Arch, and often I tend to see the deprecated failures and the random issues from using non-standard applications of Elixir's tools and it happens quite frequently (Elixir has quite fast development!)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is done this way to comply with the Elixir API; otherwise, the behavior would be different from what is expected in the Elixir code. The goal of this PR is to be 100% compatible with the Elixir API, even for deprecated features. When it's removed from Elixir, we'll remove it here.