Skip to content

Conversation

@mahadzaryab1
Copy link
Collaborator

@mahadzaryab1 mahadzaryab1 commented Oct 28, 2025

Which problem is this PR solving?

Description of the changes

How was this change tested?

  • CI / unit tests

Checklist

Signed-off-by: Mahad Zaryab <[email protected]>
Signed-off-by: Mahad Zaryab <[email protected]>
@mahadzaryab1 mahadzaryab1 added the changelog:exprimental Change to an experimental part of the code label Oct 28, 2025
Comment on lines 142 to 144
if err != nil {
break
}
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

@yurishkuro How should we handle this? It's on the write path. Should we add a warning for this?

Copy link
Member

Choose a reason for hiding this comment

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

yes I would still add the warning, it's better than silently ignoring the error. another alternative is to log it, but I prefer storing it int the span.

Signed-off-by: Mahad Zaryab <[email protected]>
Signed-off-by: Mahad Zaryab <[email protected]>
Signed-off-by: Mahad Zaryab <[email protected]>
@codecov
Copy link

codecov bot commented Oct 28, 2025

Codecov Report

❌ Patch coverage is 86.95652% with 12 lines in your changes missing coverage. Please review.
✅ Project coverage is 96.53%. Comparing base (528476f) to head (da1ad98).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
...nal/storage/v2/clickhouse/tracestore/dbmodel/to.go 78.57% 10 Missing and 2 partials ⚠️

❌ Your patch status has failed because the patch coverage (86.95%) is below the target coverage (95.00%). You can increase the patch coverage or adjust the target coverage.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #7627      +/-   ##
==========================================
- Coverage   96.59%   96.53%   -0.07%     
==========================================
  Files         384      384              
  Lines       19404    19464      +60     
