VictoriaTraces: Recording Rules, метрики та алерти з trace spans
0 (0)

Автор |  22/05/2026
Click to rate this post!
[Total: 0 Average: 0]

VictoriaTraces – як і VictoriaLogs – підтримує Recording Rules (див. VictoriaMetrics: Recording Rules для логів AWS Load Balancer) для трейсів, бо по факту трейси – це ті ж самі логи, просто інакше структуровані.

А раз є Recording Rules – то ми можемо з логів створювати метрики для алертів та Grafana dashboards.

Хоча насправді це не найкращий варіант, тим більш для якогось high load проекту, бо vmalert з Recording Rule постійно робить запити до VictoriaTraces – і тут краще підійшов би якийсь otelcol.connector.spanmetrics, який можна було б додати в pipeline.traces – але якщо OTel стеку нема або, як в моєму випадку, проект невеликий – то цілком робочий варіант робити метрики з Recording Rules.

Це вже третя частина по OpenTelemetry та VictoriaTraces, попередні тут:

Метрики з трейсів: а для чого?

Пара прикладів з моїх власних “хотєлок” на проекті – чому я почав робити таке рішення.

AWS ALB response time

У нас є метрика AWS ALB response time: тригерить алерт, коли якийсь ендпоінт починає довго відповідати. Метрика генериться з логів ALB, рахуючи поля з log record:

- record: vmlogs:alb:logs:alb_response_time:p95
  expr: |
    {namespace="ops-monitoring-ns"} app:="alb-logs-exporter" -"DEBUG" -"SQS" -"VMLOGS" -"PARSER"
    | filter not `{"date"`*
    | extract "<_> <_> <elb_id> <_> <_> <request_processing_time> <target_processing_time> <response_processing_time> <elb_status_code> <target_status_code> <received_bytes> <sent_bytes> <request_line> <user_agent> <_> <_> <_> <trace_id> <domain_name> <_> <_> <_> <_> <_> <error_reason> <_> <_> <_> <_> <conn_trace_id> <_> <_> <_>"
    | extract_regexp `.*:443(?P<uri_path>/[^/?]*).* HTTP` from request_line
    | filter target_processing_time :! "-1" and request_processing_time :! "-1" and response_processing_time :! "-1"
    | filter request_processing_time :! "" and target_processing_time :! "" and response_processing_time :! ""
    | math request_processing_time + target_processing_time + response_processing_time as total_response_time
    | rename domain_name as domain
    | stats by (domain, uri_path) quantile(0.95, total_response_time) as alb_response_time

І з нею відразу кілька проблем.

Перша: знов-таки – навантаження на бекенд, VictoriaLogs: якщо логів багато – то vmalert робить запит кожну хвилину (interval: 1m), до того ж в запиті є regex – який сам по собі доволі важкий в плані CPU/RAM.

Друга: лейбла uri_path в значенні має тільки першу частину URI. Тобто, якщо запит прийшов на /user/<name>/orders – то в метрику vmlogs:alb:logs:alb_response_time:p95 буде збережено тільки uri_path="/user".

Так зроблено через cardinality issue – аби не створювати багато різних значень, бо це вплине на сторейдж і ресурси (див. VictoriaMetrics: Churn Rate, High cardinality, метрики та IndexDB).

Відповідно, коли приходить алерт, ми бачимо тільки дуже загальну інформацію – по самому ендпоінту, а не конкретного юзера.

Ну і головне, чому я поліз копати в цю тему – це те, що алерти ніяк не прив’язані до трейсів.

Зараз, якщо приходить алерт типу:

VictoriaTraces: Recording Rules, метрики та алерти з trace spans

Все, що ми можемо зробити – це піти в Grafana dashboard для Kubernetes Pods і WorkerNodes, і там дивитись навантаження CPU/RAM. Якщо там все ок – то йти в дашборду по RDS, і розбиратись там.

