Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
9 changes: 7 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,13 @@ Other demo entrypoints:
- `python -m telemetry_window_demo.cli run-ai-demo`
- `python -m telemetry_window_demo.cli run-rule-dedup-demo`
- `python -m telemetry_window_demo.cli run-config-change-demo`

That command reads `data/raw/sample_events.jsonl` and regenerates:

Useful inspection commands:

- `python -m telemetry_window_demo.cli summarize --input data/raw/sample_events.jsonl`
- `python -m telemetry_window_demo.cli summarize --input events.csv --timestamp-col event_time`

That command reads `data/raw/sample_events.jsonl` and regenerates:
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Point output artifact claim to the run command

After adding the summarize examples, the sentence “That command reads data/raw/sample_events.jsonl and regenerates:” now follows the summarize bullets, but summarize only prints stats and does not write features.csv, alerts.csv, or plots. This README flow now misstates actual CLI behavior and can mislead users reproducing outputs; the sentence should explicitly reference python -m telemetry_window_demo.cli run --config configs/default.yaml (or be moved back under that command).

Useful? React with 👍 / 👎.


- `data/processed/features.csv`
- `data/processed/alerts.csv`
Expand Down
24 changes: 18 additions & 6 deletions src/telemetry_window_demo/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,13 @@ def build_parser() -> argparse.ArgumentParser:
"summarize",
help="Summarize an input event file.",
)
summarize_parser.add_argument("--input", required=True, help="Path to .jsonl or .csv.")
summarize_parser.set_defaults(func=summarize_command)
summarize_parser.add_argument("--input", required=True, help="Path to .jsonl or .csv.")
summarize_parser.add_argument(
"--timestamp-col",
default=DEFAULT_TIMESTAMP_COLUMN,
help="Timestamp column name in the input event file.",
)
summarize_parser.set_defaults(func=summarize_command)

plot_parser = subparsers.add_parser("plot", help="Render plots from CSV outputs.")
plot_parser.add_argument("--features", required=True, help="Path to features.csv.")
Expand Down Expand Up @@ -174,10 +179,17 @@ def run_command(args: argparse.Namespace) -> None:
print(f" - {plot_path.name}")


def summarize_command(args: argparse.Namespace) -> None:
events = normalize_events(load_events(args.input))
min_time = format_timestamp(events["timestamp"].min())
max_time = format_timestamp(events["timestamp"].max())
def summarize_command(args: argparse.Namespace) -> None:
timestamp_col = _timestamp_column_config_value(
args.timestamp_col,
"timestamp-col",
)
events = normalize_events(
load_events(args.input, timestamp_col=timestamp_col),
timestamp_col=timestamp_col,
)
min_time = format_timestamp(events[timestamp_col].min())
max_time = format_timestamp(events[timestamp_col].max())
top_event_types = events["event_type"].value_counts().head(5).to_dict()
overall_error_rate = float(events["is_error"].mean()) if not events.empty else 0.0

Expand Down
30 changes: 30 additions & 0 deletions tests/test_cli_errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,36 @@ def test_main_reports_directory_input_without_traceback(tmp_path, capsys) -> Non
assert "Traceback" not in stderr


def test_main_reports_bad_summarize_timestamp_column_without_traceback(
tmp_path,
capsys,
) -> None:
input_path = tmp_path / "events.csv"
input_path.write_text(
"event_type,source,target,status\n"
"2026-03-10T10:00:00Z,user_a,auth,ok\n",
encoding="utf-8",
)

with pytest.raises(SystemExit) as excinfo:
main(
[
"summarize",
"--input",
str(input_path),
"--timestamp-col",
"event_type",
]
)

assert excinfo.value.code == 1
stderr = capsys.readouterr().err
assert stderr.startswith("error: ")
assert "timestamp-col" in stderr
assert "event_type" in stderr
assert "Traceback" not in stderr


def test_main_reports_bad_plot_feature_table_without_traceback(tmp_path, capsys) -> None:
features_path = tmp_path / "features.csv"
features_path.write_text(
Expand Down
29 changes: 29 additions & 0 deletions tests/test_cli_summarize.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
from __future__ import annotations

from telemetry_window_demo.cli import main


def test_summarize_honors_configured_timestamp_column(tmp_path, capsys) -> None:
input_path = tmp_path / "events.csv"
input_path.write_text(
"event_time,event_type,source,target,status,severity\n"
"2026-03-10T10:00:10Z,login_success,user_a,auth,ok,low\n"
"2026-03-10T10:00:00Z,login_fail,user_b,auth,fail,high\n",
encoding="utf-8",
)

main(
[
"summarize",
"--input",
str(input_path),
"--timestamp-col",
"event_time",
]
)

stdout = capsys.readouterr().out
assert "events: 2" in stdout
assert "time_range: 2026-03-10T10:00:00Z -> 2026-03-10T10:00:10Z" in stdout
assert "unique_sources: 2" in stdout
assert "overall_error_rate: 0.50" in stdout
Loading