Skip to content

ES/OS filter refuses most built-in fields although the schema indexes them #9474

Description

@yurishkuro

Summary

The Elasticsearch/OpenSearch filter lowering serves 4 of the built-in fields RFC 0005
defines — span.name, span.duration, resource.service, event.name — and refuses the
rest. For most of the refused ones the value is already indexed, so the gap is a missing
mapping from the field to the column that holds it, not missing data.

Verified against a production OpenSearch cluster over a 6-hour window. Counts are trace
counts for an exists query on the attribute spelling of the same value.

field where the value is indexed today
span.traceID traceID, top-level keyword refused: does not support the built-in field
span.spanID spanID, top-level keyword refused: does not support the built-in field
scope.name otel.scope.name tag — present on 100 traces refused: does not index the "scope" level
scope.version otel.scope.version tag — present on 100 traces refused: does not index the "scope" level
link.traceID references.traceID, nested keyword refused: does not index the "link" level
link.spanID references.spanID, nested keyword refused: does not index the "link" level
span.startTime startTime long and startTimeMillis date refused: a timestamp constant declares a type this schema cannot search
event.time logs.timestamp, nested refused: a timestamp constant declares a type this schema cannot search

span.kind and span.status are the same shape and are filed separately as #9473.

Two distinct causes

No case for the field. buildComparison and buildMembership
(core/filter.go)
switch on a handful of fields and send everything else to errUnsupportedField, and the
scope and link levels are refused wholesale before any field is looked at. traceID and
spanID are top-level keywords in the span mapping, and references.traceID /
references.spanID are indexed inside the existing references nested type, which the
lowering already knows how to query for other purposes.

The timestamp constant type is unsupported. span.startTime and event.time are
refused for the constant rather than for the field. This one is the most surprising of the
set, because startTimeMillis is mapped as a date specifically so that time-range queries
work — the reader already uses it for the query's own time bounds — and logs.timestamp is
mapped for events. So an ordered comparison on an instant has exactly the right index
waiting for it.

The level-wide refusals are inaccurate as stated

errUnsupportedLevel says the schema "does not index the scope level". It does index part
of it: getTagsFromInstrumentationLibrary
(to_dbmodel.go)
writes otel.scope.name and otel.scope.version as span tags, and from_dbmodel.go reads
them back into the scope and removes them from the span. What the schema genuinely drops is
the scope's attributes, which that function never writes.

The link level is the same: dbmodel.Reference keeps only the trace ID, span ID and
reference type, so link attributes are genuinely absent, while the two IDs are indexed.

So scope.attr(...) and link.attr(...) are correctly refused and should stay refused; it
is the four built-in fields beside them that have somewhere to go.

Suggested fix

Refuse per field rather than per level, and add cases for the fields whose column exists:
span.traceID, span.spanID, scope.name, scope.version, link.traceID and
link.spanID. Separately, support the timestamp constant type so span.startTime and
event.time can lower to a range over startTimeMillis and logs.timestamp.

Reword errUnsupportedLevel so it says which part of a level is unindexed, since a level
that stores its identity but not its attributes is the common case rather than the exception.

Environment

Jaeger f7d52c13a, OpenSearch, both api_v3 bindings, filters behind the
jaeger.query.structuredFilters feature gate.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    good first issueGood for beginnershelp wantedFeatures that maintainers are willing to accept but do not have cycles to implement

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions