mirror of
https://github.com/hanzoai/o11y.git
synced 2026-10-15 12:58:33 +00:00
MAIN HAD NOT COMPILED SINCE 2026-07-30. Commit 5e3210f759 rewrote tables.go in three telemetry packages and the sentrytypes Event struct without updating their consumers, while its message claimed the read paths 'build clean' — proven false with a detached worktree at clean HEAD. That is why the deployed backend is SHA-pinned and stale: CI could not build main at all. THE RENAME: /api/v1|v2|v3|v4/<rest> -> /v1/o11y/<rest> (290 replacements; the host already says api, so the path never does, and one live generation carries no version segments). 21 duplicate v1 registrations DELETED with their v2 twins kept — gorilla/mux is first-match, so after the collapse the v1 line would have shadowed v2 silently, with no error, forever: rules (6), dashboards (6), services/top_operations/entry_point_operations/ttl (5), features, query_range v3+v4 -> v5, metrics/dashboards. 16 orphaned handler funcs (430 lines) deleted. CONSUMERS MIGRATED to the one-way table names, never the reverse: tables.go's deletion of the versioned constants was deliberate (stated three times), and the new blocks are positional 1:1 rewrites of the old, so every resolution is a constant the same commit declared — SpanIndexV3->span, LogsV2->log, SamplesV4->metric, TimeseriesV4->series, UpdatedMetadata->descriptor, ambiguity on operation-vs-trace settled by tables.go's own inline comments. sentrytypes.Frame/Event.Frames/Event.Handled RECONSTRUCTED, not guessed: pinned independently by eventsql.go's projection, eventstore.go's scan targets and module.go's clampLine/InApp, and asserted literally by the pre-existing TestFramesRoundTrip. TraceSummary.Sample -> Message (event.error has no sample column). Event.Sample deleted: a field that always read "" while claiming to hold the occurrence JSON. PATH MANGLERS KILLED, both deployment shapes: mount.go rewriteExternalPath+ setPath deleted (it mapped /v1/o11y/services -> /api/services => 404 on the cloud-binary path — proven with a real test before deletion); server.go StripPrefix removed (it reduced /v1/o11y/services -> /services => the web catch-all answered index.html on the standalone path). versionless.go + versionless_test.go + both call sites deleted: its regex matched 0 of the registered routes and walked the router at every startup to register nothing — the second spelling of one path, gone with the mechanism that needed it. FRONTEND: prependBase '/api/v1/' -> '/v1/o11y/' (both baseURL branches), 17 /api/v1/assistant literals renamed (note: no assistant route exists in pkg/ — client-only surface, a real product gap, not papered over), 21 MSW mocks moved so they intercept the paths the app now requests. GATE, all executed: go build ./... green; go test ./... green (exit 0); 0 /api/v[0-9] references in pkg code (frontend's 5 are query-builder escaping fixtures); 0 duplicate (method,path) registrations; /v1/o11y/services survives both mount.go and server.go untouched. Co-authored-by: Hanzo Dev <[email protected]>
112 lines
3.5 KiB
Go
112 lines
3.5 KiB
Go
package telemetrytraces
|
|
|
|
import (
|
|
"context"
|
|
"log/slog"
|
|
|
|
"github.com/hanzoai/o11y/pkg/errors"
|
|
"github.com/hanzoai/o11y/pkg/factory"
|
|
"github.com/hanzoai/o11y/pkg/flagger"
|
|
"github.com/hanzoai/o11y/pkg/querybuilder"
|
|
"github.com/hanzoai/o11y/pkg/telemetryresourcefilter"
|
|
qbtypes "github.com/hanzoai/o11y/pkg/types/querybuildertypes/querybuildertypesv5"
|
|
"github.com/hanzoai/o11y/pkg/types/telemetrytypes"
|
|
)
|
|
|
|
type traceOperatorStatementBuilder struct {
|
|
logger *slog.Logger
|
|
metadataStore telemetrytypes.MetadataStore
|
|
fm qbtypes.FieldMapper
|
|
cb qbtypes.ConditionBuilder
|
|
traceStmtBuilder qbtypes.StatementBuilder[qbtypes.TraceAggregation]
|
|
resourceFilterStmtBuilder qbtypes.StatementBuilder[qbtypes.TraceAggregation]
|
|
aggExprRewriter qbtypes.AggExprRewriter
|
|
}
|
|
|
|
var _ qbtypes.TraceOperatorStatementBuilder = (*traceOperatorStatementBuilder)(nil)
|
|
|
|
func NewTraceOperatorStatementBuilder(
|
|
settings factory.ProviderSettings,
|
|
metadataStore telemetrytypes.MetadataStore,
|
|
fieldMapper qbtypes.FieldMapper,
|
|
conditionBuilder qbtypes.ConditionBuilder,
|
|
traceStmtBuilder qbtypes.StatementBuilder[qbtypes.TraceAggregation],
|
|
aggExprRewriter qbtypes.AggExprRewriter,
|
|
flagger flagger.Flagger,
|
|
) *traceOperatorStatementBuilder {
|
|
tracesSettings := factory.NewScopedProviderSettings(settings, "github.com/hanzoai/o11y/pkg/telemetrytraces")
|
|
|
|
resourceFilterStmtBuilder := telemetryresourcefilter.New[qbtypes.TraceAggregation](
|
|
settings,
|
|
DBName,
|
|
SpanResourceTableName,
|
|
telemetrytypes.SignalTraces,
|
|
telemetrytypes.SourceUnspecified,
|
|
metadataStore,
|
|
nil,
|
|
nil,
|
|
flagger,
|
|
)
|
|
|
|
return &traceOperatorStatementBuilder{
|
|
logger: tracesSettings.Logger(),
|
|
metadataStore: metadataStore,
|
|
fm: fieldMapper,
|
|
cb: conditionBuilder,
|
|
traceStmtBuilder: traceStmtBuilder,
|
|
resourceFilterStmtBuilder: resourceFilterStmtBuilder,
|
|
aggExprRewriter: aggExprRewriter,
|
|
}
|
|
}
|
|
|
|
// Build builds a SQL query based on the given parameters.
|
|
func (b *traceOperatorStatementBuilder) Build(
|
|
ctx context.Context,
|
|
start uint64,
|
|
end uint64,
|
|
requestType qbtypes.RequestType,
|
|
query qbtypes.QueryBuilderTraceOperator,
|
|
compositeQuery *qbtypes.CompositeQuery,
|
|
) (*qbtypes.Statement, error) {
|
|
|
|
start = querybuilder.ToNanoSecs(start)
|
|
end = querybuilder.ToNanoSecs(end)
|
|
|
|
// Parse the expression if not already parsed
|
|
if query.ParsedExpression == nil {
|
|
if err := query.ParseExpression(); err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
// Validate compositeQuery parameter
|
|
if compositeQuery == nil {
|
|
return nil, errors.NewInvalidInputf(errors.CodeInvalidInput, "compositeQuery cannot be nil")
|
|
}
|
|
|
|
b.logger.DebugContext(ctx, "Building trace operator query",
|
|
slog.String("expression", query.Expression),
|
|
slog.Any("request_type", requestType))
|
|
|
|
// Build the CTE-based query
|
|
builder := &traceOperatorCTEBuilder{
|
|
start: start,
|
|
end: end,
|
|
operator: &query,
|
|
stmtBuilder: b,
|
|
queries: make(map[string]*qbtypes.QueryBuilderQuery[qbtypes.TraceAggregation]),
|
|
ctes: []cteNode{}, // Use slice to maintain order
|
|
cteNameToIndex: make(map[string]int),
|
|
queryToCTEName: make(map[string]string),
|
|
compositeQuery: compositeQuery, // Now passed as explicit parameter
|
|
}
|
|
|
|
// Collect all referenced queries
|
|
if err := builder.collectQueries(); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Build the query
|
|
return builder.build(ctx, requestType)
|
|
}
|