Skip to content

🚀 Feature: Create dmesg enricher action#2037

Open
letho1608 wants to merge 1 commit intorobusta-dev:masterfrom
letho1608:contribai/feat/create-dmesg-enricher-action
Open

🚀 Feature: Create dmesg enricher action#2037
letho1608 wants to merge 1 commit intorobusta-dev:masterfrom
letho1608:contribai/feat/create-dmesg-enricher-action

Conversation

@letho1608
Copy link
Copy Markdown

🚀 New Feature

Problem

Create a new action that executes dmesg on a node and returns the output as a FileBlock. This action should work for both NodeEvent and PodEvent, extracting node information from pods when necessary.

Severity: medium
File: playbooks/robusta_playbooks/dmesg_enricher.py

Solution

Create a new file with a function similar to node_bash_enricher but specifically for dmesg. The function should:

Changes

  • playbooks/robusta_playbooks/dmesg_enricher.py (new)

Testing

  • Existing tests pass
  • Manual review completed
  • No new warnings/errors introduced

Closes #549

Create a new action that executes dmesg on a node and returns the output as a FileBlock. This action should work for both NodeEvent and PodEvent, extracting node information from pods when necessary.

Affected files: dmesg_enricher.py

Signed-off-by: Le Quang Tho <92069270+letho1608@users.noreply.github.com>
@CLAassistant
Copy link
Copy Markdown

CLAassistant commented Mar 28, 2026

CLA assistant check
All committers have signed the CLA.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 28, 2026

Walkthrough

A new Robusta action module has been added that implements dmesg enrichment functionality. The module defines parameters and two action handlers—one for NodeEvent and one for PodEvent—both executing dmesg commands on target nodes and attaching the output as file blocks.

Changes

Cohort / File(s) Summary
Dmesg Enricher Action
playbooks/robusta_playbooks/dmesg_enricher.py
Added new action module with DmesgParams (configurable tail_lines parameter), dmesg_enricher action for NodeEvent (executes dmesg via debug pod, attaches output as FileBlock), and dmesg_enricher_on_pod action for PodEvent (converts to NodeEvent and delegates).

Sequence Diagram

sequenceDiagram
    participant Event as NodeEvent/PodEvent
    participant Action as dmesg_enricher
    participant Validator as Validation Logic
    participant Executor as RobustaPod.exec_in_debugger_pod
    participant Node as Target Node
    participant Attachment as Event Enrichment

    Event->>Action: Trigger with event & params
    Action->>Validator: Extract & validate node
    alt Node validation fails
        Validator-->>Action: Node missing
        Action-->>Event: Log error & return
    else Node validation passes
        Validator-->>Action: Node valid
        Action->>Executor: Execute dmesg (timeout: 60s)
        Executor->>Node: Run dmesg command
        Node-->>Executor: Return output/error
        alt Command fails
            Executor-->>Action: Non-zero return code
            Action-->>Event: Log failure with stderr
        else Command succeeds
            Executor-->>Action: Stdout output
            Action->>Action: Optionally truncate to tail_lines
            Action->>Attachment: Create FileBlock (dmesg.txt)
            Attachment->>Event: Attach enriched block
            Action-->>Event: Enrichment complete
        end
    end
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the main change: creating a new dmesg enricher action, which matches the primary objective of the PR.
Description check ✅ Passed The description is related to the changeset, explaining the problem, solution, and changes made to implement the dmesg enricher action.
Linked Issues check ✅ Passed The PR implements all coding requirements from issue #549: dmesg collection via action, support for both NodeEvent and PodEvent, and FileBlock packaging for readable output.
Out of Scope Changes check ✅ Passed The PR contains only the new dmesg_enricher.py file implementing the requested feature with no unrelated or out-of-scope changes.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

Copy link
Copy Markdown

