Skip to content
Open
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
5 changes: 5 additions & 0 deletions .changeset/populate-telemetry-columns.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@core/sync-service': patch
---

Populate previously-empty telemetry span attributes for shape requests: `num_bytes` on the root shape-get span and `electric.subqueries.subset_result.{bytes,rows,duration_µs}` on subset materialisation spans. This makes the corresponding Honeycomb columns queryable.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,5 @@ response.tmp
.claude
!website/.claude/commands
!website/.claude/skills
_artifacts
_artifacts
.agent-tasks
10 changes: 9 additions & 1 deletion packages/sync-service/lib/electric/plug/serve_shape_plug.ex
Original file line number Diff line number Diff line change
Expand Up @@ -291,11 +291,13 @@ defmodule Electric.Plug.ServeShapePlug do
# is the place to assign them because we keep this plug last in the "plug pipeline" defined
# in this module.
defp end_telemetry_span(%Conn{assigns: assigns} = conn, _ \\ nil) do
bytes_sent = assigns[:streaming_bytes_sent] || 0

OpenTelemetry.execute(
[:electric, :plug, :serve_shape],
%{
count: 1,
bytes: assigns[:streaming_bytes_sent] || 0,
bytes: bytes_sent,
monotonic_time: System.monotonic_time(),
duration: System.monotonic_time() - conn.private[:electric_telemetry_span][:start_time]
},
Expand All @@ -308,6 +310,12 @@ defmodule Electric.Plug.ServeShapePlug do
}
)

# Expose the total response body size as a dedicated span attribute
# alongside the semantic `http.response_size` set by
# `Electric.Plug.Utils.common_open_telemetry_attrs/1`. This populates the
# `num_bytes` Honeycomb column for shape-get requests.
OpenTelemetry.add_span_attributes(%{num_bytes: bytes_sent})

add_span_attrs_from_conn(conn)
OpentelemetryTelemetry.end_telemetry_span(OpenTelemetry, %{})
conn
Expand Down
13 changes: 12 additions & 1 deletion packages/sync-service/lib/electric/shapes/partial_modes.ex
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,12 @@ defmodule Electric.Shapes.PartialModes do
{[row], {start_time, bytes + IO.iodata_length(row), rows + 1}}
end,
fn {start_time, bytes, rows} ->
duration = System.monotonic_time(:microsecond) - start_time

OpenTelemetry.execute(
[:electric, :subqueries, :subset_result],
%{
duration: System.monotonic_time(:microsecond) - start_time,
duration: duration,
bytes: bytes,
count: 1,
rows: rows
Expand All @@ -77,6 +79,15 @@ defmodule Electric.Shapes.PartialModes do
"shape.root_table": shape.root_table
}
)

# Expose subset materialisation metrics as span attributes on the
# active shape_snapshot.query_fn child span so they become queryable
# Honeycomb columns. Mirrors the telemetry event measurements above.
OpenTelemetry.add_span_attributes(%{
"electric.subqueries.subset_result.bytes" => bytes,
"electric.subqueries.subset_result.rows" => rows,
"electric.subqueries.subset_result.duration_µs" => duration
})
end
)
end
Expand Down