==========================================
+ Hits        18744    18790      +46     
- Misses        477      489      +12     
- Partials      183      185       +2     
Flag Coverage Δ
badger_v1 8.83% <ø> (ø)
badger_v2 1.73% <0.00%> (-0.01%) ⬇️
cassandra-4.x-v1-manual 12.56% <ø> (ø)
cassandra-4.x-v2-auto 1.72% <0.00%> (-0.01%) ⬇️
cassandra-4.x-v2-manual 1.72% <0.00%> (-0.01%) ⬇️
cassandra-5.x-v1-manual 12.56% <ø> (ø)
cassandra-5.x-v2-auto 1.72% <0.00%> (-0.01%) ⬇️
cassandra-5.x-v2-manual 1.72% <0.00%> (-0.01%) ⬇️
clickhouse 1.65% <0.00%> (-0.01%) ⬇️
elasticsearch-6.x-v1 16.76% <ø> (ø)
elasticsearch-7.x-v1 16.79% <ø> (ø)
elasticsearch-8.x-v1 16.94% <ø> (ø)
elasticsearch-8.x-v2 1.73% <0.00%> (-0.01%) ⬇️
elasticsearch-9.x-v2 1.73% <0.00%> (-0.01%) ⬇️
grpc_v1 10.76% <ø> (ø)
grpc_v2 1.73% <0.00%> (-0.01%) ⬇️
kafka-3.x-v1 10.26% <ø> (ø)
kafka-3.x-v2 1.73% <0.00%> (-0.01%) ⬇️
memory_v2 1.73% <0.00%> (-0.01%) ⬇️
opensearch-1.x-v1 16.84% <ø> (ø)
opensearch-2.x-v1 16.84% <ø> (ø)
opensearch-2.x-v2 1.73% <0.00%> (-0.01%) ⬇️
opensearch-3.x-v2 1.73% <0.00%> (-0.01%) ⬇️
query 1.73% <0.00%> (-0.01%) ⬇️
tailsampling-processor 0.50% <0.00%> (-0.01%) ⬇️
unittests 95.44% <86.95%> (-0.06%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions
Copy link

github-actions bot commented Oct 28, 2025

Metrics Comparison Summary

Total changes across all snapshots: 53

Detailed changes per snapshot

summary_metrics_snapshot_cassandra

📊 Metrics Diff Summary

Total Changes: 53

  • 🆕 Added: 53 metrics
  • ❌ Removed: 0 metrics
  • 🔄 Modified: 0 metrics

🆕 Added Metrics

  • http_server_request_body_size_bytes (18 variants)
View diff sample
+http_server_request_body_size_bytes{http_request_method="GET",http_response_status_code="503",le="+Inf",network_protocol_name="http",network_protocol_version="1.1",otel_scope_name="go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp",otel_scope_schema_url="",otel_scope_version="0.63.0",server_address="localhost",server_port="13133",url_scheme="http"}
+http_server_request_body_size_bytes{http_request_method="GET",http_response_status_code="503",le="0",network_protocol_name="http",network_protocol_version="1.1",otel_scope_name="go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp",otel_scope_schema_url="",otel_scope_version="0.63.0",server_address="localhost",server_port="13133",url_scheme="http"}
+http_server_request_body_size_bytes{http_request_method="GET",http_response_status_code="503",le="10",network_protocol_name="http",network_protocol_version="1.1",otel_scope_name="go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp",otel_scope_schema_url="",otel_scope_version="0.63.0",server_address="localhost",server_port="13133",url_scheme="http"}
+http_server_request_body_size_bytes{http_request_method="GET",http_response_status_code="503",le="100",network_protocol_name="http",network_protocol_version="1.1",otel_scope_name="go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp",otel_scope_schema_url="",otel_scope_version="0.63.0",server_address="localhost",server_port="13133",url_scheme="http"}
+http_server_request_body_size_bytes{http_request_method="GET",http_response_status_code="503",le="1000",network_protocol_name="http",network_protocol_version="1.1",otel_scope_name="go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp",otel_scope_schema_url="",otel_scope_version="0.63.0",server_address="localhost",server_port="13133",url_scheme="http"}
+http_server_request_body_size_bytes{http_request_method="GET",http_response_status_code="503",le="10000",network_protocol_name="http",network_protocol_version="1.1",otel_scope_name="go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp",otel_scope_schema_url="",otel_scope_version="0.63.0",server_address="localhost",server_port="13133",url_scheme="http"}
+http_server_request_body_size_bytes{http_request_method="GET",http_response_status_code="503",le="25",network_protocol_name="http",network_protocol_version="1.1",otel_scope_name="go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp",otel_scope_schema_url="",otel_scope_version="0.63.0",server_address="localhost",server_port="13133",url_scheme="http"}
...
- `http_server_request_duration_seconds` (17 variants)
View diff sample
+http_server_request_duration_seconds{http_request_method="GET",http_response_status_code="503",le="+Inf",network_protocol_name="http",network_protocol_version="1.1",otel_scope_name="go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp",otel_scope_schema_url="",otel_scope_version="0.63.0",server_address="localhost",server_port="13133",url_scheme="http"}
+http_server_request_duration_seconds{http_request_method="GET",http_response_status_code="503",le="0.005",network_protocol_name="http",network_protocol_version="1.1",otel_scope_name="go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp",otel_scope_schema_url="",otel_scope_version="0.63.0",server_address="localhost",server_port="13133",url_scheme="http"}
+http_server_request_duration_seconds{http_request_method="GET",http_response_status_code="503",le="0.01",network_protocol_name="http",network_protocol_version="1.1",otel_scope_name="go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp",otel_scope_schema_url="",otel_scope_version="0.63.0",server_address="localhost",server_port="13133",url_scheme="http"}
+http_server_request_duration_seconds{http_request_method="GET",http_response_status_code="503",le="0.025",network_protocol_name="http",network_protocol_version="1.1",otel_scope_name="go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp",otel_scope_schema_url="",otel_scope_version="0.63.0",server_address="localhost",server_port="13133",url_scheme="http"}
+http_server_request_duration_seconds{http_request_method="GET",http_response_status_code="503",le="0.05",network_protocol_name="http",network_protocol_version="1.1",otel_scope_name="go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp",otel_scope_schema_url="",otel_scope_version="0.63.0",server_address="localhost",server_port="13133",url_scheme="http"}
+http_server_request_duration_seconds{http_request_method="GET",http_response_status_code="503",le="0.075",network_protocol_name="http",network_protocol_version="1.1",otel_scope_name="go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp",otel_scope_schema_url="",otel_scope_version="0.63.0",server_address="localhost",server_port="13133",url_scheme="http"}
+http_server_request_duration_seconds{http_request_method="GET",http_response_status_code="503",le="0.1",network_protocol_name="http",network_protocol_version="1.1",otel_scope_name="go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp",otel_scope_schema_url="",otel_scope_version="0.63.0",server_address="localhost",server_port="13133",url_scheme="http"}
...
- `http_server_response_body_size_bytes` (18 variants)
View diff sample
+http_server_response_body_size_bytes{http_request_method="GET",http_response_status_code="503",le="+Inf",network_protocol_name="http",network_protocol_version="1.1",otel_scope_name="go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp",otel_scope_schema_url="",otel_scope_version="0.63.0",server_address="localhost",server_port="13133",url_scheme="http"}
+http_server_response_body_size_bytes{http_request_method="GET",http_response_status_code="503",le="0",network_protocol_name="http",network_protocol_version="1.1",otel_scope_name="go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp",otel_scope_schema_url="",otel_scope_version="0.63.0",server_address="localhost",server_port="13133",url_scheme="http"}
+http_server_response_body_size_bytes{http_request_method="GET",http_response_status_code="503",le="10",network_protocol_name="http",network_protocol_version="1.1",otel_scope_name="go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp",otel_scope_schema_url="",otel_scope_version="0.63.0",server_address="localhost",server_port="13133",url_scheme="http"}
+http_server_response_body_size_bytes{http_request_method="GET",http_response_status_code="503",le="100",network_protocol_name="http",network_protocol_version="1.1",otel_scope_name="go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp",otel_scope_schema_url="",otel_scope_version="0.63.0",server_address="localhost",server_port="13133",url_scheme="http"}
+http_server_response_body_size_bytes{http_request_method="GET",http_response_status_code="503",le="1000",network_protocol_name="http",network_protocol_version="1.1",otel_scope_name="go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp",otel_scope_schema_url="",otel_scope_version="0.63.0",server_address="localhost",server_port="13133",url_scheme="http"}
+http_server_response_body_size_bytes{http_request_method="GET",http_response_status_code="503",le="10000",network_protocol_name="http",network_protocol_version="1.1",otel_scope_name="go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp",otel_scope_schema_url="",otel_scope_version="0.63.0",server_address="localhost",server_port="13133",url_scheme="http"}
+http_server_response_body_size_bytes{http_request_method="GET",http_response_status_code="503",le="25",network_protocol_name="http",network_protocol_version="1.1",otel_scope_name="go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp",otel_scope_schema_url="",otel_scope_version="0.63.0",server_address="localhost",server_port="13133",url_scheme="http"}
...

➡️ View full metrics file

Signed-off-by: Mahad Zaryab <[email protected]>
Signed-off-by: Mahad Zaryab <[email protected]>
@mahadzaryab1 mahadzaryab1 marked this pull request as ready for review November 1, 2025 15:56
@mahadzaryab1 mahadzaryab1 requested a review from a team as a code owner November 1, 2025 15:56
@mahadzaryab1 mahadzaryab1 requested a review from jkowall November 1, 2025 15:56
Signed-off-by: Mahad Zaryab <[email protected]>
Comment on lines 117 to 126
case pcommon.ValueTypeSlice:
key := "@slice@" + k
m := &xpdata.JSONMarshaler{}
b, err := m.MarshalValue(v)
if err != nil {
break
}
encoded := base64.StdEncoding.EncodeToString(b)
out.ComplexKeys = append(out.ComplexKeys, key)
out.ComplexValues = append(out.ComplexValues, encoded)
Copy link
Contributor

Choose a reason for hiding this comment

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

Silent data loss on marshal failure. When m.MarshalValue(v) returns an error, the code uses break which only exits the switch statement but continues the Range loop. This causes the slice attribute to be silently dropped with no error logging or warning added to the span.

Impact: Attributes will be lost in production without any indication to users or operators.

Fix: Add error handling similar to the from.go pattern:

case pcommon.ValueTypeSlice:
    key := "@slice@" + k
    m := &xpdata.JSONMarshaler{}
    b, err := m.MarshalValue(v)
    if err != nil {
        // Log error or add warning to span
        // For now, skip this attribute
        return true
    }
    encoded := base64.StdEncoding.EncodeToString(b)
    out.ComplexKeys = append(out.ComplexKeys, key)
    out.ComplexValues = append(out.ComplexValues, encoded)

Spotted by Graphite Agent

Fix in Graphite


Is this helpful? React 👍 or 👎 to let us know.

Comment on lines 127 to 136
case pcommon.ValueTypeMap:
key := "@map@" + k
m := &xpdata.JSONMarshaler{}
b, err := m.MarshalValue(v)
if err != nil {
break
}
encoded := base64.StdEncoding.EncodeToString(b)
out.ComplexKeys = append(out.ComplexKeys, key)
out.ComplexValues = append(out.ComplexValues, encoded)
Copy link
Contributor

Choose a reason for hiding this comment

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

Silent data loss on marshal failure. When m.MarshalValue(v) returns an error for map attributes, the code uses break which only exits the switch statement but continues the Range loop. This causes the map attribute to be silently dropped with no error logging or warning.

Impact: Map attributes will be lost in production without any indication to users or operators.

Fix: Add error handling similar to the from.go pattern:

case pcommon.ValueTypeMap:
    key := "@map@" + k
    m := &xpdata.JSONMarshaler{}
    b, err := m.MarshalValue(v)
    if err != nil {
        // Log error or add warning to span
        // For now, skip this attribute
        return true
    }
    encoded := base64.StdEncoding.EncodeToString(b)
    out.ComplexKeys = append(out.ComplexKeys, key)
    out.ComplexValues = append(out.ComplexValues, encoded)
Suggested change
case pcommon.ValueTypeMap:
key := "@map@" + k
m := &xpdata.JSONMarshaler{}
b, err := m.MarshalValue(v)
if err != nil {
break
}
encoded := base64.StdEncoding.EncodeToString(b)
out.ComplexKeys = append(out.ComplexKeys, key)
out.ComplexValues = append(out.ComplexValues, encoded)
case pcommon.ValueTypeMap:
key := "@map@" + k
m := &xpdata.JSONMarshaler{}
b, err := m.MarshalValue(v)
if err != nil {
// Log error or add warning to span
// For now, skip this attribute
return true
}
encoded := base64.StdEncoding.EncodeToString(b)
out.ComplexKeys = append(out.ComplexKeys, key)
out.ComplexValues = append(out.ComplexValues, encoded)

Spotted by Graphite Agent

Fix in Graphite


Is this helpful? React 👍 or 👎 to let us know.

Signed-off-by: Mahad Zaryab <[email protected]>
Comment on lines 126 to 139
vm := pcommon.NewValueMap()
vm.Map().PutStr("key", "value")
m := &xpdata.JSONMarshaler{}
buf, err := m.MarshalValue(vm)
require.NoError(t, err)
encodedMap := base64.StdEncoding.EncodeToString(buf)

vs := pcommon.NewValueSlice()
vs.Slice().AppendEmpty().SetInt(1)
vs.Slice().AppendEmpty().SetInt(2)
vs.Slice().AppendEmpty().SetInt(3)
buf, err = m.MarshalValue(vs)
require.NoError(t, err)
encodedSlice := base64.StdEncoding.EncodeToString(buf)
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

@yurishkuro would it better to test using the raw json string here?

}
k := strings.TrimPrefix(storedAttrs.ComplexKeys[i], "@bytes@")
attrs.PutEmptyBytes(k).FromRaw(decoded)
case strings.HasPrefix(storedAttrs.ComplexKeys[i], "@slice@"):
Copy link
Member

Choose a reason for hiding this comment

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

Aside from prefix the code is identical to next case:, can move to shared helper

Copy link
Collaborator Author

@mahadzaryab1 mahadzaryab1 Nov 1, 2025

Choose a reason for hiding this comment

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

@yurishkuro The slice and map are added differently

attrs.PutEmptySlice(k).FromRaw(val.Slice().AsRaw())

vs.

attrs.PutEmptyMap(k).FromRaw(val.Map().AsRaw())

The warning messages are slightly different as well.

//
// - pcommon.ValueTypeSlice:
// Represents an OTLP slice (array). The value is first serialized to JSON, then
// Base64-encoded before storage. Keys for this type are prefixed with `@slice@`.
Copy link
Member

Choose a reason for hiding this comment

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

Why do we need to encode json as base64? I understand we need it for bytes as they may be unprintable, but json can be stored directly as string.

Signed-off-by: Mahad Zaryab <[email protected]>
Signed-off-by: Mahad Zaryab <[email protected]>
Signed-off-by: Mahad Zaryab <[email protected]>
@yurishkuro yurishkuro merged commit e217163 into jaegertracing:main Nov 2, 2025
65 of 66 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/storage changelog:exprimental Change to an experimental part of the code enhancement

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants