Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ Additionally the `compaction_tenant_backoff_total` metric has been renamed to `c
* [BUGFIX] fix tempo configuration options that are always overrided with config overrides section [#5202](https://github.com/grafana/tempo/pull/5202) (@KyriosGN0)
* [ENHANCEMENT] Add endpoint for partition downscaling [#4913](https://github.com/grafana/tempo/pull/4913) (@mapno)
* [ENHANCEMENT] Add alert for high error rate reported by vulture [#5206](https://github.com/grafana/tempo/pull/5206) (@ruslan-mikhailov)
* [ENHANCEMENT] Support the new `db.namespace` attribute for service-graph DB nodes [#5602](https://github.com/grafana/tempo/pull/5602) (@gouthamve)
* [ENHANCEMENT] Add backend scheduler and worker to the resources dashboard [#5206](https://github.com/grafana/tempo/pull/5241) (@javiermolinar)
* [ENHANCEMENT] Allow configure group lag exporter update time [#5431](https://github.com/grafana/tempo/pull/5431) (@javiermolinar)
* [ENHANCEMENT] TraceQL metrics performance increase for simple queries [#5247](https://github.com/grafana/tempo/pull/5247) (@mdisibio)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ It supports the following requests:

- A direct request between two services where the outgoing and the incoming span must have [`span.kind`](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/api.md#spankind), `client`, and `server`, respectively.
- A request across a messaging system where the outgoing and the incoming span must have `span.kind`, `producer`, and `consumer` respectively.
- A database request; in this case the processor looks for spans containing attributes `span.kind`=`client` as well as one of `db.name` or `db.system`. See below for how the name of the node is determined for a database request.
- A database request; in this case the processor looks for spans containing attributes `span.kind`=`client` as well as one of `db.namespace`, `db.name` or `db.system`. See below for how the name of the node is determined for a database request.

Every span that can be paired up to form a request is kept in an in-memory store, until its corresponding pair span is received or the maximum waiting time has passed.
When either of these conditions are reached, the request is recorded and removed from the local store.
Expand All @@ -63,9 +63,9 @@ Virtual nodes can be detected in two different ways:
- The default peer attributes are `peer.service`, `db.name` and `db.system`.
- The order of the attributes is important, as the first one is used as the virtual node name.

A database node is identified by the span having at least `db.name` or `db.system` attribute.
A database node is identified by the span having at least `db.namespace`, `db.name` or `db.system` attribute.

The name of a database node is determined using the following span attributes in order of precedence: `peer.service`, `server.address`, `network.peer.address:network.peer.port`, `db.name`.
The name of a database node is determined using the following span attributes in order of precedence: `peer.service`, `server.address`, `network.peer.address:network.peer.port`, `db.namespace`, `db.name`.

### Metrics

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"github.com/prometheus/prometheus/util/strutil"
"go.opentelemetry.io/otel/attribute"
semconv "go.opentelemetry.io/otel/semconv/v1.25.0"
semconvnew "go.opentelemetry.io/otel/semconv/v1.34.0"

gen "github.com/grafana/tempo/modules/generator/processor"
"github.com/grafana/tempo/modules/generator/processor/servicegraphs/store"
Expand Down Expand Up @@ -286,11 +287,15 @@ func (p *Processor) upsertDatabaseRequest(e *store.Edge, resourceAttr []*v1_comm
dbName string
)

// Check for db.name first. The dbName is set initially to maintain backwards compatbility.
// Check for db.name or db.namespace first. The dbName is set initially to maintain backwards compatbility.
if name, ok := processor_util.FindAttributeValue(string(semconv.DBNameKey), resourceAttr, span.Attributes); ok {
dbName = name
isDatabase = true
}
if name, ok := processor_util.FindAttributeValue(string(semconvnew.DBNamespaceKey), span.Attributes); ok {
dbName = name
isDatabase = true
}

// Check for db.system only if we don't have db.name above
if !isDatabase {
Expand Down
24 changes: 24 additions & 0 deletions modules/generator/processor/servicegraphs/servicegraphs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
semconv "go.opentelemetry.io/otel/semconv/v1.25.0"
semconvnew "go.opentelemetry.io/otel/semconv/v1.34.0"

"github.com/grafana/tempo/modules/generator/registry"
"github.com/grafana/tempo/pkg/tempopb"
Expand All @@ -32,6 +33,7 @@ func TestSemconvKeys(t *testing.T) {
require.Equal(t, string(semconv.NetworkPeerAddressKey), "network.peer.address")
require.Equal(t, string(semconv.NetworkPeerPortKey), "network.peer.port")
require.Equal(t, string(semconv.ServerAddressKey), "server.address")
require.Equal(t, string(semconvnew.DBNamespaceKey), "db.namespace")
}

func TestServiceGraphs(t *testing.T) {
Expand Down Expand Up @@ -447,6 +449,28 @@ func TestServiceGraphs_databaseVirtualNodes(t *testing.T) {
total: 1.0,
errors: 0.0,
},
{
name: "dbNamespaceAttribute",
fixturePath: "testdata/trace-with-db-namespace.json",
databaseLabels: labels.FromMap(map[string]string{
"client": "mythical-server",
"server": "mydb",
"connection_type": "database",
}),
total: 1.0,
errors: 0.0,
},
{
name: "bothDbNameAndNamespace",
fixturePath: "testdata/trace-with-both-db-attributes.json",
databaseLabels: labels.FromMap(map[string]string{
"client": "mythical-server",
"server": "priority-db",
"connection_type": "database",
}),
total: 1.0,
errors: 0.0,
},
}

for _, tc := range cases {
Expand Down
Loading
Loading