Skip to content

Conversation

@SomilJain0112
Copy link
Contributor

@SomilJain0112 SomilJain0112 commented Oct 10, 2025

Which problem is this PR solving?

#7223

Description of the changes

a. Add IndexSpanAlias and IndexServiceAlias config fields
b. Use explicit aliases when provided instead of prefix pattern

How was this change tested?

Through local testing

Checklist

Comment on lines 129 to 133
if p.SpanAlias != "" || p.ServiceAlias != "" {
return func(_ time.Time) (string, string) {
return spanIndexPrefix, serviceIndexPrefix
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

There's a logical issue in this conditional block. When either p.SpanAlias or p.ServiceAlias is set (but not both), the function will return both indices without date suffixes. This creates inconsistent behavior where an index without an explicit alias will lose its date suffix.

Consider refactoring to handle each index type independently:

return func(date time.Time) (string, string) {
    spanIndex := spanIndexPrefix
    serviceIndex := serviceIndexPrefix
    
    // Only apply date suffix to indices without explicit aliases
    if p.SpanAlias == "" {
        spanIndex = indexWithDate(spanIndexPrefix, p.SpanIndex.DateLayout, date)
    }
    if p.ServiceAlias == "" {
        serviceIndex = indexWithDate(serviceIndexPrefix, p.ServiceIndex.DateLayout, date)
    }
    
    return spanIndex, serviceIndex
}

This ensures that date suffixes are only omitted for indices with explicit aliases configured.

Spotted by Graphite Agent

Fix in Graphite


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

@codecov
Copy link

codecov bot commented Oct 10, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 96.58%. Comparing base (528476f) to head (0d6d3bc).

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #7550      +/-   ##
==========================================
- Coverage   96.59%   96.58%   -0.02%     
==========================================
  Files         384      384              
  Lines       19404    19431      +27     
==========================================
+ Hits        18744    18767      +23     
- Misses        477      480       +3     
- Partials      183      184       +1     
Flag Coverage Δ
badger_v1 8.80% <0.00%> (-0.03%) ⬇️
badger_v2 1.73% <0.00%> (-0.01%) ⬇️
cassandra-4.x-v1-manual 12.52% <0.00%> (-0.04%) ⬇️
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.52% <0.00%> (-0.04%) ⬇️
cassandra-5.x-v2-auto 1.72% <0.00%> (-0.01%) ⬇️
cassandra-5.x-v2-manual 1.72% <0.00%> (-0.01%) ⬇️
clickhouse 1.66% <0.00%> (-0.01%) ⬇️
elasticsearch-6.x-v1 16.83% <60.00%> (+0.06%) ⬆️
elasticsearch-7.x-v1 16.86% <60.00%> (+0.06%) ⬆️
elasticsearch-8.x-v1 17.01% <60.00%> (+0.06%) ⬆️
elasticsearch-8.x-v2 1.73% <0.00%> (-0.01%) ⬇️
elasticsearch-9.x-v2 1.73% <0.00%> (-0.01%) ⬇️
grpc_v1 10.73% <0.00%> (-0.04%) ⬇️
grpc_v2 1.73% <0.00%> (-0.01%) ⬇️
kafka-3.x-v1 10.23% <0.00%> (-0.03%) ⬇️
kafka-3.x-v2 1.73% <0.00%> (-0.01%) ⬇️
memory_v2 1.73% <0.00%> (-0.01%) ⬇️
opensearch-1.x-v1 16.90% <60.00%> (+0.06%) ⬆️
opensearch-2.x-v1 16.90% <60.00%> (+0.06%) ⬆️
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.48% <100.00%> (-0.02%) ⬇️

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 10, 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

Comment on lines 122 to 121
if p.UseReadWriteAliases {
return func(_ time.Time) (string, string) {
return spanIndexPrefix + writeAlias, serviceIndexPrefix + writeAlias
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

When both UseReadWriteAliases and explicit aliases are configured, the current implementation will append the write alias suffix to the explicit aliases. This behavior may be inconsistent with the purpose of explicit aliases, which are typically intended to be used exactly as provided.

Consider one of these approaches:

  1. Check for explicit aliases before checking UseReadWriteAliases to prioritize the explicit alias behavior
  2. Add logic to handle the combination of both settings explicitly
  3. Document the current behavior in the configuration comments to clarify that explicit aliases will still receive the write suffix when UseReadWriteAliases is enabled

This would ensure the behavior is either consistent with user expectations or clearly documented.

Suggested change
if p.UseReadWriteAliases {
return func(_ time.Time) (string, string) {
return spanIndexPrefix + writeAlias, serviceIndexPrefix + writeAlias
}
}
if p.SpanIndexAlias != "" && p.ServiceIndexAlias != "" {
return func(_ time.Time) (string, string) {
return p.SpanIndexAlias, p.ServiceIndexAlias
}
}
if p.UseReadWriteAliases {
return func(_ time.Time) (string, string) {
return spanIndexPrefix + writeAlias, serviceIndexPrefix + writeAlias
}
}

Spotted by Graphite Agent

Fix in Graphite


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

@SomilJain0112
Copy link
Contributor Author

Hii @yurishkuro,
Please review the PR. Please let me know if any changes are required and I am going in the right direction for solving this issue or not.
Thanks!

@SomilJain0112
Copy link
Contributor Author

Hii @yurishkuro,
Please review this PR.
Thanks!

@SomilJain0112
Copy link
Contributor Author

Hii @yurishkuro ,
Please review this PR as well.
Thanks!

@SomilJain0112 SomilJain0112 force-pushed the fix/Added-fields-for-explicit-alias branch from bcc7b86 to 83eb73c Compare October 18, 2025 05:47
@SomilJain0112
Copy link
Contributor Author

Hii @yurishkuro ,
I have resolved all the comments made by you, please review the changes.
Thanks!

@SomilJain0112
Copy link
Contributor Author

Hii @yurishkuro , I have resolved comments. Please review here!

serviceIndexPrefix = p.ServiceIndexOverride
}

useAliasMode := p.UseReadWriteAliases || hasSpanOverride || hasServiceOverride
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
useAliasMode := p.UseReadWriteAliases || hasSpanOverride || hasServiceOverride
useAliasMode := p.UseReadWriteAliases

useAliasMode := p.UseReadWriteAliases || hasSpanOverride || hasServiceOverride

maxSpanAge := p.MaxSpanAge
// Setting the maxSpanAge to a large duration will ensure all spans in the "read" alias are accessible by queries (query window = [now - maxSpanAge, now]).
Copy link
Member

Choose a reason for hiding this comment

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

why are comments removed?

}

var timeRangeFn TimeRangeIndexFn
if hasSpanOverride || hasServiceOverride {
Copy link
Member

Choose a reason for hiding this comment

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

spaghetti. Keep all index logic in TimeRangeIndicesFn

Comment on lines 108 to 111
hasSpanOverride := p.SpanIndexOverride != ""
if hasSpanOverride {
spanIndexPrefix = p.SpanIndexOverride
}
Copy link
Member

Choose a reason for hiding this comment

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

why is this needed? There is a very simple function in L133 if p.UseReadWriteAliases { which covers the overrides condition and where overrides can be applied instead of composing index name from pieces

// SpanIndexOverride allows full control over the name of the index alias.
// Overrides any index prefix / suffix settings.
// Can only be used with UseReadWriteAliases=true.
SpanIndexOverride string `mapstructure:"span_index_override"`
Copy link
Member

Choose a reason for hiding this comment

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

how is this supposed to work with UseReadWriteAliases=true? When aliases are used the read and write indices are still different. So what does it mean to have a single SpanIndexOverride?

Copy link
Member

@yurishkuro yurishkuro Oct 25, 2025

Choose a reason for hiding this comment

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

When set, it replaces the prefix but read/write suffixes are still appended.

doesn't that go against the requirement expressed by the user?

@SomilJain0112
Copy link
Contributor Author

Hii @yurishkuro ,
Addressed your above comments and made changes accordingly in the code. Kindly review it.
Thanks!

Comment on lines +748 to +757
hasSpanAliases := c.SpanReadAlias != "" || c.SpanWriteAlias != ""
hasServiceAliases := c.ServiceReadAlias != "" || c.ServiceWriteAlias != ""

if hasSpanAliases && (c.SpanReadAlias == "" || c.SpanWriteAlias == "") {
return errors.New("both span_read_alias and span_write_alias must be set together")
}

if hasServiceAliases && (c.ServiceReadAlias == "" || c.ServiceWriteAlias == "") {
return errors.New("both service_read_alias and service_write_alias must be set together")
}
Copy link
Contributor

Choose a reason for hiding this comment

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

The validation logic enforces paired read/write aliases (for spans and services separately), but doesn't enforce consistency between span and service aliases. This creates a potential scenario where a user configures only span aliases without service aliases, or vice versa.

Consider enhancing the validation to either:

  1. Require all four aliases to be set when any are used, or
  2. Document the expected behavior when only span aliases or only service aliases are configured

The current implementation in reader.go handles this case by using explicit aliases when provided and falling back to prefix patterns, but this mixed approach should be clearly documented if it's the intended behavior.

Suggested change
hasSpanAliases := c.SpanReadAlias != "" || c.SpanWriteAlias != ""
hasServiceAliases := c.ServiceReadAlias != "" || c.ServiceWriteAlias != ""
if hasSpanAliases && (c.SpanReadAlias == "" || c.SpanWriteAlias == "") {
return errors.New("both span_read_alias and span_write_alias must be set together")
}
if hasServiceAliases && (c.ServiceReadAlias == "" || c.ServiceWriteAlias == "") {
return errors.New("both service_read_alias and service_write_alias must be set together")
}
hasSpanAliases := c.SpanReadAlias != "" || c.SpanWriteAlias != ""
hasServiceAliases := c.ServiceReadAlias != "" || c.ServiceWriteAlias != ""
hasAnyAliases := hasSpanAliases || hasServiceAliases
if hasSpanAliases && (c.SpanReadAlias == "" || c.SpanWriteAlias == "") {
return errors.New("both span_read_alias and span_write_alias must be set together")
}
if hasServiceAliases && (c.ServiceReadAlias == "" || c.ServiceWriteAlias == "") {
return errors.New("both service_read_alias and service_write_alias must be set together")
}
if hasAnyAliases && (!hasSpanAliases || !hasServiceAliases) {
return errors.New("all aliases (span_read_alias, span_write_alias, service_read_alias, service_write_alias) must be set together")
}

Spotted by Graphite Agent

Fix in Graphite


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

@SomilJain0112
Copy link
Contributor Author

Hii @yurishkuro
Now we will have complete control over naming that's what we were trying to achieve from this issue.
Please review, Thanks!

@SomilJain0112
Copy link
Contributor Author

Hii @yurishkuro
Please review this PR, Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants