Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(oas): update Tempo API #404

Merged
merged 22 commits into from
May 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
8e271d2
feat(oas): update Tempo API
tdakkota May 21, 2024
149797b
chore: commit generated files
tdakkota May 21, 2024
b11e9e2
chore(tempoproxy): update handler due to code changes
tdakkota May 21, 2024
4f5cf41
feat(traceql): parse autocomplete queries
tdakkota May 21, 2024
bf647e3
chore: make ogen output less verbose
tdakkota May 22, 2024
d283fba
feat(oas): add autocomplete parameter to `searchTagValues`
tdakkota May 22, 2024
ec05262
chore: commit generated files
tdakkota May 22, 2024
5d32a86
feat(traceql): add `ParseAttribute` function
tdakkota May 22, 2024
0a617d7
feat(tempohandler): update handler to latest API
tdakkota May 22, 2024
91c13d2
test(tempoe2e): update tests to latest API
tdakkota May 22, 2024
4b1d48d
feat(traceql): implement stringer for `AttributeScope`
tdakkota May 23, 2024
bd41c67
feat(tracestorage): collect tag scope
tdakkota May 23, 2024
95dc15b
refactor(chstorage): update code due to API changes
tdakkota May 23, 2024
d6ef0ec
feat(integration): filter ch-go logs
tdakkota May 23, 2024
2b314de
fix(tempohandler): deduplicate tag names
tdakkota May 23, 2024
b19f545
fix(tempoe2e): do not add span name to the tag set
tdakkota May 23, 2024
6c57007
chore: formatting
tdakkota May 23, 2024
36bd388
fix(tempohandler): make autocomplete queries opt-in
tdakkota May 23, 2024
c377a6c
fix(traceql): do not return empty intrinsic names
tdakkota May 23, 2024
392c83c
fix(chstorage): return valid intrinsic enum values
tdakkota May 23, 2024
1005db6
feat(tempohandler): implement `SearchTagsV2`
tdakkota May 23, 2024
9d60e6d
test(tempoe2e): add test for `SearchTagsV2`
tdakkota May 23, 2024
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
167 changes: 163 additions & 4 deletions _oas/tempo.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
openapi: 3.0.3
info:
title: Grafana Tempo 'query-frontend' API
version: 2.1.0
version: 2.4.0
externalDocs:
description: Tempo API reference
url: https://grafana.com/docs/tempo/latest/api_docs
Expand Down Expand Up @@ -33,12 +33,14 @@ paths:
schema:
type: string
description: TraceID to query.

- name: start
in: query
schema:
type: integer
format: unix-seconds
description: Along with `end` define a time range from which traces should be returned.

- name: end
in: query
schema:
Expand Down Expand Up @@ -116,6 +118,13 @@ paths:
Providing both `start` and `end` will change the way that Tempo searches.
If the parameters are not provided, then Tempo will search the recent trace data stored in the ingesters.
If the parameters are provided, it will search the backend as well.

- name: spss
in: query
schema:
type: integer
description: |
Limit the number of spans per span-set. Default value is 3.
responses:
200:
$ref: "#/components/responses/Search"
Expand All @@ -126,6 +135,30 @@ paths:
get:
operationId: searchTags
description: This endpoint retrieves all discovered tag names that can be used in search.
parameters:
- name: scope
in: query
schema:
$ref: "#/components/schemas/TagScope"
description: |
Specifies the scope of the tags, this is an optional parameter, if not specified it means all scopes.

- name: start
in: query
schema:
type: integer
format: unix-seconds
description: |
Along with `end` define a time range from which tags should be returned.

- name: end
in: query
schema:
type: integer
format: unix-seconds
description: |
Along with `start` define a time range from which tags should be returned.
Providing both `start` and `end` includes blocks for the specified time range only.
responses:
200:
$ref: "#/components/responses/SearchTags"
Expand All @@ -143,29 +176,123 @@ paths:
schema:
type: string
description: Tag name.

- name: q
in: query
schema:
type: string
description: |
If provided, the tag values returned by the API are filtered to only return values seen on spans matching your filter parameters.
Queries can be incomplete: for example, `{ .cluster = }`. Tempo extracts only the valid matchers and build a valid query.

Only queries with a single selector `{}`` and AND `&&` operators are supported.

- Example supported: `{ .cluster = "us-east-1" && .service = "frontend" }`
- Example unsupported: `{ .cluster = "us-east-1" || .service = "frontend" } && { .cluster = "us-east-2" }`

- name: start
in: query
schema:
type: integer
format: unix-seconds
description: |
Along with `end` define a time range from which tags should be returned.

- name: end
in: query
schema:
type: integer
format: unix-seconds
description: |
Along with `start` define a time range from which tags should be returned.
Providing both `start` and `end` includes blocks for the specified time range only.
responses:
200:
$ref: "#/components/responses/SearchTagValues"
default:
$ref: "#/components/responses/Error"

/api/v2/search/tag/{tag_name}/values:
/api/v2/search/tag/{attribute_selector}/values:
get:
operationId: searchTagValuesV2
description: This endpoint retrieves all discovered values and their data types for the given TraceQL identifier.
parameters:
- name: tag_name
- name: attribute_selector
in: path
required: true
schema:
type: string
description: Tag name.
description: TraceQL attribute selector (`.service.name`, `resource.service.name`, etc.).

- name: q
in: query
schema:
type: string
description: |
If provided, the tag values returned by the API are filtered to only return values seen on spans matching your filter parameters.
Queries can be incomplete: for example, `{ .cluster = }`. Tempo extracts only the valid matchers and build a valid query.

Only queries with a single selector `{}`` and AND `&&` operators are supported.

- Example supported: `{ .cluster = "us-east-1" && .service = "frontend" }`
- Example unsupported: `{ .cluster = "us-east-1" || .service = "frontend" } && { .cluster = "us-east-2" }`

- name: start
in: query
schema:
type: integer
format: unix-seconds
description: |
Along with `end` define a time range from which tags should be returned.

- name: end
in: query
schema:
type: integer
format: unix-seconds
description: |
Along with `start` define a time range from which tags should be returned.
Providing both `start` and `end` includes blocks for the specified time range only.
responses:
200:
$ref: "#/components/responses/SearchTagValuesV2"
default:
$ref: "#/components/responses/Error"

/api/v2/search/tags:
get:
operationId: searchTagsV2
description: This endpoint retrieves all discovered tag names that can be used in search.
parameters:
- name: scope
in: query
schema:
$ref: "#/components/schemas/TagScope"
description: |
Specifies the scope of the tags, this is an optional parameter, if not specified it means all scopes.

- name: start
in: query
schema:
type: integer
format: unix-seconds
description: |
Along with `end` define a time range from which tags should be returned.

- name: end
in: query
schema:
type: integer
format: unix-seconds
description: |
Along with `start` define a time range from which tags should be returned.
Providing both `start` and `end` includes blocks for the specified time range only.
responses:
200:
$ref: "#/components/responses/SearchTagsV2"
default:
$ref: "#/components/responses/Error"

components:
responses:
Error:
Expand Down Expand Up @@ -201,6 +328,12 @@ components:
"application/json":
schema:
$ref: "#/components/schemas/TagValues"
SearchTagsV2:
description: Search tags result
content:
"application/json":
schema:
$ref: "#/components/schemas/TagNamesV2"
SearchTagValuesV2:
description: Search tag values result
content:
Expand Down Expand Up @@ -354,6 +487,24 @@ components:
items:
type: string

TagNamesV2:
type: object
properties:
scopes:
type: array
items:
$ref: "#/components/schemas/ScopeTags"
ScopeTags:
type: object
required: [name]
properties:
name:
$ref: "#/components/schemas/TagScope"
tags:
type: array
items:
type: string

TagValuesV2:
type: object
properties:
Expand All @@ -372,5 +523,13 @@ components:
value:
type: string

TagScope:
type: string
enum:
- "span"
- "resource"
- "intrinsic"
- "none"

