Skip to content

fix: implement real functionality for kdm logs and kdm health commands (#1)#40

Merged
utkarsh232005 merged 5 commits into
KDM-cli:mainfrom
Rishiraj-Pathak-27:main
May 17, 2026
Merged

fix: implement real functionality for kdm logs and kdm health commands (#1)#40
utkarsh232005 merged 5 commits into
KDM-cli:mainfrom
Rishiraj-Pathak-27:main

Conversation

@Rishiraj-Pathak-27
Copy link
Copy Markdown
Contributor

@Rishiraj-Pathak-27 Rishiraj-Pathak-27 commented May 17, 2026

Summary

This PR resolves Issue #1 by replacing the placeholder implementations of kdm logs and kdm health with fully functional Docker and Kubernetes integrations.

Both commands now fetch and display real runtime data instead of static placeholder messages.


Changes Made

kdm logs

  • Added real Docker container log fetching
  • Added automatic Kubernetes pod fallback when no Docker match exists
  • Supports:
    • container names
    • container ID prefixes
    • Kubernetes pod names
  • Displays the latest logs directly from workloads

kdm health

  • Added real-time Docker container health checks
  • Added Kubernetes pod status monitoring
  • Added combined all target support
  • Displays formatted health tables with workload details
  • Added graceful fallback handling when Docker or Kubernetes is unavailable

Additional Improvements

  • Added detailed documentation for:
    • kdm logs
    • kdm health
  • Added examples, expected outputs, and common error handling documentation
  • Improved CLI usability and debugging experience

Screenshots

Health tests

image

kdm logs

image

kdm health

image

Testing

Tested successfully with:

  • Docker containers
  • Kubernetes pods
  • Missing workload scenarios
  • Docker unavailable scenarios
  • Kubernetes unavailable scenarios

Summary by CodeRabbit

  • New Features

    • Health command shows container and pod status with colored health, details, and target selection (all/containers/pods); warns when sources are unavailable.
    • Logs command fetches recent logs for container IDs, names, or pods, preferring Docker and falling back to Kubernetes, streaming and printing recent lines.
  • Tests

    • Expanded health command test coverage with comprehensive scenarios and error handling.

Review Change Stack

- Wire real Docker/K8s clients in health.ts and logs.ts
- Independent try/catch blocks so Docker shows even when K8s is down
- Add .npmrc ignore-scripts=true to prevent ssh2 segfault on Node v20
- Expand health.test.ts: vi.mocked(), empty/error/per-target coverage
- Trim .coderabbit.yaml tone_instructions to ≤ 250 chars

Fixes KDM-cli#1
- Add real expected output with color-coded table examples
- Document Docker-first + Kubernetes fallback behavior in logs
- Add error table with causes and fixes for both commands
- Remove placeholder dummy output from previous docs
Copilot AI review requested due to automatic review settings May 17, 2026 07:24
@github-actions github-actions Bot added documentation Improvements or additions to documentation frontend labels May 17, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 17, 2026

Caution

Review failed

Pull request was closed or merged during review

Note

.coderabbit.yaml has unrecognized properties

CodeRabbit is using all valid settings from your configuration. Unrecognized properties (listed below) have been ignored and may indicate typos or deprecated fields that can be removed.

⚠️ Parsing warnings (1)
Validation error: Unrecognized key(s) in object: 'pre_merge_checks'
⚙️ Configuration instructions
  • Please see the configuration documentation for more information.
  • You can also validate your configuration using the online YAML validator.
  • 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
📝 Walkthrough

Walkthrough

Two command handlers: showHealth(target) validates targets and renders a colored status table from container and pod data; showLogs(name) fetches Docker logs and falls back to Kubernetes pod logs, streaming output to stdout. Health tests are expanded and wired to the CLI.

Changes

CLI Command Handlers

Layer / File(s) Summary
Health command implementation
src/commands/health.ts
healthColor() maps status strings to chalk colors; showHealth(target) validates target against ['all','containers','pods'], fetches containers and/or pods with separate try/catch (logs Docker/Kubernetes unavailable warnings), formats rows (TYPE, NAME, HEALTH, DETAILS including pod namespace/restarts), uses a spinner, warns if no rows, and calls renderTable when rows exist.
Health command registration
src/commands/health.ts
registerHealthCommand(program) now returns void and wires health <target> to .action(showHealth) with updated help text.
Health command test suite
src/__tests__/health.test.ts
Vitest-based tests add mocks for getRunningContainers, getRunningPods, logger, renderTable, and spinner; assert command registration, rendering for all/containers/pods, no-result warning, unknown-target error, container/pod fetch rejection warnings, and partial-success behavior (Docker fail + pods succeed).
Logs command implementation
src/commands/logs.ts
Adds printStream(value) to write coerced output to stdout; showLogs(name) validates input, starts spinner, attempts Docker container log retrieval (match by ID prefix or container name), prints logs, debug-logs Docker failures and falls back to Kubernetes readNamespacedPodLog({ tailLines: 100 }), prints response.body, and handles spinner/error lifecycle without rethrowing Kubernetes errors.
Logs command registration
src/commands/logs.ts
registerLogsCommand(program) now returns void, updates the logs <name> description to mention container ID prefix/name and pod name matching, and wires .action(showLogs).

Sequence Diagram(s)

sequenceDiagram
  participant showHealth as showHealth
  participant Spinner
  participant Containers as getRunningContainers()
  participant Pods as getRunningPods()
  participant Table as renderTable
  showHealth->>Spinner: start()
  showHealth->>Containers: fetch (try/catch)
  showHealth->>Pods: fetch (try/catch)
  showHealth->>Table: renderTable(rows: TYPE, NAME, HEALTH, DETAILS)
  Table-->>showHealth: rendered
  showHealth->>Spinner: stop()
Loading
sequenceDiagram
  participant showLogs as showLogs
  participant Spinner
  participant Docker as Docker API
  participant Print as printStream
  participant K8s as Kubernetes API
  showLogs->>Spinner: start()
  showLogs->>Docker: listContainers() / get container logs
  alt Docker Success
    Docker-->>Print: log payload
    Print->>showLogs: write stdout
  else Docker Fails
    showLogs->>showLogs: logger.debug Docker failure
    showLogs->>K8s: readNamespacedPodLog(opts: { tailLines:100 })
    K8s-->>Print: pod log payload
    Print->>showLogs: write stdout
  end
  showLogs->>Spinner: stop()
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🩺 Health tables hum in colored rows,
Docker may grumble, K8s still flows.
Spinners spin, the logs cascade,
Tests assert the paths we made.
Small CLI magic, neatly played.

🚥 Pre-merge checks | ✅ 5
✅ 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 accurately describes the main change: implementing real functionality for the kdm logs and kdm health commands, replacing placeholder implementations with Docker and Kubernetes integrations.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

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

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

Copy link
Copy Markdown
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

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/__tests__/health.test.ts`:
- Around line 78-174: Add a new test in src/__tests__/health.test.ts that
simulates a mixed-failure for the "health all" command by mocking one backend to
reject (e.g., vi.mocked(getRunningContainers).mockRejectedValue(new Error(...))
or getRunningPods likewise) and the other to resolve with at least one workload,
then call program.parseAsync(['node','test','health','all']) and assert that
logger.warn was called with a message indicating the unavailable backend (e.g.,
contains "Docker unavailable" or "Kubernetes unavailable") and that
tableUtils.renderTable was still called with rows containing the available
workload (use expect.arrayContaining with expect.arrayContaining(['container',
...]) or ['pod', ...] to locate the rendered row); reference
getRunningContainers, getRunningPods, program.parseAsync, logger.warn, and
tableUtils.renderTable to locate and implement the test.

In `@src/commands/health.ts`:
- Around line 49-54: The branch that handles invalid targets (checking
validTargets.includes(target)) currently logs via logger.error but returns
normally; change it to terminate with a non-zero exit status so callers see
failure — e.g., after logging in the same block where validTargets and target
are checked, call process.exit(1) (or throw an Error) instead of returning;
ensure the error log still uses logger.error and include target/validTargets
context as currently done.

In `@src/commands/logs.ts`:
- Around line 1-23: Remove the entire commented-out scaffold block in this file
that defines registerLogsCommand (the commented imports and the commented export
const registerLogsCommand = (program: Command) => { ... }), since it is dead
code and duplicates the real implementation; search for symbols like
registerLogsCommand, program, createSpinner, and logger to locate the commented
section and delete it entirely so only the active implementation remains.
- Around line 38-41: In showLogs, validate that the incoming name string is
non-empty before doing any container lookups; if name is empty or only
whitespace, abort early (e.g., log an error and return) so you don't call
container.Id.startsWith('') which matches every container. Update the input
guard at the top of showLogs to trim the name, check length, and handle the
failure path (stop spinner, logger.error, and return) so downstream code that
iterates containers or calls container.Id.startsWith(name) only runs for a valid
non-empty name.
🪄 Autofix (Beta)

❌ Autofix failed (check again to retry)

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: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 14a1b961-be0a-41f1-af94-8d6bbfe1b642

📥 Commits

Reviewing files that changed from the base of the PR and between e4e3486 and f78ab59.

⛔ Files ignored due to path filters (5)
  • .coderabbit.yaml is excluded by none and included by none
  • docs/v1.2.1/health/README.md is excluded by none and included by none
  • docs/v1.2.1/logs/README.md is excluded by none and included by none
  • package-lock.json is excluded by !**/package-lock.json, !package-lock.json and included by none
  • package.json is excluded by none and included by none
📒 Files selected for processing (3)
  • src/__tests__/health.test.ts
  • src/commands/health.ts
  • src/commands/logs.ts

Comment thread src/__tests__/health.test.ts
Comment thread src/commands/health.ts
Comment thread src/commands/logs.ts
Comment on lines +1 to +23
// import { Command } from 'commander';
// import { logger } from '../utils/logger';
// import { createSpinner } from '../ui/spinner';

// export const registerLogsCommand = (program: Command) => {
// program
// .command('logs <name>')
// .description('Show logs for a container or pod')
// .action(async (name) => {
// const spinner = createSpinner(`Fetching logs for ${name}...`).start();
// try {
// // TODO: Implement actual log fetching logic
// spinner.stop(`Logs for ${name} fetched`);
// logger.info(`Showing logs for ${name}...`);
// } catch (error) {
// const errorMessage = (error as Error).message;
// spinner.fail(`Failed to fetch logs for ${name}: ${errorMessage}`);
// logger.error(`Failed to fetch logs for ${name}: ${errorMessage}`, error);
// throw error;
// }
// });
// };

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial | 💤 Low value

Remove commented-out placeholder code.

This dead code clutters the file now that the real implementation is in place. If you ever need the old scaffold, git history has your back.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/commands/logs.ts` around lines 1 - 23, Remove the entire commented-out
scaffold block in this file that defines registerLogsCommand (the commented
imports and the commented export const registerLogsCommand = (program: Command)
=> { ... }), since it is dead code and duplicates the real implementation;
search for symbols like registerLogsCommand, program, createSpinner, and logger
to locate the commented section and delete it entirely so only the active
implementation remains.

Comment thread src/commands/logs.ts Outdated
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 17, 2026

Note

Autofix is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it.

⚠️ Branch updated during autofix.

The branch was updated while autofix was in progress. Please try again.

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Copilot AI review requested due to automatic review settings May 17, 2026 09:48
utkarsh232005 and others added 2 commits May 17, 2026 15:19
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Copy link
Copy Markdown
Member

@utkarsh232005 utkarsh232005 left a comment

Choose a reason for hiding this comment

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

lgtm

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

@utkarsh232005 utkarsh232005 merged commit c8c40c7 into KDM-cli:main May 17, 2026
3 of 5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation frontend

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants