SCI Profiler PHP includes four built-in reporters. Enable them via the reporters configuration option.
Writes one JSON object per line to <output_dir>/sci-profiler.jsonl.
Best for: CI/CD pipelines, automated analysis, data processing, jq queries.
Each line is a self-contained JSON object:
{
"profile_id": "a1b2c3d4e5f6g7h8",
"timestamp": "2026-03-13T10:30:00+00:00",
"time.wall_time_ns": 45230000,
"time.wall_time_ms": 45.23,
"time.wall_time_sec": 0.04523,
"time.cpu_user_time_sec": 0.032,
"time.cpu_system_time_sec": 0.004,
"time.cpu_total_time_sec": 0.036,
"memory.memory_start_bytes": 2097152,
"memory.memory_end_bytes": 4194304,
"memory.memory_peak_bytes": 8388608,
"memory.memory_delta_bytes": 2097152,
"memory.memory_peak_mb": 8.0,
"request.method": "GET",
"request.uri": "/dashboard",
"request.response_code": 200,
"request.input_bytes": 0,
"request.output_bytes": 15234,
"sci.energy_kwh": 2.261e-7,
"sci.operational_carbon_gco2eq": 0.0000751,
"sci.embodied_carbon_gco2eq": 0.0002270,
"sci.sci_gco2eq": 0.0003021,
"sci.sci_mgco2eq": 0.3021
}# View latest entry
tail -1 /tmp/sci-profiler/sci-profiler.jsonl | jq .
# Average SCI over last 100 requests
tail -100 /tmp/sci-profiler/sci-profiler.jsonl \
| jq -s 'map(.["sci.sci_mgco2eq"]) | add / length'
# Filter by URI pattern
cat /tmp/sci-profiler/sci-profiler.jsonl \
| jq 'select(.["request.uri"] | startswith("/api/"))'
# Top 10 heaviest requests
cat /tmp/sci-profiler/sci-profiler.jsonl \
| jq -s 'sort_by(-.["sci.sci_mgco2eq"]) | .[0:10] | map({uri: .["request.uri"], sci: .["sci.sci_mgco2eq"], ms: .["time.wall_time_ms"]})'
# Group by HTTP method
cat /tmp/sci-profiler/sci-profiler.jsonl \
| jq -s 'group_by(.["request.method"]) | map({method: .[0]["request.method"], count: length, avg_sci: (map(.["sci.sci_mgco2eq"]) | add / length)})'
# Carbon budget check: fail if any request exceeds 5 mgCO2eq
MAX_SCI=5.0
VIOLATIONS=$(jq "select(.[\"sci.sci_mgco2eq\"] > $MAX_SCI)" /tmp/sci-profiler/sci-profiler.jsonl | wc -l)
if [ "$VIOLATIONS" -gt 0 ]; then
echo "FAIL: $VIOLATIONS requests exceeded SCI budget"
exit 1
fiAppends human-readable lines to <output_dir>/sci-profiler.log.
Best for: quick monitoring with tail -f, human review, development.
[2026-03-13T10:30:00+00:00] GET /dashboard | 45.23 ms | 0.3021 mgCO2eq | peak 8.00 MB
[2026-03-13T10:30:01+00:00] POST /api/users | 123.45 ms | 0.8234 mgCO2eq | peak 12.50 MB
[2026-03-13T10:30:02+00:00] CLI /var/www/myapp/artisan | 1523.00 ms | 8.1200 mgCO2eq | peak 64.00 MB
The LogReporter accepts an optional PSR-3 compatible logger. When provided, it uses the logger instead of writing to a file:
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
use SciProfiler\Reporter\LogReporter;
$logger = new Logger('sci');
$logger->pushHandler(new StreamHandler('/var/log/sci-profiler.log'));
$reporter = new LogReporter($logger);This allows routing SCI logs to any PSR-3 compatible backend (Monolog, Sentry, Logtail, etc.).
Generates a self-contained static HTML page at <output_dir>/dashboard.html.
Best for: visual overview, team dashboards, periodic review.
Requires the
jsonreporter to be enabled — the dashboard reads fromsci-profiler.jsonl.
- Summary cards: total requests, average SCI, total emissions, average response time
- SVG timeline chart: one colored polyline per script showing SCI trajectory over time, with a shared Y-axis, grid lines, and legend — no JavaScript required. Scripts with a single entry are excluded from the chart.
- Per-script summary table: grouped by script filename, with inline SVG sparkline, "last vs previous" comparison (with percentage delta), and first-half/second-half trend indicator
- Measurement parameters: device power (E), grid carbon intensity (I), embodied carbon (M), device lifetime
- Detail table: timestamp, method, URI (with script filename), response time, SCI score with per-script delta marks (▲/▼ — only comparing entries of the same script), status badges (200/301/500), peak memory — last 200 requests
# Enable both json and html reporters
export SCI_PROFILER_REPORTERS=json,html
# After some requests, open the dashboard
open /tmp/sci-profiler/dashboard.htmlThe dashboard is regenerated on every request, so it always shows the latest data.
Generates a terminal-friendly trend report at <output_dir>/sci-trend.txt.
Best for: tracking SCI changes over time, comparing runs, spotting regressions.
Requires the
jsonreporter to be enabled (reads fromsci-profiler.jsonl).
- Config parameters: device power, grid intensity, embodied carbon, machine description
- Per-script trends: first → last SCI, percentage change, sparkline, memory usage
- Recent history: chronological table with delta indicators (▲ worse, ▼ improved, ═ stable)
- 0 entries: shows "No profiling data collected yet" with setup hint
- 1 entry: shows the first measurement and "Waiting for more data"
- 2+ entries: full trend report
╔══════════════════════════════════════════════════════════════════╗
║ SCI Trend Report — 2026-03-18 19:00:00 UTC ║
╚══════════════════════════════════════════════════════════════════╝
Config: E=18W I=332 gCO2eq/kWh M=211,000 gCO2eq Lifetime=11,680h
Machine: MacBook Pro - Dev
analisi/factorial.php [3 runs]
SCI: 0.3968 → 0.3648 mgCO2eq ▼ improved (-8.1%)
Memory: avg 4.0 MB | peak 4.0 MB
Trend: █▇▁
export SCI_PROFILER_REPORTERS=json,trendEnable multiple reporters as a comma-separated list:
// config file
'reporters' => ['json', 'log', 'html', 'trend'],# environment variable
export SCI_PROFILER_REPORTERS=json,log,html,trendAll reporters run independently. If one fails, the others still execute (errors are silently caught).
All reporters output the same metrics collected during the request:
| Metric Key | PHP Source | Description |
|---|---|---|
time.wall_time_ns |
hrtime(true) |
Wall time in nanoseconds |
time.wall_time_ms |
derived | Wall time in milliseconds |
time.wall_time_sec |
derived | Wall time in seconds |
time.cpu_user_time_sec |
getrusage() |
CPU user-space time (Linux/macOS) |
time.cpu_system_time_sec |
getrusage() |
CPU kernel-space time (Linux/macOS) |
time.cpu_total_time_sec |
derived | CPU user + system time |
memory.memory_start_bytes |
memory_get_usage() |
Memory at request start |
memory.memory_end_bytes |
memory_get_usage() |
Memory at request end |
memory.memory_peak_bytes |
memory_get_peak_usage() |
Peak memory during request |
memory.memory_delta_bytes |
derived | Memory end - start |
memory.memory_peak_mb |
derived | Peak memory in megabytes |
request.method |
$_SERVER['REQUEST_METHOD'] |
HTTP method or CLI |
request.uri |
$_SERVER['REQUEST_URI'] |
Request path with query string |
request.script_filename |
$_SERVER['SCRIPT_FILENAME'] |
PHP file being executed |
request.response_code |
http_response_code() |
HTTP response status code |
request.input_bytes |
php://input |
Request body size in bytes |
request.output_bytes |
ob_get_length() |
Response body size in bytes |
sci.energy_kwh |
calculated | Energy consumed (kWh) |
sci.operational_carbon_gco2eq |
calculated | Operational carbon (gCO2eq) |
sci.embodied_carbon_gco2eq |
calculated | Embodied carbon (gCO2eq) |
sci.sci_gco2eq |
calculated | SCI score (gCO2eq) |
sci.sci_mgco2eq |
calculated | SCI score (mgCO2eq) |