Skip to content

[ENHANCEMENT] Add structured logging with configurable verbosity levels (--verbose / --debug) #52

@advaitpatel

Description

@advaitpatel

Overview

DockSec currently has inconsistent logging — some operations use a custom logger, others use `print()` or Rich `console.print()` directly. There is no way for a user to increase or decrease verbosity. In CI/CD pipelines where DockSec runs unattended, this makes debugging failures unnecessarily difficult.

Problems Today

  1. No `--verbose` flag — users can't get more detail when a scan fails silently
  2. Mixed output mechanisms — `print()`, `logging`, and `rich.console` all coexist
  3. Subprocess errors swallowed — Trivy/Hadolint stderr often disappears with no way to surface it
  4. No log file output — no `--log-file` option for CI artifact collection
  5. Security-sensitive output always shown — no way to suppress verbose output in shared terminals

Proposed Changes

1. Add `--verbose` and `--debug` flags to `docksec.py`

parser.add_argument("-v", "--verbose", action="store_true",
                    help="Show detailed scan progress and tool output")
parser.add_argument("--debug", action="store_true",
                    help="Show debug-level output including raw tool outputs (implies --verbose)")
parser.add_argument("--log-file", metavar="PATH",
                    help="Write logs to a file in addition to stdout")

2. Centralize logging in `utils.py`

import logging

def configure_logging(verbose: bool = False, debug: bool = False, log_file: str = None):
    level = logging.DEBUG if debug else (logging.INFO if verbose else logging.WARNING)
    
    handlers = [logging.StreamHandler()]
    if log_file:
        handlers.append(logging.FileHandler(log_file))
    
    logging.basicConfig(
        level=level,
        format="%(asctime)s [%(levelname)s] %(name)s: %(message)s",
        handlers=handlers,
    )

3. Replace print() calls in core modules with structured log calls

# Before
print(f"Scanning image {image_name}...")

# After
logger = logging.getLogger(__name__)
logger.info("Scanning image %s", image_name)
logger.debug("Running: %s", " ".join(cmd))

4. Surface subprocess stderr in verbose mode

result = subprocess.run(cmd, capture_output=True, text=True, timeout=timeout)
if result.returncode != 0:
    logger.error("Tool failed: %s", result.stderr)
elif result.stderr:
    logger.debug("Tool stderr: %s", result.stderr)

Default Behavior (No Flags)

Only show: scan start/complete messages, security score, errors.

`--verbose` Behavior

Add: tool version checks, progress for each scan phase, number of findings per severity.

`--debug` Behavior

Add: raw subprocess commands, full tool stderr, LLM prompt/response payloads (redacted), timing for each phase.

Files to Modify

File Change
`docksec.py` Add `-v`, `--debug`, `--log-file` args; call `configure_logging()`
`utils.py` Add `configure_logging()`; replace `print` with `logging`
`docker_scanner.py` Replace `print` with `logging`; surface subprocess stderr
`score_calculator.py` Add logger; log score components at DEBUG level
`report_generator.py` Add logger; log report paths at INFO level

Acceptance Criteria

  • `--verbose` shows tool progress without debug noise
  • `--debug` surfaces raw subprocess output and LLM timings
  • `--log-file PATH` writes structured logs to file
  • Default output unchanged (no regressions for existing users)
  • No `print()` calls remain in library code (only in `docksec.py` entrypoint if needed)
  • Unit tests verify log output at different verbosity levels

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestpythonPull requests that update python code

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions