recipes/beyla-service-graph/collector-config.yaml (107 lines of code) (raw):
# Copyright 2023 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: opentelemetry.io/v1alpha1
kind: OpenTelemetryCollector
metadata:
name: otel
spec:
image: otel/opentelemetry-collector-contrib:0.112.0
config: |
receivers:
# receive OTLP spans from Beyla
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
http:
endpoint: 0.0.0.0:4318
connectors:
# convert spans into a calls metric
spanmetrics/servicegraph:
histogram:
disable: true
dimensions:
- name: server.address
- name: client.address
exclude_dimensions:
- 'status.code'
- 'span.kind'
- 'span.name'
- 'service.name'
- 'rpc.method'
- 'rpc.system'
- 'rpc.grpc.status_code'
- 'server.port'
processors:
# filter down to only non-local http server spans
filter/serveronly:
error_mode: ignore
traces:
span:
- attributes["http.request.method"] == nil and attributes["rpc.method"] == nil
- kind.string != "Server"
- attributes["server.address"] == "127.0.0.1"
# detect gke resource attributes
resourcedetection:
detectors: [env, gcp]
timeout: 2s
override: false
# Move server and client address from metric attributes to resource attributes so we can
# use it to get k8s.pod.name for the server and client pods
groupbyattrs:
keys:
- server.address
- client.address
# Metrics are generated from server spans only, so k8s.pod.name already contains the server pod
transform/k8spodname_to_server:
metric_statements:
- context: resource
statements:
- set(attributes["server"], attributes["k8s.pod.name"])
- delete_key(attributes, "k8s.pod.name")
# Put the client address into k8s.pod.ip for k8sattributes processor to detect the client pod name
- set(attributes["k8s.pod.ip"], attributes["client.address"])
# Add k8s.pod.name
k8sattributes:
extract:
metadata:
- k8s.pod.name
pod_association:
- sources:
- from: resource_attribute
name: k8s.pod.ip
# Moves annotated k8s.pod.name to client.address
transform/k8spodname_to_client:
metric_statements:
- context: resource
statements:
- set(attributes["client"], attributes["k8s.pod.name"])
- delete_key(attributes, "k8s.pod.name")
- delete_key(attributes, "k8s.pod.ip")
transform/servicegraphconventions:
metric_statements:
- context: datapoint
statements:
# GMP metrics are expected to be double
- set(value_double, Double(value_int))
# Rename metric to match the servicegraphconnector's output
# https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/connector/servicegraphconnector#how-it-works
- context: metric
statements:
- set(name, "traces_service_graph_request") where name == "traces.span.metrics.calls"
resource/podinstance:
attributes:
- key: pod
from_attribute: k8s.pod.name
action: upsert
- key: service.instance.id
from_attribute: k8s.pod.uid
action: upsert
exporters:
googlemanagedprometheus:
metric:
resource_filters:
- regex: 'pod'
- regex: client
- regex: server
service:
pipelines:
traces:
receivers: [otlp]
processors: [filter/serveronly]
exporters: [spanmetrics/servicegraph]
metrics:
receivers: [spanmetrics/servicegraph]
processors:
- groupbyattrs
- transform/k8spodname_to_server
- k8sattributes
- transform/k8spodname_to_client
- transform/servicegraphconventions
- resourcedetection
exporters: [googlemanagedprometheus]