@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: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@playbooks/robusta_playbooks/dmesg_enricher.py`:
- Around line 57-62: The code incorrectly constructs NodeEvent with pod metadata
causing a TypeError; replace the synthetic NodeEvent creation with a real Node
lookup by calling Node.readNode(pod.spec.nodeName), then construct NodeEvent
with the returned Node object and the required named_sinks list before calling
dmesg_enricher(node_event, params); add error handling around Node.readNode to
catch lookup failures (log/skip/early return) so dmesg_enricher is only invoked
when a valid Node is obtained.
- Around line 23-34: The call to RobustaPod.exec_in_debugger_pod is using the
wrong signature and handling its return incorrectly: pass a valid pod_name
string as the first arg, then node_name as the second, and put "dmesg" (the
command) as the third arg to match exec_in_debugger_pod(pod_name, node_name,
cmd, ...); remove invalid kwargs override_container_name and command_timeout and
if needed use supported kwargs like debug_image or custom_annotations; treat the
function's return as a plain str (e.g., assign exec_output =
RobustaPod.exec_in_debugger_pod(...)) and replace the
return_code/.stderr/.stdout checks with a simple emptiness check and error log
(use logging.error with node_name and exec_output), then set output =
exec_output for downstream use (references: RobustaPod.exec_in_debugger_pod,
exec_result/exec_output, node_name, output, logging.error).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 754e96df-8bda-4e39-b385-ff3900c14b09

📥 Commits

Reviewing files that changed from the base of the PR and between 14d6ba5 and 3079521.

📒 Files selected for processing (1)
  • playbooks/robusta_playbooks/dmesg_enricher.py

Comment on lines +23 to +34
exec_result = RobustaPod.exec_in_debugger_pod(
"dmesg",
node_name,
override_container_name="debug",
command_timeout=60,
)

if exec_result.return_code != 0:
logging.error(f"dmesg failed on node {node_name}: {exec_result.stderr}")
return

output = exec_result.stdout
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Search for exec_in_debugger_pod definition and usage patterns
ast-grep --pattern $'def exec_in_debugger_pod($$$) {
  $$$
}'

echo "---"
echo "Checking existing usages in playbooks:"
rg -n "exec_in_debugger_pod" --type py -C 3

Repository: robusta-dev/robusta

Length of output: 6151


🏁 Script executed:

sed -n '318,345p' src/robusta/integrations/kubernetes/custom_models.py

Repository: robusta-dev/robusta

Length of output: 1014


Critical: exec_in_debugger_pod API mismatch causes runtime failure.

The method signature exec_in_debugger_pod(pod_name: str, node_name: str, cmd, ...) -> str confirms three critical issues:

  1. Wrong argument order: "dmesg" is passed as pod_name (1st arg), but should be the cmd (3rd arg).
  2. Missing pod_name argument: The first positional argument should be a pod identifier string.
  3. Invalid kwargs: override_container_name and command_timeout are not valid parameters; only debug_image and custom_annotations are supported.
  4. Return type mismatch: The method returns str (command output), not an object with .return_code, .stderr, .stdout attributes. Lines 30-34 will fail when accessing these attributes.
🐛 Proposed fix aligning with the actual API
-    exec_result = RobustaPod.exec_in_debugger_pod(
-        "dmesg",
-        node_name,
-        override_container_name="debug",
-        command_timeout=60,
-    )
-
-    if exec_result.return_code != 0:
-        logging.error(f"dmesg failed on node {node_name}: {exec_result.stderr}")
-        return
-
-    output = exec_result.stdout
+    try:
+        output = RobustaPod.exec_in_debugger_pod(
+            pod_name="dmesg-debugger",
+            node_name=node_name,
+            cmd="dmesg",
+        )
+    except Exception as e:
+        logging.error(f"dmesg failed on node {node_name}: {e}")
+        return
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
exec_result = RobustaPod.exec_in_debugger_pod(
"dmesg",
node_name,
override_container_name="debug",
command_timeout=60,
)
if exec_result.return_code != 0:
logging.error(f"dmesg failed on node {node_name}: {exec_result.stderr}")
return
output = exec_result.stdout
try:
output = RobustaPod.exec_in_debugger_pod(
pod_name="dmesg-debugger",
node_name=node_name,
cmd="dmesg",
)
except Exception as e:
logging.error(f"dmesg failed on node {node_name}: {e}")
return
🧰 Tools
🪛 Flake8 (7.3.0)

[error] 23-23: 'RobustaPod' may be undefined, or defined from star imports: robusta.api

(F405)


[error] 31-31: 'logging' may be undefined, or defined from star imports: robusta.api

(F405)

🪛 Ruff (0.15.7)

[error] 23-23: RobustaPod may be undefined, or defined from star imports

(F405)


[error] 31-31: logging may be undefined, or defined from star imports

(F405)

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

In `@playbooks/robusta_playbooks/dmesg_enricher.py` around lines 23 - 34, The call
to RobustaPod.exec_in_debugger_pod is using the wrong signature and handling its
return incorrectly: pass a valid pod_name string as the first arg, then
node_name as the second, and put "dmesg" (the command) as the third arg to match
exec_in_debugger_pod(pod_name, node_name, cmd, ...); remove invalid kwargs
override_container_name and command_timeout and if needed use supported kwargs
like debug_image or custom_annotations; treat the function's return as a plain
str (e.g., assign exec_output = RobustaPod.exec_in_debugger_pod(...)) and
replace the return_code/.stderr/.stdout checks with a simple emptiness check and
error log (use logging.error with node_name and exec_output), then set output =
exec_output for downstream use (references: RobustaPod.exec_in_debugger_pod,
exec_result/exec_output, node_name, output, logging.error).

Comment on lines +57 to +62
node_event = NodeEvent(
metadata=pod.metadata,
involvedObject=pod,
nodeName=pod.spec.nodeName,
)
dmesg_enricher(node_event, params) No newline at end of file
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify NodeEvent constructor and check how other playbooks create NodeEvent from pods
echo "=== NodeEvent class definition ==="
ast-grep --pattern $'class NodeEvent($$$):
  def __init__($$$):
    $$$
'

echo ""
echo "=== How other playbooks handle similar pod-to-node scenarios ==="
rg -n "NodeEvent\(" --type py -C 5 playbooks/

Repository: robusta-dev/robusta

Length of output: 3569


🏁 Script executed:

#!/bin/bash
# Check PodEvent class and verify named_sinks attribute
echo "=== PodEvent class definition ==="
rg -n "class PodEvent" --type py -A 10 src/robusta/integrations/kubernetes/autogenerated/events.py | head -20

echo ""
echo "=== Check if PodEvent inherits named_sinks ==="
rg -n "class KubernetesResourceEvent" --type py -A 5 src/robusta/integrations/kubernetes/

echo ""
echo "=== Verify named_sinks usage in PodEvent context ==="
rg -n "named_sinks" --type py src/robusta/integrations/kubernetes/autogenerated/events.py | head -10

Repository: robusta-dev/robusta

Length of output: 1818


Critical: NodeEvent constructor signature mismatch causes TypeError.

The NodeEvent.__init__ signature requires (obj: Node, named_sinks: List[str]), but the code passes metadata, involvedObject, and nodeName kwargs which do not exist in the constructor. This will raise a TypeError at runtime.

The current approach of synthesizing a NodeEvent from pod metadata cannot work. NodeEvent requires an actual Node object retrieved from the Kubernetes API, not pod metadata.

Use Node.readNode(pod.spec.nodeName) to fetch the real Node object:

Proposed fix
    node_event = NodeEvent(
-       metadata=pod.metadata,
-       involvedObject=pod,
-       nodeName=pod.spec.nodeName,
+       obj=Node.readNode(pod.spec.nodeName).obj,
+       named_sinks=event.named_sinks,
    )
    dmesg_enricher(node_event, params)

Add error handling to gracefully handle Node lookup failures.

🧰 Tools
🪛 Flake8 (7.3.0)

[error] 57-57: 'NodeEvent' may be undefined, or defined from star imports: robusta.api

(F405)

🪛 Ruff (0.15.7)

[error] 57-57: NodeEvent may be undefined, or defined from star imports

(F405)

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

In `@playbooks/robusta_playbooks/dmesg_enricher.py` around lines 57 - 62, The code
incorrectly constructs NodeEvent with pod metadata causing a TypeError; replace
the synthetic NodeEvent creation with a real Node lookup by calling
Node.readNode(pod.spec.nodeName), then construct NodeEvent with the returned
Node object and the required named_sinks list before calling
dmesg_enricher(node_event, params); add error handling around Node.readNode to
catch lookup failures (log/skip/early return) so dmesg_enricher is only invoked
when a valid Node is obtained.

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.

Dmesg enricher (action)

2 participants