Telemetry Logging ================= Simulated annealing runs can emit structured telemetry so that future tuning (manual, LLM-assisted, or automated) can analyse performance. Use ``--telemetry-log PATH`` with either ``fhops solve-heur`` or ``fhops bench suite`` to append newline-delimited JSON records:: fhops solve-heur examples/tiny7/scenario.yaml --out tmp/result.csv \ --telemetry-log tmp/telemetry.jsonl --show-operator-stats Schema ------ Each JSON record includes the following fields: ``timestamp`` (str) ISO8601 UTC timestamp when the entry was written. ``source`` (str) Command that generated the entry (``solve-heur`` or ``bench-suite``). ``scenario`` (str) / ``scenario_path`` (str) Scenario name and file path. ``solver`` (str) Identifies the solver (``sa``, ``ils``, ``tabu``). When omitted the record came from ``solve-heur`` without specifying an algorithm (legacy). ``seed`` (int), ``iterations`` (int) Parameters used for the run. ``objective`` (float) Final objective reported by the solver. ``kpis`` (object) Snapshot of computed KPIs (mobilisation cost, total production, etc.). ``operators_config`` (object) Final operator weight configuration used for the run. ``operators_stats`` (object) Per-operator telemetry with the following fields: - ``proposals``: number of neighbour proposals emitted. - ``accepted``: number of accepted neighbours. - ``skipped``: times the operator returned ``None`` (e.g., infeasible move). - ``weight``: effective weight used for selection. - ``acceptance_rate``: ``accepted / proposals`` (0 when proposals is 0). Example ~~~~~~~ .. code-block:: json { "timestamp": "2025-11-09T05:31:42.972801", "source": "solve-heur", "scenario": "FHOPS Tiny7", "scenario_path": "examples/tiny7/scenario.yaml", "solver": "sa", "seed": 42, "iterations": 200, "objective": 13.0, "kpis": {"total_production": 45.5, "mobilisation_cost": 65.0, "...": "..."}, "operators_config": {"swap": 1.0, "move": 1.0}, "operators_stats": { "swap": { "proposals": 200.0, "accepted": 200.0, "skipped": 0.0, "weight": 1.0, "acceptance_rate": 1.0 }, "move": { "proposals": 200.0, "accepted": 200.0, "skipped": 0.0, "weight": 1.0, "acceptance_rate": 1.0 } } } Solver-specific fields ~~~~~~~~~~~~~~~~~~~~~~ - ILS entries echo diversification metadata: ``perturbations``, ``restarts``, ``improvement_steps``, ``stall_limit``, ``perturbation_strength``, and hybrid flags (``hybrid_use_mip``, ``hybrid_mip_time_limit``). - Tabu entries include ``tabu_tenure`` and ``tabu_stall_limit``. Usage Notes ----------- - Logs are append-only; use tooling such as ``jq`` or pandas to analyse historical performance. - Operators with frequently low acceptance rates may warrant weight adjustments or new presets. - Combine logs with the hyperparameter tuning plan (``notes/metaheuristic_hyperparam_tuning.md``) to drive future ML/LLM-based schedulers. - Parallel options add ``batch_size``/``max_workers`` fields to single-run records. Multi-start telemetry logs per-run entries with ``run_id``/``preset`` and a summary record containing ``type: multi_start_summary``, ``best_run_id``, ``best_objective``, and ``runs_executed``. CLI Reporting ------------- Use the ``fhops telemetry report`` sub-command to aggregate the mirrored SQLite store into CSV/Markdown summaries without re-running the tuners (CI and the weekly analytics workflow both invoke this before deploying GitHub Pages):: fhops telemetry report telemetry/runs.sqlite \ --out-csv tmp/tuner_report.csv \ --out-markdown tmp/tuner_report.md The command scans ``runs``, ``run_metrics``, ``run_kpis``, and ``tuner_summaries`` tables to surface best/mean objective values per algorithm and scenario. See :doc:`../howto/telemetry_tuning` for a step-by-step guide and ``docs/reference/dashboards`` for the live links generated from these files. Historical Trends ----------------- Each CI run uploads three ready-made history artefacts under the ``telemetry-report`` bundle: * ``history_summary.csv`` — tabular history of best/mean objectives for dated snapshots. * ``history_summary.md`` — Markdown rendering of the same table. * ``history_summary.html`` — Altair chart plotting best objective trends. * ``history_delta.{csv,md}`` — latest vs. previous snapshot diff across objectives and key KPIs. Download those files (or rerun ``analyze_tuner_reports.py --history-dir`` on a local archive) to inspect performance trends without regenerating telemetry.