Opentelemetry Collector
Данное практическое занятие посвящено знакомству с opentelemetry collector, с помощью которого можно отправлять метрики, логи и трейсы в различные хранилища для дальнейшей обработки и анализа.
Vagrant
Для работы будем использовать следующий Vagrantfile
:
Vagrant.configure("2") do |config|
config.vm.define "otel" do |c|
c.vm.provider "virtualbox" do |v|
v.cpus = 2
v.memory = 2048
end
c.vm.box = "ubuntu/lunar64"
c.vm.hostname = "otel"
c.vm.network "forwarded_port", guest: 8888, host: 8888
c.vm.provision "shell", inline: <<-SHELL
apt-get update -q
apt-get install -yq docker.io docker-compose-v2
usermod -a -G docker vagrant
docker pull ghcr.io/open-telemetry/opentelemetry-collector-contrib/telemetrygen:latest
docker inspect ghcr.io/open-telemetry/opentelemetry-collector-contrib/telemetrygen:latest \
| jq -r '.[0].GraphDriver.Data.UpperDir' \
| xargs -i sudo cp {}/telemetrygen /usr/local/bin/
SHELL
end
end
Данная конфигурация установит на виртуальную машину docker и docker compose, с помощью которых в дальнейшем будут развернуты остальные компоненты. А также поставит утилиту telemetrygen, с помощью которой можно будет сгенерировать метрики, логи и трейсы и отправить в коллектор.
Collector
Развернем коллектор при помощи docker-compose, для этого зададим для него
конфигурацию в файл config.yaml
:
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
processors:
batch:
exporters:
debug:
verbosity: detailed
service:
pipelines:
logs:
receivers: [otlp]
processors: [batch]
exporters: [debug]
metrics:
receivers: [otlp]
processors: [batch]
exporters: [debug]
traces:
receivers: [otlp]
processors: [batch]
exporters: [debug]
Данная конфигурация позволяет принимать метрики, логи и трейсы по протоколу otlp и
выводить информацию об этом в лог коллектора.
После чего создадим сам файл compose.yaml
:
services:
otel-collector:
container_name: collector
image: otel/opentelemetry-collector-contrib:0.86.0
ports:
- 4317:4317
volumes:
- ./config.yaml:/etc/otelcol-contrib/config.yaml
Запустим и отправим метрику в коллектор утилитой telemetrygen, после чего увидим ее в логах коллектора:
$ docker compose up -d
[+] Running 2/2
✔ Network vagrant_default Created 0.1s
✔ Container collector Started 0.9s
$ telemetrygen metrics --otlp-insecure
2024-04-24T17:09:35.396Z INFO metrics/metrics.go:30 starting the metrics generator with configuration {"config": {"WorkerCount":1,"Rate":0,"TotalDuration":0,"ReportingInterval":1000000000,"SkipSettingGRPCLogger":false,"CustomEndpoint":"","Insecure":true,"UseHTTP":false,"HTTPPath":"/v1/metrics","Headers":{},"ResourceAttributes":{},"TelemetryAttributes":{},"CaFile":"","ClientAuth":{"Enabled":false,"ClientCertFile":"","ClientKeyFile":""},"NumMetrics":1,"MetricType":"Gauge"}}
2024-04-24T17:09:35.396Z INFO metrics/metrics.go:81 generation of metrics isn't being throttled
2024-04-24T17:09:35.396Z INFO metrics/metrics.go:49 starting gRPC exporter
2024-04-24T17:09:35.397Z INFO grpc@v1.63.2/clientconn.go:427 [core][Channel #1]Channel created {"system": "grpc", "grpc_log": true}
2024-04-24T17:09:35.397Z INFO grpc@v1.63.2/clientconn.go:1668 [core][Channel #1]original dial target is: "localhost:4317" {"system": "grpc", "grpc_log": true}
2024-04-24T17:09:35.397Z INFO grpc@v1.63.2/clientconn.go:1675 [core][Channel #1]parsed dial target is: resolver.Target{URL:url.URL{Scheme:"localhost", Opaque:"4317", User:(*url.Userinfo)(nil), Host:"", Path:"", RawPath:"", OmitHost:false, ForceQuery:false, RawQuery:"", Fragment:"", RawFragment:""}} {"system": "grpc", "grpc_log": true}
2024-04-24T17:09:35.397Z INFO grpc@v1.63.2/clientconn.go:1694 [core][Channel #1]fallback to scheme "dns" {"system": "grpc", "grpc_log": true}
2024-04-24T17:09:35.397Z INFO grpc@v1.63.2/clientconn.go:1702 [core][Channel #1]parsed dial target is: dns:///localhost:4317 {"system": "grpc", "grpc_log": true}
2024-04-24T17:09:35.397Z INFO grpc@v1.63.2/clientconn.go:1825 [core][Channel #1]Channel authority set to "localhost:4317" {"system": "grpc", "grpc_log": true}
2024-04-24T17:09:35.397Z INFO grpc@v1.63.2/clientconn.go:332 [core][Channel #1]Channel exiting idle mode {"system": "grpc", "grpc_log": true}
2024-04-24T17:09:35.398Z INFO grpc@v1.63.2/resolver_wrapper.go:197 [core][Channel #1]Resolver state updated: {
"Addresses": [
{
"Addr": "127.0.0.1:4317",
"ServerName": "",
"Attributes": null,
"BalancerAttributes": null,
"Metadata": null
}
],
"Endpoints": [
{
"Addresses": [
{
"Addr": "127.0.0.1:4317",
"ServerName": "",
"Attributes": null,
"BalancerAttributes": null,
"Metadata": null
}
],
"Attributes": null
}
],
"ServiceConfig": null,
"Attributes": null
} (resolver returned new addresses) {"system": "grpc", "grpc_log": true}
2024-04-24T17:09:35.399Z INFO grpc@v1.63.2/balancer_wrapper.go:103 [core][Channel #1]Channel switches to new LB policy "pick_first" {"system": "grpc", "grpc_log": true}
2024-04-24T17:09:35.399Z INFO grpc@v1.63.2/balancer_wrapper.go:170 [core][Channel #1 SubChannel #2]Subchannel created {"system": "grpc", "grpc_log": true}
2024-04-24T17:09:35.399Z INFO grpc@v1.63.2/clientconn.go:531 [core][Channel #1]Channel Connectivity change to CONNECTING {"system": "grpc", "grpc_log": true}
2024-04-24T17:09:35.399Z INFO grpc@v1.63.2/clientconn.go:1195 [core][Channel #1 SubChannel #2]Subchannel Connectivity change to CONNECTING {"system": "grpc", "grpc_log": true}
2024-04-24T17:09:35.399Z INFO grpc@v1.63.2/clientconn.go:1310 [core][Channel #1 SubChannel #2]Subchannel picks a new address "127.0.0.1:4317" to connect {"system": "grpc", "grpc_log": true}
2024-04-24T17:09:35.400Z INFO grpc@v1.63.2/clientconn.go:1195 [core][Channel #1 SubChannel #2]Subchannel Connectivity change to READY {"system": "grpc", "grpc_log": true}
2024-04-24T17:09:35.401Z INFO grpc@v1.63.2/clientconn.go:531 [core][Channel #1]Channel Connectivity change to READY {"system": "grpc", "grpc_log": true}
2024-04-24T17:09:35.402Z INFO metrics/worker.go:103 metrics generated {"worker": 0, "metrics": 1}
$ docker logs collector
2024-04-24T17:07:40.261Z info service@v0.86.0/telemetry.go:84 Setting up own telemetry...
2024-04-24T17:07:40.261Z info service@v0.86.0/telemetry.go:201 Serving Prometheus metrics {"address": ":8888", "level": "Basic"}
2024-04-24T17:07:40.261Z info exporter@v0.86.0/exporter.go:275 Development component. May change in the future. {"kind": "exporter", "data_type": "metrics", "name": "debug"}
2024-04-24T17:07:40.262Z info exporter@v0.86.0/exporter.go:275 Development component. May change in the future. {"kind": "exporter", "data_type": "logs", "name": "debug"}
2024-04-24T17:07:40.262Z info exporter@v0.86.0/exporter.go:275 Development component. May change in the future. {"kind": "exporter", "data_type": "traces", "name": "debug"}
2024-04-24T17:07:40.262Z info service@v0.86.0/service.go:138 Starting otelcol-contrib... {"Version": "0.86.0", "NumCPU": 2}
2024-04-24T17:07:40.262Z info extensions/extensions.go:31 Starting extensions...
2024-04-24T17:07:40.263Z warn internal@v0.86.0/warning.go:40 Using the 0.0.0.0 address exposes this server to every network interface, which may facilitate Denial of Service attacks {"kind": "receiver", "name": "otlp", "data_type": "metrics", "documentation": "https://github.com/open-telemetry/opentelemetry-collector/blob/main/docs/security-best-practices.md#safeguards-against-denial-of-service-attacks"}
2024-04-24T17:07:40.263Z info otlpreceiver@v0.86.0/otlp.go:83 Starting GRPC server {"kind": "receiver", "name": "otlp", "data_type": "metrics", "endpoint": "0.0.0.0:4317"}
2024-04-24T17:07:40.263Z info service@v0.86.0/service.go:161 Everything is ready. Begin running and processing data.
2024-04-24T17:09:35.531Z info MetricsExporter {"kind": "exporter", "data_type": "metrics", "name": "debug", "resource metrics": 1, "metrics": 1, "data points": 1}
2024-04-24T17:09:35.531Z info ResourceMetrics #0
Resource SchemaURL: https://opentelemetry.io/schemas/1.13.0
ScopeMetrics #0
ScopeMetrics SchemaURL:
InstrumentationScope
Metric #0
Descriptor:
-> Name: gen
-> Description:
-> Unit:
-> DataType: Gauge
NumberDataPoints #0
StartTimestamp: 1970-01-01 00:00:00 +0000 UTC
Timestamp: 2024-04-24 17:09:35.397178162 +0000 UTC
Value: 0
{"kind": "exporter", "data_type": "metrics", "name": "debug"}
Metrics
Развернем prometheus для хранения метрик и сконфигурируем коллектор
для отправки метрик в него. Таким образом config.yaml
будет выглядеть так:
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
processors:
batch:
exporters:
debug:
verbosity: detailed
prometheusremotewrite:
endpoint: http://prometheus:9090/api/v1/write
service:
pipelines:
logs:
receivers: [otlp]
processors: [batch]
exporters: [debug]
metrics:
receivers: [otlp]
processors: [batch]
exporters: [prometheusremotewrite,debug]
traces:
receivers: [otlp]
processors: [batch]
exporters: [debug]
Также добавим prometheus в compose.yaml
:
services:
otel-collector:
container_name: collector
image: otel/opentelemetry-collector-contrib:0.86.0
ports:
- 4317:4317
volumes:
- ./config.yaml:/etc/otelcol-contrib/config.yaml
prometheus:
container_name: prometheus
image: prom/prometheus:v2.50.1
command:
- --config.file=/etc/prometheus/prometheus.yml
- --storage.tsdb.path=/prometheus
- --web.enable-remote-write-receiver
ports:
- 9090:9090
После чего запустим, отправим метрику и посмотрим через api prometheus:
$ docker compose up -d --force-recreate
[+] Running 2/2
✔ Container collector Started 0.6s
✔ Container prometheus Started 0.6s
$ telemetrygen metrics --otlp-insecure --telemetry-attributes 'test_key="test_value"'
2024-04-24T17:44:47.846Z INFO metrics/metrics.go:30 starting the metrics generator with configuration {"config": {"WorkerCount":1,"Rate":0,"TotalDuration":0,"ReportingInterval":1000000000,"SkipSettingGRPCLogger":false,"CustomEndpoint":"","Insecure":true,"UseHTTP":false,"HTTPPath":"/v1/metrics","Headers":{},"ResourceAttributes":{},"TelemetryAttributes":{"test_key":"test_value"},"CaFile":"","ClientAuth":{"Enabled":false,"ClientCertFile":"","ClientKeyFile":""},"NumMetrics":1,"MetricType":"Gauge"}}
2024-04-24T17:44:47.849Z INFO metrics/metrics.go:81 generation of metrics isn't being throttled
2024-04-24T17:44:47.851Z INFO metrics/metrics.go:49 starting gRPC exporter
2024-04-24T17:44:47.853Z INFO grpc@v1.63.2/clientconn.go:427 [core][Channel #1]Channel created {"system": "grpc", "grpc_log": true}
2024-04-24T17:44:47.855Z INFO grpc@v1.63.2/clientconn.go:1668 [core][Channel #1]original dial target is: "localhost:4317" {"system": "grpc", "grpc_log": true}
2024-04-24T17:44:47.857Z INFO grpc@v1.63.2/clientconn.go:1675 [core][Channel #1]parsed dial target is: resolver.Target{URL:url.URL{Scheme:"localhost", Opaque:"4317", User:(*url.Userinfo)(nil), Host:"", Path:"", RawPath:"", OmitHost:false, ForceQuery:false, RawQuery:"", Fragment:"", RawFragment:""}} {"system": "grpc", "grpc_log": true}
2024-04-24T17:44:47.859Z INFO grpc@v1.63.2/clientconn.go:1694 [core][Channel #1]fallback to scheme "dns" {"system": "grpc", "grpc_log": true}
2024-04-24T17:44:47.861Z INFO grpc@v1.63.2/clientconn.go:1702 [core][Channel #1]parsed dial target is: dns:///localhost:4317 {"system": "grpc", "grpc_log": true}
2024-04-24T17:44:47.863Z INFO grpc@v1.63.2/clientconn.go:1825 [core][Channel #1]Channel authority set to "localhost:4317" {"system": "grpc", "grpc_log": true}
2024-04-24T17:44:47.866Z INFO grpc@v1.63.2/clientconn.go:332 [core][Channel #1]Channel exiting idle mode {"system": "grpc", "grpc_log": true}
2024-04-24T17:44:47.866Z INFO grpc@v1.63.2/resolver_wrapper.go:197 [core][Channel #1]Resolver state updated: {
"Addresses": [
{
"Addr": "127.0.0.1:4317",
"ServerName": "",
"Attributes": null,
"BalancerAttributes": null,
"Metadata": null
}
],
"Endpoints": [
{
"Addresses": [
{
"Addr": "127.0.0.1:4317",
"ServerName": "",
"Attributes": null,
"BalancerAttributes": null,
"Metadata": null
}
],
"Attributes": null
}
],
"ServiceConfig": null,
"Attributes": null
} (resolver returned new addresses) {"system": "grpc", "grpc_log": true}
2024-04-24T17:44:47.871Z INFO grpc@v1.63.2/balancer_wrapper.go:103 [core][Channel #1]Channel switches to new LB policy "pick_first" {"system": "grpc", "grpc_log": true}
2024-04-24T17:44:47.871Z INFO grpc@v1.63.2/balancer_wrapper.go:170 [core][Channel #1 SubChannel #2]Subchannel created {"system": "grpc", "grpc_log": true}
2024-04-24T17:44:47.872Z INFO grpc@v1.63.2/clientconn.go:531 [core][Channel #1]Channel Connectivity change to CONNECTING {"system": "grpc", "grpc_log": true}
2024-04-24T17:44:47.872Z INFO grpc@v1.63.2/clientconn.go:1195 [core][Channel #1 SubChannel #2]Subchannel Connectivity change to CONNECTING {"system": "grpc", "grpc_log": true}
2024-04-24T17:44:47.872Z INFO grpc@v1.63.2/clientconn.go:1310 [core][Channel #1 SubChannel #2]Subchannel picks a new address "127.0.0.1:4317" to connect {"system": "grpc", "grpc_log": true}
2024-04-24T17:44:47.874Z INFO grpc@v1.63.2/clientconn.go:1195 [core][Channel #1 SubChannel #2]Subchannel Connectivity change to READY {"system": "grpc", "grpc_log": true}
2024-04-24T17:44:47.874Z INFO grpc@v1.63.2/clientconn.go:531 [core][Channel #1]Channel Connectivity change to READY {"system": "grpc", "grpc_log": true}
2024-04-24T17:44:47.875Z INFO metrics/worker.go:103 metrics generated {"worker": 0, "metrics": 1}
2024-04-24T17:44:47.875Z INFO metrics/worker.go:41 stopping the exporter {"worker": 0}
$ curl -s localhost:9090/api/v1/query?query=gen | jq
{
"status": "success",
"data": {
"resultType": "vector",
"result": [
{
"metric": {
"__name__": "gen"
},
"value": [
1713980703.106,
"0"
]
},
{
"metric": {
"__name__": "gen",
"test_key": "test_value"
},
"value": [
1713980703.106,
"0"
]
}
]
}
}
Logs
Для хранения логов развернем elasticsearch и сконфигурируем коллектор следующим образом:
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
processors:
batch:
exporters:
debug:
verbosity: detailed
prometheusremotewrite:
endpoint: http://prometheus:9090/api/v1/write
elasticsearch:
endpoints: [http://elasticsearch:9200]
logs_index: my-log-index
service:
pipelines:
logs:
receivers: [otlp]
processors: [batch]
exporters: [elasticsearch,debug]
metrics:
receivers: [otlp]
processors: [batch]
exporters: [prometheusremotewrite,debug]
traces:
receivers: [otlp]
processors: [batch]
exporters: [debug]
И добавим elastic в compose.yaml
:
services:
otel-collector:
container_name: collector
image: otel/opentelemetry-collector-contrib:0.86.0
ports:
- 4317:4317
volumes:
- ./config.yaml:/etc/otelcol-contrib/config.yaml
prometheus:
container_name: prometheus
image: prom/prometheus:v2.50.1
command:
- --config.file=/etc/prometheus/prometheus.yml
- --storage.tsdb.path=/prometheus
- --web.enable-remote-write-receiver
ports:
- 9090:9090
elasticsearch:
image: elasticsearch:8.13.0
container_name: elasticsearch
ports:
- "9200:9200"
environment:
- discovery.type=single-node
- http.host=0.0.0.0
- transport.host=0.0.0.0
- xpack.security.enabled=false
- cluster.name=elasticsearch
- bootstrap.memory_lock=true
- ES_JAVA_OPTS=-Xms256m -Xmx256m
После запустим и попробуем отправить логи через коллектор, а также посмотреть их через api elasticsearch:
$ docker compose up -d --force-recreate
[+] Running 3/3
✔ Container collector Started 3.1s
✔ Container prometheus Started 3.0s
✔ Container elasticsearch Started 3.1s
$ telemetrygen logs --otlp-insecure
2024-04-24T18:00:03.576Z INFO grpc@v1.63.2/clientconn.go:427 [core][Channel #1]Channel created {"system": "grpc", "grpc_log": true}
2024-04-24T18:00:03.576Z INFO grpc@v1.63.2/clientconn.go:1668 [core][Channel #1]original dial target is: "localhost:4317" {"system": "grpc", "grpc_log": true}
2024-04-24T18:00:03.576Z INFO grpc@v1.63.2/clientconn.go:1675 [core][Channel #1]parsed dial target is: resolver.Target{URL:url.URL{Scheme:"localhost", Opaque:"4317", User:(*url.Userinfo)(nil), Host:"", Path:"", RawPath:"", OmitHost:false, ForceQuery:false, RawQuery:"", Fragment:"", RawFragment:""}} {"system": "grpc", "grpc_log": true}
2024-04-24T18:00:03.576Z INFO grpc@v1.63.2/clientconn.go:1694 [core][Channel #1]fallback to scheme "dns" {"system": "grpc", "grpc_log": true}
2024-04-24T18:00:03.576Z INFO grpc@v1.63.2/clientconn.go:1702 [core][Channel #1]parsed dial target is: dns:///localhost:4317 {"system": "grpc", "grpc_log": true}
2024-04-24T18:00:03.576Z INFO grpc@v1.63.2/clientconn.go:1825 [core][Channel #1]Channel authority set to "localhost:4317" {"system": "grpc", "grpc_log": true}
2024-04-24T18:00:03.576Z INFO logs/logs.go:52 generation of logs isn't being throttled
2024-04-24T18:00:03.580Z INFO grpc@v1.63.2/resolver_wrapper.go:197 [core][Channel #1]Resolver state updated: {
"Addresses": [
{
"Addr": "127.0.0.1:4317",
"ServerName": "",
"Attributes": null,
"BalancerAttributes": null,
"Metadata": null
}
],
"Endpoints": [
{
"Addresses": [
{
"Addr": "127.0.0.1:4317",
"ServerName": "",
"Attributes": null,
"BalancerAttributes": null,
"Metadata": null
}
],
"Attributes": null
}
],
"ServiceConfig": null,
"Attributes": null
} (resolver returned new addresses) {"system": "grpc", "grpc_log": true}
2024-04-24T18:00:03.580Z INFO grpc@v1.63.2/balancer_wrapper.go:103 [core][Channel #1]Channel switches to new LB policy "pick_first" {"system": "grpc", "grpc_log": true}
2024-04-24T18:00:03.581Z INFO grpc@v1.63.2/balancer_wrapper.go:170 [core][Channel #1 SubChannel #2]Subchannel created {"system": "grpc", "grpc_log": true}
2024-04-24T18:00:03.581Z INFO grpc@v1.63.2/clientconn.go:531 [core][Channel #1]Channel Connectivity change to CONNECTING {"system": "grpc", "grpc_log": true}
2024-04-24T18:00:03.581Z INFO grpc@v1.63.2/clientconn.go:1195 [core][Channel #1 SubChannel #2]Subchannel Connectivity change to CONNECTING {"system": "grpc", "grpc_log": true}
2024-04-24T18:00:03.581Z INFO grpc@v1.63.2/clientconn.go:1310 [core][Channel #1 SubChannel #2]Subchannel picks a new address "127.0.0.1:4317" to connect {"system": "grpc", "grpc_log": true}
2024-04-24T18:00:03.583Z INFO grpc@v1.63.2/clientconn.go:332 [core][Channel #1]Channel exiting idle mode {"system": "grpc", "grpc_log": true}
2024-04-24T18:00:03.586Z INFO grpc@v1.63.2/clientconn.go:1195 [core][Channel #1 SubChannel #2]Subchannel Connectivity change to READY {"system": "grpc", "grpc_log": true}
2024-04-24T18:00:03.587Z INFO grpc@v1.63.2/clientconn.go:531 [core][Channel #1]Channel Connectivity change to READY {"system": "grpc", "grpc_log": true}
2024-04-24T18:00:03.595Z INFO logs/worker.go:71 logs generated {"worker": 0, "logs": 1}
$ curl -s localhost:9200/my-log-index/_search | jq
{
"took": 72,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 1,
"hits": [
{
"_index": "my-log-index",
"_id": "3mxDEY8Brl8cR2jNztu-",
"_score": 1,
"_source": {
"@timestamp": "2024-04-24T18:00:03.578798630Z",
"Attributes": {
"app": "server"
},
"Body": "the message",
"SeverityNumber": 9,
"SeverityText": "Info",
"TraceFlags": 0
}
}
]
}
}
Traces
Для хранения трейсов развернем jaeger и добавим в конфигурацию коллектора:
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
processors:
batch:
exporters:
debug:
verbosity: detailed
prometheusremotewrite:
endpoint: http://prometheus:9090/api/v1/write
elasticsearch:
endpoints: [http://elasticsearch:9200]
logs_index: my-log-index
otlp:
endpoint: jaeger:4317
tls:
insecure: true
service:
pipelines:
logs:
receivers: [otlp]
processors: [batch]
exporters: [elasticsearch,debug]
metrics:
receivers: [otlp]
processors: [batch]
exporters: [prometheusremotewrite,debug]
traces:
receivers: [otlp]
processors: [batch]
exporters: [otlp,debug]
И добавим в compose.yaml
:
services:
otel-collector:
container_name: collector
image: otel/opentelemetry-collector-contrib:0.86.0
ports:
- 4317:4317
volumes:
- ./config.yaml:/etc/otelcol-contrib/config.yaml
prometheus:
container_name: prometheus
image: prom/prometheus:v2.50.1
command:
- --config.file=/etc/prometheus/prometheus.yml
- --storage.tsdb.path=/prometheus
- --web.enable-remote-write-receiver
ports:
- 9090:9090
elasticsearch:
image: elasticsearch:8.13.0
container_name: elasticsearch
ports:
- "9200:9200"
environment:
- discovery.type=single-node
- http.host=0.0.0.0
- transport.host=0.0.0.0
- xpack.security.enabled=false
- cluster.name=elasticsearch
- bootstrap.memory_lock=true
- ES_JAVA_OPTS=-Xms256m -Xmx256m
jaeger:
container_name: jaeger
image: jaegertracing/all-in-one:1.56
ports:
- "16686:16686"
После чего запустим, отправим трейс через коллектор и посмотрим его через api jaeger:
$ docker compose up -d --force-recreate
[+] Running 4/4
✔ Container collector Started 3.0s
✔ Container elasticsearch Started 3.0s
✔ Container jaeger Started 2.9s
✔ Container prometheus Started 3.1s
$ telemetrygen traces --otlp-insecure
2024-04-24T18:08:43.789Z INFO traces/traces.go:52 starting gRPC exporter
2024-04-24T18:08:43.829Z INFO grpc@v1.63.2/clientconn.go:427 [core][Channel #1]Channel created {"system": "grpc", "grpc_log": true}
2024-04-24T18:08:43.829Z INFO grpc@v1.63.2/clientconn.go:1668 [core][Channel #1]original dial target is: "localhost:4317" {"system": "grpc", "grpc_log": true}
2024-04-24T18:08:43.829Z INFO grpc@v1.63.2/clientconn.go:1675 [core][Channel #1]parsed dial target is: resolver.Target{URL:url.URL{Scheme:"localhost", Opaque:"4317", User:(*url.Userinfo)(nil), Host:"", Path:"", RawPath:"", OmitHost:false, ForceQuery:false, RawQuery:"", Fragment:"", RawFragment:""}} {"system": "grpc", "grpc_log": true}
2024-04-24T18:08:43.829Z INFO grpc@v1.63.2/clientconn.go:1694 [core][Channel #1]fallback to scheme "dns" {"system": "grpc", "grpc_log": true}
2024-04-24T18:08:43.830Z INFO grpc@v1.63.2/clientconn.go:1702 [core][Channel #1]parsed dial target is: dns:///localhost:4317 {"system": "grpc", "grpc_log": true}
2024-04-24T18:08:43.830Z INFO grpc@v1.63.2/clientconn.go:1825 [core][Channel #1]Channel authority set to "localhost:4317" {"system": "grpc", "grpc_log": true}
2024-04-24T18:08:43.830Z INFO traces/traces.go:114 generation of traces isn't being throttled
2024-04-24T18:08:43.830Z INFO traces/worker.go:108 traces generated {"worker": 0, "traces": 1}
2024-04-24T18:08:43.831Z INFO traces/traces.go:74 stop the batch span processor
2024-04-24T18:08:43.831Z INFO grpc@v1.63.2/clientconn.go:332 [core][Channel #1]Channel exiting idle mode {"system": "grpc", "grpc_log": true}
2024-04-24T18:08:43.832Z INFO grpc@v1.63.2/resolver_wrapper.go:197 [core][Channel #1]Resolver state updated: {
"Addresses": [
{
"Addr": "127.0.0.1:4317",
"ServerName": "",
"Attributes": null,
"BalancerAttributes": null,
"Metadata": null
}
],
"Endpoints": [
{
"Addresses": [
{
"Addr": "127.0.0.1:4317",
"ServerName": "",
"Attributes": null,
"BalancerAttributes": null,
"Metadata": null
}
],
"Attributes": null
}
],
"ServiceConfig": null,
"Attributes": null
} (resolver returned new addresses) {"system": "grpc", "grpc_log": true}
2024-04-24T18:08:43.833Z INFO grpc@v1.63.2/balancer_wrapper.go:103 [core][Channel #1]Channel switches to new LB policy "pick_first" {"system": "grpc", "grpc_log": true}
2024-04-24T18:08:43.833Z INFO grpc@v1.63.2/balancer_wrapper.go:170 [core][Channel #1 SubChannel #2]Subchannel created {"system": "grpc", "grpc_log": true}
2024-04-24T18:08:43.833Z INFO grpc@v1.63.2/clientconn.go:531 [core][Channel #1]Channel Connectivity change to CONNECTING {"system": "grpc", "grpc_log": true}
2024-04-24T18:08:43.833Z INFO grpc@v1.63.2/clientconn.go:1195 [core][Channel #1 SubChannel #2]Subchannel Connectivity change to CONNECTING {"system": "grpc", "grpc_log": true}
2024-04-24T18:08:43.834Z INFO grpc@v1.63.2/clientconn.go:1310 [core][Channel #1 SubChannel #2]Subchannel picks a new address "127.0.0.1:4317" to connect {"system": "grpc", "grpc_log": true}
2024-04-24T18:08:43.836Z INFO grpc@v1.63.2/clientconn.go:1195 [core][Channel #1 SubChannel #2]Subchannel Connectivity change to READY {"system": "grpc", "grpc_log": true}
2024-04-24T18:08:43.836Z INFO grpc@v1.63.2/clientconn.go:531 [core][Channel #1]Channel Connectivity change to READY {"system": "grpc", "grpc_log": true}
2024-04-24T18:08:43.840Z INFO grpc@v1.63.2/clientconn.go:531 [core][Channel #1]Channel Connectivity change to SHUTDOWN {"system": "grpc", "grpc_log": true}
2024-04-24T18:08:43.840Z INFO grpc@v1.63.2/resolver_wrapper.go:100 [core][Channel #1]Closing the name resolver {"system": "grpc", "grpc_log": true}
2024-04-24T18:08:43.840Z INFO grpc@v1.63.2/balancer_wrapper.go:135 [core][Channel #1]ccBalancerWrapper: closing {"system": "grpc", "grpc_log": true}
2024-04-24T18:08:43.840Z INFO grpc@v1.63.2/clientconn.go:1195 [core][Channel #1 SubChannel #2]Subchannel Connectivity change to SHUTDOWN {"system": "grpc", "grpc_log": true}
2024-04-24T18:08:43.840Z INFO grpc@v1.63.2/clientconn.go:1143 [core][Channel #1 SubChannel #2]Subchannel deleted {"system": "grpc", "grpc_log": true}
2024-04-24T18:08:43.841Z INFO grpc@v1.63.2/clientconn.go:1145 [core][Channel #1]Channel deleted {"system": "grpc", "grpc_log": true}
2024-04-24T18:08:43.841Z INFO traces/traces.go:64 stopping the exporter
$ curl -s localhost:16686/api/traces?service=telemetrygen | jq '.data[].spans[]| "\(.traceID) \(.spanID) \(.operationName)"'
"7bcdc72d64b16a8c83dd668f74cd65f2 d063605ba96839d2 okey-dokey-0"
"7bcdc72d64b16a8c83dd668f74cd65f2 aba8028c6e80fbbf lets-go"
Visualization
Для удобного отображения данных развернем также grafana, добавив compose.yaml
:
services:
otel-collector:
container_name: collector
image: otel/opentelemetry-collector-contrib:0.86.0
ports:
- 4317:4317
volumes:
- ./config.yaml:/etc/otelcol-contrib/config.yaml
prometheus:
container_name: prometheus
image: prom/prometheus:v2.50.1
command:
- --config.file=/etc/prometheus/prometheus.yml
- --storage.tsdb.path=/prometheus
- --web.enable-remote-write-receiver
ports:
- 9090:9090
elasticsearch:
image: elasticsearch:8.13.0
container_name: elasticsearch
ports:
- "9200:9200"
environment:
- discovery.type=single-node
- http.host=0.0.0.0
- transport.host=0.0.0.0
- xpack.security.enabled=false
- cluster.name=elasticsearch
- bootstrap.memory_lock=true
- ES_JAVA_OPTS=-Xms256m -Xmx256m
jaeger:
container_name: jaeger
image: jaegertracing/all-in-one:1.56
ports:
- "16686:16686"
grafana:
container_name: grafana
image: grafana/grafana:10.4.0
ports:
- 8888:3000
Перезапустим контейнеры и запустим одновременную отправку метрик, трейсов и логов:
$ docker compose up -d --force-recreate
[+] Running 5/5
✔ Container collector Started 1.4s
✔ Container elasticsearch Started 1.4s
✔ Container prometheus Started 1.3s
✔ Container grafana Started 1.5s
✔ Container jaeger Started 1.5s
$ telemetrygen traces --otlp-insecure --duration=1h --rate=10 & \
telemetrygen metrics --otlp-insecure --duration=1h --rate=1 & \
telemetrygen logs --otlp-insecure --duration=1h --rate=5 &
После чего откроем графану по адресу localhost:8888,
авторизуемся под учетными данными admin:admin
и перейдем к добавлению наших
датасорсов /connections/datasources.
Prometheus
Добавим наши метрики используя тип датасорса prometheus
:
Elasticsearch
Логи добавим с помощью датасорса elasticsearch
:
Jaeger
И наконец трейсы через датасорс jaeger
:
Dashboard
После чего можем отобразить их на дашборде, перейдя на страницу /dashboards и создав новый дашборд и визуализацию в нем:
Также добавим наши логи используя датасорс elasticsearch
и визуализацию logs
:
И наконец добавим наши трейсы в виде двух визуализаций из датасорса jaeger
,
таблицы трейсов:
И информации по конкретному трейсу:
Для связи двух визуализаций создадим переменную в дашборде:
И добавим ссылку в визуализацию с таблицей трейсов traces
с помощью field override:
После чего выбирая Trace ID
в таблице traces
в таблице trace detail
будет
отображаться информация по нему:
Таким образом можно отобразить различные виды телеметрии на одном дашборде.