А маючи метрики з трейсів – я можу прямо в алерті створити лінк на всі пов’язані трейси, і тоді відразу в Grafana та VictoriaTraces побачити де проблема.

AWS RDS query duration

Інший приклад – метрика з логів AWS RDS:

- record: vmlogs:aws:rds:cloudwatch_logs:explain:query_duration:sum:avg:5m
  expr: |
    logtype:="rds" "plan:"
      | extract_regexp `.*:(?P<connection>.*_kraken_user@.*kraken_db:\[\d+\])`
      | extract_regexp ".*duration: (?P<duration>.+) ms"
      | duration:~".+"
      | extract_regexp `.*Query Text: (?P<query>.+?)(?:\s+AS\s|\s+FROM\s)`
      | query:~".+"
      | stats by (environment, connection, query) avg(duration) avg_duration

Тут аналогічний підхід: AWS RDS пише в лог AUTO EXPLAIN (див. PostgreSQL: використання EXPLAIN та налаштування “auto_explain” в AWS RDS), а ми парсимо логи в VictoriaLogs та генеруємо метрику.

Загалом дані в лейблах більш цікаві, ніж в прикладі з AWS ALB, бо є і частина SQL-запиту, і “connection ID” у вигляді “<db_user>@<db_host>:<PID>” – але знову-таки дебажити такі алерти складніше, бо треба брати цей connection ID, шукати його в логах RDS, потім ці логи якось пов’язувати з логами самого Backend API.

Натомість – можна мати аналогічну метрику з трейсів і генерити пряму лінку на Grafana/VictoriaTraces.

Отже, що будемо сьогодні робити – подивимось на метадані, які використовуються в OTLP для spans, опишемо кілька метрик з трейсів та напишемо кілька алертів.

Метрики HTTP

Наш Backend API “обмазаний” OTel auto-instrumentation (сподіваюсь, таки допишу пост по OTel та Python).

Трейси генеряться з усіх FastAPI та AWS викликів – і, використовуючи їх, можемо собі написати метрик та алертів.

В трейсах бекенду від FastAPI маємо поля (атрибути) http.route, http.status_code, duration – тому ми можемо створити зручні метрики з яких потім можемо створити зручні алерти.

Корисні span та resource attributes

Спершу на прикладі HTTP span від FastAPI подивимось в VictoriaTraces – що цікавого у нас є в span та resource attributes.

[
  {
    ...
    "duration": "4464509750",
    ...
    "kind": "2",
    "name": "GET /morpheus/sleep-agent/status",
    ...
    "resource_attr:k8s.namespace.name": "prod-backend-api-ns",
    "resource_attr:k8s.node.name": "ip-10-0-42-22.ec2.internal",
    "resource_attr:k8s.pod.name": "backend-api-deployment-6966566f55-khb9v",
    "resource_attr:service.name": "kraken-prod",
    ...
    "span_attr:http.method": "GET",
    "span_attr:http.route": "/morpheus/sleep-agent/status",
    "span_attr:http.scheme": "http",
    "span_attr:http.status_code": "503",
    "span_attr:http.target": "/morpheus/sleep-agent/status",
    ...
    ...
    "status_code": "2",
    "status_message": "http 503",
    "trace_id": "6a0c64013a090e5462414f3e3fba1630"
  },

Що з цього нам може бути цікаве і корисне:

  • duration: час виконання запиту (в наносекундах) – корисно для метрик HTTP latency та PostgreSQL  query duration
  • kind: визначає роль span – чи це наш сервіс оброблює запит від клієнта (тип 2 – SERVER), чи сервіс робить запит до зовнішнього ресурсу (тип 3 – CLIENT), див. Span Kind та самі значення в коді trace.proto
    • в прикладах нижче буде AWS буде span.kind=3, тобто “CLIENT” – наш сервіс є клієнтом, бо виконує вихідний виклик до AWS API
  • name: ім’я span, згенероване SDK – корисне, бо включає в себе відразу кілька інших атрибутів – простіше використовувати в фільтрах для Grafana (про це далі, коли будемо робити алерт)
  • k8s.namespace.name, node.name, pod.name: resource-level атрибути, які задаються або OTel Collector, або, як в моєму випадку, з Downward API в Kubernetes Deployment для Backend API (костиль, поки нема OTel Collector)
    • дуже корисні атрибути, бо дозволять будувати зв’язки між Pod-level metrics, Node-level, etc – дають загальний контекст для observability
  • span_attr:http.method та http.route: корисно відобразити і в алерті, і мати фільтр в Grafana для VictoriaMetrics
  • span_attr:http.target: якщо http.route вище – це саме роут у FastAPI (з плейсхолдером типу /chats/{chat_id}) – то в http.target вже маємо конкретний URI, який був викликаний
    • в цьому прикладі не дуже очевидна різниця, бо роут статичний, але в інших спанах вони виглядають як route="/chats/{chat_id}" – а в target="/chats/john-789?limit=10"
  • span_attr:http.status_code: не путати з status_code нижче – тут маємо саме HTTP-код відповіді від сервера клієнту
  • status_code: дуже корисний атрибут – OTel Span Status code (не HTTP status вище), який вказує на результат виконання операції – Success (1) або Error (2), див. Set Status
    • в цьому прикладі як раз добре видно, що HTTP-запит завершився з 503 – Service Unavailable, і, відповідно, статус цього span == Error
  • status_message: description до status_code – FastAPI/OTel, коли задавав значення status_code=2 додав текстовий опис помилки
  • trace_id: ну і ID самого трейсу, до якого відноситься конкретно цей span

Тепер, маючи список атрибутів – можемо подумати над метрикою.

Метрика “vmtraces:backend:http:request_5xx:rate”

Створюємо новий VMRule з type: vlogs:

apiVersion: operator.victoriametrics.com/v1beta1
kind: VMRule
metadata:
  name: recording-rules-vmalert-traces
  labels:
    app: vmalert-traces
spec:
  groups:
    - name: Traces.VictoriaTraces.Logs.rules
      type: vlogs
      interval: 5m

      rules:

        - record: vmtraces:kraken:http:request_5xx:rate
          expr: |
            {resource_attr:service.name=~"kraken-.*"} "span_attr:http.route":!"" "span_attr:http.status_code":~"5.."
            | stats by ("resource_attr:k8s.namespace.name", "resource_attr:service.name", "span_attr:http.route", "span_attr:http.status_code") rate() requests_per_sec

Тут вибираємо всі трейси від service.name=~"kraken-.*" (Kraken – ім’я нашого бекенду), вибираємо тільки ті, які відносяться до HTTP – "span_attr:http.route":!"", вибираємо тільки з помилками 5хх.

Далі рахуємо per second rate, агрегуючи по Kubernetes Namespace, OTel Service Name, HTTP route (URI) та коду помилки.

Трохи забігаючи наперед: прикольно було б в алерті відразу створювати лінк на конкретний trace по його ID – але писати тут в метрику лейблу trace_id не варто, бо це мільйон різних значень – заб’ємо базу VictoriaMetrics.

Деплоїмо, перевіряємо, що метрика в VictoriaMetrics є:

VictoriaTraces: Recording Rules, метрики та алерти з trace spans

Алерт “Backend HTTP 5xx Errors”

Аби не писати окремі алерти на Dev/Staging/Prod – використаємо Helm range.

Додаємо в values.yaml чарту:

alerts:
  traces:
    backend:
      - env: dev
        namespace: dev-backend-api-ns
        severities: [warning]
      - env: staging
        namespace: staging-backend-api-ns
        severities: [warning]
      - env: prod
        namespace: prod-backend-api-ns
        severities: [warning, critical]

Описуємо новий VMRule (я для зручності тримаю окремо Recording Rules та алерти) – вже з самим алертом:

apiVersion: operator.victoriametrics.com/v1beta1
kind: VMRule
metadata:
    name: alerts-kraken-traces-http
spec:

  groups:

    ##########################
    ### Kraken Traces HTTP ###
    ##########################

    - name:  Kraken.Traces.HTTP.rules

      rules:

      ##############################
      ### Kraken HTTP 5xx Errors ###
      ##############################

      {{- range .Values.alerts.traces.backend }}
      {{- $ns := . }}
      {{- range .severities }}
      {{- if not (eq . "critical") }}
      - alert: Kraken HTTP 5xx Errors
        expr: vmtraces:kraken:http:request_5xx:rate{"resource_attr:k8s.namespace.name"="{{ $ns.namespace }}",stats_result="requests_per_sec"} > 0
        for: 1s
        labels:
          severity: {{ . }}
          component: backend
          environment: {{ $ns.env }}
          ilert_routingkey: backend-{{ $ns.env }}-{{ . }}
        annotations:
          summary: "Kraken service is returning HTTP 5xx errors"
          description: |-
            HTTP 5xx error rate has been above 0 for more than `{{ "{{" }} $for }}`
            *Namespace*: `{{ "{{" }} index $labels "resource_attr:k8s.namespace.name" }}`
            *HTTP route*: `{{ "{{" }} index $labels "span_attr:http.route" }}`
            *HTTP status*: `{{ "{{" }} index $labels "span_attr:http.status_code" }}`
            *5xx rate*: `{{ "{{" }} printf "%.3f" $value }}` req/s
            <https://{{ $.Values.monitoring.root_url }}/explore?orgId=1&left=%7B%22datasource%22:%22{{ $.Values.monitoring.victoria_traces_uid }}%22,%22queries%22:%5B%7B%22refId%22:%22A%22,%22datasource%22:%7B%22type%22:%22jaeger%22,%22uid%22:%22{{ $.Values.monitoring.victoria_traces_uid }}%22%7D,%22queryType%22:%22search%22,%22service%22:%22{{ "{{" }} index $labels "resource_attr:service.name" }}%22,%22tags%22:%22http.route%3D{{ "{{" }} index $labels "span_attr:http.route" }}%22,%22limit%22:100%7D%5D,%22range%22:%7B%22from%22:%22now-1h%22,%22to%22:%22now%22%7D%7D|:grafana: VictoriaTraces>
      {{- end }}
      {{- end }}
      {{- end }}

Тут з {{- range .Values.alerts.traces.backend }} проходимось в циклі по всім значенням з values і для кожного оточення створюємо окремий алерт.

З {{- if not (eq . "critical") }} не створюю алерти CRITICAL, бо він приходить з @channel в Slack – поки це в тесті, подивитись, як буде працювати.

OTel names формат та Helm templating

Тут є цікавий момент, пов’язаний з OTel форматом імен метрик і лейбл.

Якщо в Prometheus format вони задаються через “_” – тобто у вигляді “resource_attr_k8s_namespace_name“, то OTel використовує крапки і двокрапки – і це ломає шаблонізатор Helm/Go.

Є варіант використовувати Label sanitization – писати метрики до VictoriaMetrics відразу в Prometheus-форматі, але це (поки що) не можна робити для трейсів і логів, і тоді в різних бекендах будемо мати різні імена лейбл.

Тому я поки що вирішив не включати usePromCompatibleNaming і писати дані як є, а коли вже цю опцію додадуть до VictoriaLogs та VictoriaTraces – можна буде оновити алерти.

Btw, можете лайкнути issue на GitHub – OpenTelemetry: support field names transformations 😉

Тому тут робимо з index $labels, а імена лейбл вказуємо в лапках:

index $labels "resource_attr:k8s.namespace.name"

Значення в $labels – це тип map(map[string]string), тому index проходиться по вкладеним ключам і отримує потрібну лейблу.

Grafana link до VictoriaTraces

Останнім в алерті створюється прямий лінк на Grafana – щоб ми з алерту могли відразу відкрити всі деталі.

Як писав вище – простіше тут було робити пошук по trace_id – але його ми не можемо писати в лейбли, бо знов-таки – cardinality issue.

Тому я зробив через фільтр по тегам, які підставляються з отриманих атрибутів в $labels – в данному випадку по span_attr:http.route:

VictoriaTraces: Recording Rules, метрики та алерти з trace spans

А сам алерт в Slack виглядає так:

VictoriaTraces: Recording Rules, метрики та алерти з trace spans

Метрика “vmtraces:backend:http:request_duration:p95”

Тут, в принципі, все аналогічно – тільки рахується не rate() – а 95 перцентиль по полю duration.

Чому 95 перцентиль, а не якийсь avg(): бо average дасть загальну “розмазану картину” по всім запитам – але може пропустити проблеми у невеликої кількості юзерів.

Recording Rule вийшов таким:

- record: vmtraces:kraken:http:request_duration:p95
  expr: |
    {resource_attr:service.name=~"kraken-.*"} "span_attr:http.route":!"" kind:=2
    | stats by ("resource_attr:k8s.namespace.name", "resource_attr:service.name", "span_attr:http.route") quantile(0.95, duration) value

Тут в фільтрах додаємо kind=2, аби рахувати дані тільки від спанів з типом SERVER – бо нам цікавий результат від самого FastAPI на Backend API.

Інакше в результати міг б попасти спан із дочірніх спанів з цього трейсу – запити від Backend API до, наприклад, DynamoDB або RDS (хоча фільтр з "span_attr:http.route":!"" має вибрати тільки HTTP).

Деплоїмо, перевіряємо метрику:

VictoriaTraces: Recording Rules, метрики та алерти з trace spans

Алерт “Backend HTTP p95 latency is high”

Тут все аналогічно до алерту по помилкам 5хх.

Тільки в expression виконуємо конвертацію наносекунд в секунди – ділимо результат на 1e9 (мільярд) і тригеримо алерт, p95 latency вище 5 секунд:

{{- range .Values.alerts.traces.backend }}
{{- $ns := . }}
{{- range .severities }}
{{- if not (eq . "critical") }}
- alert: Kraken HTTP Latency p95 High
  expr: vmtraces:kraken:http:request_duration:p95{"resource_attr:k8s.namespace.name"="{{ $ns.namespace }}",stats_result="value"} / 1e9 > 5
  for: 5m
  labels:
    severity: {{ . }}
    component: backend
    environment: {{ $ns.env }}
    ilert_routingkey: backend-{{ $ns.env }}-{{ . }}
  annotations:
    summary: "Kraken HTTP p95 latency is high"
    description: |-
      HTTP p95 latency has been above 5s for more than `{{ "{{" }} $for }}`
      *Namespace*: `{{ "{{" }} index $labels "resource_attr:k8s.namespace.name" }}`
      *Service name*: `{{ "{{" }} index $labels "resource_attr:service.name" }}`
      *HTTP route*: `{{ "{{" }} index $labels "span_attr:http.route" }}`
      *P95 latency*: `{{ "{{" }} printf "%.2f" $value }}` seconds
      <https://{{ $.Values.monitoring.root_url }}/explore?orgId=1&left=%7B%22datasource%22:%22{{ $.Values.monitoring.victoria_traces_uid }}%22,%22queries%22:%5B%7B%22refId%22:%22A%22,%22datasource%22:%7B%22type%22:%22jaeger%22,%22uid%22:%22{{ $.Values.monitoring.victoria_traces_uid }}%22%7D,%22queryType%22:%22search%22,%22service%22:%22{{ "{{" }} index $labels "resource_attr:service.name" }}%22,%22tags%22:%22http.route%3D{{ "{{" }} index $labels "span_attr:http.route" }}%22,%22limit%22:100%7D%5D,%22range%22:%7B%22from%22:%22now-1h%22,%22to%22:%22now%22%7D%7D|:grafana: VictoriaTraces>
{{- end }}
{{- end }}
{{- end }}

З HTTP поки все – йдемо далі.

Метрики AWS API

Для вибору спанів, пов’язаних з AWS можемо використати фільтр по атрибуту "span_attr:rpc.system".

Перевіряємо що у нас є цікавого:

{resource_attr:service.name=~"kraken-.*"} "span_attr:rpc.system":"aws-api"

VictoriaTraces: Recording Rules, метрики та алерти з trace spans

Тут вже як раз бачимо kind=3 – наш бекенд виступає в ролі CLIENT до AWS API.

Метрика “vmtraces:backend:aws:client_error:rate”

З цікавих метрик, які тут можемо зробити – алертити, коли виникають помилки при запитах до AWS.

Описуємо новий Recording Rule:

- record: vmtraces:kraken:aws:client_error:rate
  expr: |
    {resource_attr:service.name=~"kraken-.*"} "span_attr:rpc.system":"aws-api" status_code:=2
    | stats by ("resource_attr:k8s.namespace.name", "resource_attr:service.name", "span_attr:rpc.service", name) rate() requests_per_sec

Тут фільтр status_code:=2 вибираємо тільки помилки:

VictoriaTraces: Recording Rules, метрики та алерти з trace spans

В атрибутах спану маємо і сам stacktrace, і status_message – але їх в лейбли не пишемо, це вже можна буде глянути в Grafana.

Деплоїмо, перевіряємо метрику:

VictoriaTraces: Recording Rules, метрики та алерти з trace spans

Алерт “Backend is getting errors from AWS services”

Описуємо алерт – тут все аналогічно, тільки в Grafana link робимо фільтр по name, і його ж виводимо в тексті алерта в полі Operation – бо там є і AWS service name, і тип операції:

{{- range .Values.alerts.traces.backend }}
{{- $ns := . }}
{{- range .severities }}
{{- if not (eq . "critical") }}
- alert: Kraken AWS Client Errors
  expr: vmtraces:kraken:aws:client_error:rate{"resource_attr:k8s.namespace.name"="{{ $ns.namespace }}",stats_result="requests_per_sec"} > 0
  for: 1s
  labels:
    severity: {{ . }}
    component: backend
    environment: {{ $ns.env }}
    ilert_routingkey: backend-{{ $ns.env }}-{{ . }}
  annotations:
    summary: "Kraken is getting errors from AWS services"
    description: |-
      AWS client error rate has been above 0 for more than `{{ "{{" }} $for }}`
      *Namespace*: `{{ "{{" }} index $labels "resource_attr:k8s.namespace.name" }}`
      *Service name*: `{{ "{{" }} index $labels "resource_attr:service.name" }}`
      *Operation*: `{{ "{{" }} index $labels "name" }}`
      *Error rate*: `{{ "{{" }} printf "%.3f" $value }}` req/s
      <https://{{ $.Values.monitoring.root_url }}/explore?orgId=1&left=%7B%22datasource%22:%22{{ $.Values.monitoring.victoria_traces_uid }}%22,%22queries%22:%5B%7B%22refId%22:%22A%22,%22datasource%22:%7B%22type%22:%22jaeger%22,%22uid%22:%22{{ $.Values.monitoring.victoria_traces_uid }}%22%7D,%22queryType%22:%22search%22,%22service%22:%22{{ "{{" }} index $labels "resource_attr:service.name" }}%22,%22operation%22:%22{{ "{{" }} index $labels "name" }}%22,%22tags%22:%22rpc.service%3D{{ "{{" }} index $labels "span_attr:rpc.service" }}%22,%22limit%22:100%7D%5D,%22range%22:%7B%22from%22:%22now-1h%22,%22to%22:%22now%22%7D%7D|:grafana: VictoriaTraces>
{{- end }}
{{- end }}
{{- end }}

Деплоїмо, чекаємо на алерт в Slack:

VictoriaTraces: Recording Rules, метрики та алерти з trace spans

І маємо лінк на Grafana з фільтром по Operation name:

VictoriaTraces: Recording Rules, метрики та алерти з trace spans

Метрики RDS

І останній приклад – із запитами до RDS.

Метрика “vmtraces:backend:db:query_duration:p95”

Описуємо Recording Rule, фільтруємо по "scope_name":="opentelemetry.instrumentation.sqlalchemy":

# DB query p95 latency
- record: vmtraces:kraken:db:query_duration:p95
  expr: |
    {resource_attr:service.name=~"kraken-.*"} "scope_name":="opentelemetry.instrumentation.sqlalchemy"
    | stats by ("resource_attr:k8s.namespace.name", "resource_attr:service.name", "span_attr:db.name", name) quantile(0.95, duration) p95_duration

Як і для HTTP – рахуємо 95 персентиль.

Алерт “Kraken DB Query p95 Duration High”

Аналогічно до HTTP алерта – конвертуємо value в секунди:

{{- range .Values.alerts.traces.backend }}
{{- $ns := . }}
{{- range .severities }}
{{- if not (eq . "critical") }}
- alert: "Kraken DB Query p95 Duration High"
  expr: vmtraces:kraken:db:query_duration:p95{"resource_attr:k8s.namespace.name"="{{ $ns.namespace }}",stats_result="p95_duration"} / 1e9 > 1
  for: 1m
  labels:
    severity: {{ . }}
    component: backend
    environment: {{ $ns.env }}
    ilert_routingkey: backend-{{ $ns.env }}-{{ . }}
  annotations:
    summary: "Kraken DB query p95 duration is high"
    description: |-
      DB query p95 duration has been above 1s for more than `{{ "{{" }} $for }}`
      *Namespace*: `{{ "{{" }} index $labels "resource_attr:k8s.namespace.name" }}`
      *Service name*: `{{ "{{" }} index $labels "resource_attr:service.name" }}`
      *DB name*: `{{ "{{" }} index $labels "span_attr:db.name" }}`
      *Query*: `{{ "{{" }} index $labels "name" }}`
      *P95 duration*: `{{ "{{" }} printf "%.2f" $value }}` seconds
      <https://{{ $.Values.monitoring.root_url }}/explore?schemaVersion=1&panes=%7B%22dlh%22:%7B%22datasource%22:%22dfl962zwff6yoa%22,%22queries%22:%5B%7B%22refId%22:%22A%22,%22datasource%22:%7B%22type%22:%22jaeger%22,%22uid%22:%22dfl962zwff6yoa%22%7D,%22queryType%22:%22search%22,%22service%22:%22{{ "{{" }} index $labels "resource_attr:service.name" }}%22,%22limit%22:100,%22tags%22:%22%22,%22operation%22:%22{{ "{{" }} index $labels "name" }}%22%7D%5D,%22range%22:%7B%22from%22:%22now-1h%22,%22to%22:%22now%22%7D,%22compact%22:false%7D%7D&orgId=1|:grafana: VictoriaTraces>
{{- end }}
{{- end }}
{{- end }}

В Query теж робимо аналогічно до алерта AWS – виводимо значення лейбли name, бо там є частина запиту.

В результаті в Slack отримуємо такий алерт:

VictoriaTraces: Recording Rules, метрики та алерти з trace spans

І лінк в Grafana з фільтром по Operation name – “INSERT staging_kraken_db“:

VictoriaTraces: Recording Rules, метрики та алерти з trace spans

Власне, на цьому все.

Вийшло набагато краще, ніж старі алерти з логів.

А коли ще додамо OTel Collectors – буде ще краще.

Loading