Error:
type: string
2 changes: 1 addition & 1 deletion cmd/oteldb/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ func (app *App) trySetupTempo() error {
engine := traceqlengine.NewEngine(app.traceQuerier, traceqlengine.Options{
TracerProvider: app.metrics.TracerProvider(),
})
tempo := tempohandler.NewTempoAPI(q, engine)
tempo := tempohandler.NewTempoAPI(q, engine, tempohandler.TempoAPIOptions{})

s, err := tempoapi.NewServer(tempo,
tempoapi.WithTracerProvider(app.metrics.TracerProvider()),
Expand Down
49 changes: 49 additions & 0 deletions integration/logger.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package integration

import (
"testing"

"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"go.uber.org/zap/zaptest"
)

// Logger creates a new [zap.Logger] to use in tests.
func Logger(t *testing.T) *zap.Logger {
return zaptest.NewLogger(t, zaptest.WrapOptions(zap.WrapCore(wrapTestLogger)))
}

func wrapTestLogger(core zapcore.Core) zapcore.Core {
return &filterCore{core: core}
}

type filterCore struct {
core zapcore.Core
}

var _ zapcore.Core = (*filterCore)(nil)

func (c *filterCore) Enabled(l zapcore.Level) bool {
return c.core.Enabled(l)
}

func (c *filterCore) With(fields []zapcore.Field) zapcore.Core {
return &filterCore{
core: c.core.With(fields),
}
}

func (c *filterCore) Check(e zapcore.Entry, ce *zapcore.CheckedEntry) *zapcore.CheckedEntry {
if ce == nil || ce.LoggerName == "ch" {
return ce
}
return c.core.Check(e, ce)
}

func (c *filterCore) Write(e zapcore.Entry, fields []zapcore.Field) error {
return c.core.Write(e, fields)
}

func (c *filterCore) Sync() error {
return c.core.Sync()
}
3 changes: 1 addition & 2 deletions integration/lokie2e/ch_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import (
"github.com/go-faster/sdk/zctx"
"github.com/stretchr/testify/require"
"github.com/testcontainers/testcontainers-go"
"go.uber.org/zap/zaptest"

"github.com/go-faster/oteldb/integration"
"github.com/go-faster/oteldb/internal/chstorage"
Expand Down Expand Up @@ -91,6 +90,6 @@ func TestCH(t *testing.T) {
})
require.NoError(t, err)

ctx = zctx.Base(ctx, zaptest.NewLogger(t))
ctx = zctx.Base(ctx, integration.Logger(t))
runTest(ctx, t, provider, inserter, querier, querier)
}
2 changes: 2 additions & 0 deletions integration/prome2e/ch_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/ClickHouse/ch-go/chpool"
"github.com/cenkalti/backoff/v4"
"github.com/go-faster/errors"
"github.com/go-faster/sdk/zctx"
"github.com/google/uuid"
"github.com/stretchr/testify/require"
"github.com/testcontainers/testcontainers-go"
Expand Down Expand Up @@ -76,5 +77,6 @@ func TestCH(t *testing.T) {
querier, err := chstorage.NewQuerier(c, chstorage.QuerierOptions{Tables: tables})
require.NoError(t, err)

ctx = zctx.Base(ctx, integration.Logger(t))
runTest(ctx, t, inserter, querier, querier)
}
2 changes: 2 additions & 0 deletions integration/tempoe2e/ch_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/ClickHouse/ch-go/chpool"
"github.com/cenkalti/backoff/v4"
"github.com/go-faster/errors"
"github.com/go-faster/sdk/zctx"
"github.com/google/uuid"
"github.com/stretchr/testify/require"
"github.com/testcontainers/testcontainers-go"
Expand Down Expand Up @@ -76,5 +77,6 @@ func TestCH(t *testing.T) {
querier, err := chstorage.NewQuerier(c, chstorage.QuerierOptions{Tables: tables})
require.NoError(t, err)

ctx = zctx.Base(ctx, integration.Logger(t))
runTest(ctx, t, inserter, querier, querier)
}
Loading
Loading