Skip to content

Fix misleading zero timing values on failures - #14

Merged
NickBorgers merged 1 commit into
mainfrom
fix/nullable-timing-metrics
Nov 9, 2025
Merged

Fix misleading zero timing values on failures#14
NickBorgers merged 1 commit into
mainfrom
fix/nullable-timing-metrics

Conversation

@NickBorgers

Copy link
Copy Markdown
Owner

Summary

Fixes the issue where timeouts/failures were represented as 0ms in timing fields, causing Grafana dashboards to show misleading latency drops during connection failures.

Problem

When a timeout or connection failure occurred, all timing breakdown fields (dns_lookup_ms, tcp_connection_ms, tls_handshake_ms, etc.) were set to 0, which appeared in visualizations as if latency had dropped to 0ms when the connection actually failed.

Example of before (failure):

{
  "timings": {
    "dns_lookup_ms": 0,
    "tcp_connection_ms": 0,
    "tls_handshake_ms": 0,
    "total_duration_ms": 86
  }
}

Solution

Changed timing breakdown fields from int64 to *int64 (pointers) with omitempty JSON tags. Now when data is unavailable, the fields are completely omitted from JSON output rather than showing 0.

Example of after (failure):

{
  "timings": {
    "total_duration_ms": 86
  }
}

Successful requests still show all timing fields with actual values:

{
  "timings": {
    "dns_lookup_ms": 15,
    "tcp_connection_ms": 60,
    "tls_handshake_ms": 79,
    "time_to_first_byte_ms": 90,
    "total_duration_ms": 316
  }
}

Changes

  • internal/models/result.go: Changed 7 timing fields to *int64 with omitempty tags (kept total_duration_ms as int64)
  • internal/browser/controller_impl.go: Added int64Ptr() helper and updated timing assignments
  • internal/outputs/prometheus.go: Updated nil checks for pointer types
  • internal/browser/controller_impl_test.go: Updated all tests to handle nullable fields

Testing

  • ✅ All Go tests pass
  • ✅ Docker build successful
  • ✅ Manual testing with successful requests shows timing values
  • ✅ Manual testing with DNS failures shows timing fields omitted

Impact

  • Grafana: Will correctly interpret missing fields instead of showing false "0ms" spikes
  • Elasticsearch: Schema remains compatible (fields can be absent)
  • Prometheus: Gauges only set when values are available

🤖 Generated with Claude Code

Changed timing breakdown fields (DNS, TCP, TLS, TTFB, DOM, page load)
from int64 to *int64 pointers. This ensures that when timeouts or
connection failures occur, timing fields are omitted from JSON output
rather than appearing as misleading "0ms" values.

Benefits:
- Grafana dashboards no longer show false latency drops during failures
- JSON output clearly distinguishes between "no data" and "0ms"
- total_duration_ms remains int64 (always present, even on timeout)

Changes:
- Updated TimingMetrics struct to use nullable pointers with omitempty
- Added int64Ptr helper for clean pointer creation
- Updated Prometheus output to handle nil checks
- Updated all tests to handle pointer types

All tests pass. Manual testing confirms timing fields are properly
omitted on failures.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@NickBorgers
NickBorgers merged commit 632329d into main Nov 9, 2025
3 checks passed
@NickBorgers
NickBorgers deleted the fix/nullable-timing-metrics branch November 9, 2025 22:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant