Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
137 changes: 137 additions & 0 deletions docs/Logger.md
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`)
Copy link
Collaborator

@Dwctor Dwctor Nov 16, 2025

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!)

Copy link
Collaborator Author

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.

- `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.
36 changes: 36 additions & 0 deletions examples/lib/logger_example.ex
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
25 changes: 25 additions & 0 deletions examples/logger_interpolation_example.ex
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
Loading