Сбор данных мониторинга из Frontend JS приложений используя Grafana Faro

—

от автора

Введение

Здравствуйте. В данной статье будет выполнено рассмотрение и установка инструмента Grafana Faro для осуществления сбора данных мониторинга из Frontend приложений написанных на JavaScript. Также, перед непосредственным использованием Grafana Faro, выполним установку в кластере Kubernetes всех остальных необходимых компонентов Grafana стека.

Инструмент Grafana Faro представляет собой набор пакетов, подключение которых осуществляется в Frontend JavaScript приложениях. Подключаемые пакеты позволяют выполнить сбор различных данных мониторинга, существуют следующие пакеты:

  • grafana/faro-web-sdk или grafana/faro-react (при использовании React) — данные пакеты осуществляют сбор таких данных, как:

    • Метрики Core Web Vitals — скорость загрузки основного контента (LCP), время ожидания до первого взаимодействия с контентом (FID), совокупное смещение макета (CLS), время до первого байта (TTFB), первая отрисовка содержимого (FCP);

    • Необработанные исключения;

    • Сообщения выведенные в консоль;

    • События изменения view;

    • События начала и продолжения сессий;

  • grafana/faro-web-tracing — пакет осуществляет интеграцию в приложение сбора трейсов на основе OpenTelemetry.

Далее данные мониторинга полученные с помощью пакетов Grafana Faro отправляются в Grafana Alloy, который выполняет обработку полученных метрик и после этого метрики полученные из пакетов:

  • grafana/faro-web-sdk или grafana/faro-react (при использовании React) — отправляются в систему логирования Grafana Loki;

  • grafana/faro-web-tracing — отправляются в систему трассировки Grafana Tempo. 

Отображение и визуализация полученных метрик осуществляется с использованием Grafana. 

Общую структурную схему работы рассматриваемого решения для сбора данных мониторинга из Frontend JavaScript приложений можно увидеть на рисунке ниже:

Установка компонентов Grafana стека в Kubernetes

Для осуществления сбора данных мониторинга выполним создание тестовый среды с установкой инфраструктурных компонентов Grafana стека в кластера Kubernetes используя Helm. 

Создадим отдельный неймспейс в который будем выполнять установку компонентов с использованием команды:

$ kubectl create namespace monitoring

Далее выполним подключение Helm репозитория Grafana с помощью команды:

$ helm repo add grafana https://grafana.github.io/helm-charts

Установка Grafana Loki

Выполним создание файла values-loki.yaml содержащий значения Helm для выполнения установка Grafana Loki, в данном примере значения подготовлены для установки в монолитном режиме с отключенной авторизацией и использованием S3 хранилища MinIO:

loki:   auth_enabled: false   commonConfig:     replication_factor: 1   schemaConfig:     configs:       - from: 2024-04-01         store: tsdb         object_store: s3         schema: v13         index:           prefix: loki_index_           period: 24h   ingester:     chunk_encoding: snappy   tracing:     enabled: true   querier:     max_concurrent: 2 gateway:   enabled: false deploymentMode: SingleBinary singleBinary:   replicas: 1 chunksCache:   writebackSizeLimit: 10MB minio:   enabled: true backend:   replicas: 0 read:   replicas: 0 write:   replicas: 0 ingester:   replicas: 0 querier:   replicas: 0 queryFrontend:   replicas: 0 queryScheduler:   replicas: 0 distributor:   replicas: 0 compactor:   replicas: 0 indexGateway:   replicas: 0 bloomCompactor:   replicas: 0 bloomGateway:   replicas: 0

Далее выполним установку Grafana Loki используя команду:

$ helm install loki grafana/loki --namespace=monitoring --values values-loki.yaml

Установка Grafana Tempo

Подготовим файл values-tempo.yaml c добавлением значений Helm для установки Grafana Tempo, в данном примере будут использоваться все стандартные значения с единственным изменением — включением постоянного хранилища:

persistence:    enabled: true

Выполним установку Grafana Tempo:

$ helm install tempo grafana/tempo --namespace=monitoring --values values-tempo.yaml

Установка Grafana Alloy 

Далее выполним создание Helm Values файла values-alloy.yaml для установки Grafana Alloy, в данном примере выполнена настройка конфигурационного файла Alloy в котором подключен приёмник Faro с отправкой в Loki и отправку через OpenTelemetry Collector в Tempo. Дополнительно в настройках приёмника Faro выполняется конфигурирование:

  • используемого порта;

  • настройки CORS;

  • ключа API через который будет выполнять отправку метрик Faro;

  • максимальный разрешённый размер полезной нагрузки;

  • указание rate лимита.

Также в values файле выполнено добавление extraPort для Faro, так-как по умолчанию в helm значениях создаётся только порт для web-интерфейса Grafana Alloy. Дополнительно выполнено включение ingress c указанием порта Faro, в дальнейшем указанный адрес в ingress будет использоваться при подключении Grafana Faro в Frontend JS приложениях, важно чтобы указанный адрес был доступ для подключения со стороны клиентов использующих приложение, иначе отправка метрик будет невозможна:

alloy:   configMap:     create: true     content: |-         faro.receiver "frontend_applications" {             server {                 listen_address           = "0.0.0.0"                 listen_port              = 8030                 cors_allowed_origins     = ["http://example-frontend-app.local.ru"]                 api_key                  = "api-key-app"                 max_allowed_payload_size = "5MiB"                  rate_limiting {                     rate = 100                 }             }              sourcemaps { }              output {                 logs   = [loki.process.logs_process.receiver]                 traces = [otelcol.exporter.otlp.trace_write.input]             }         }          loki.process "logs_process" {             forward_to = [loki.write.logs_write.receiver]              stage.logfmt {                 mapping = { "kind" = "", "service_name" = "", "app_name" = ""}             }              stage.labels {                 values = { "kind" = "kind", "service_name" = "service_name", "app" = "app_name" }             }         }          loki.write "logs_write" {             endpoint {                 url = "http://loki.monitoring.svc.cluster.local:3100/loki/api/v1/push"             }         }          logging {             level = "info"         }          otelcol.receiver.otlp "default" {             grpc {                 include_metadata = true             }              output {                 metrics = []                 logs    = []                 traces  = [otelcol.exporter.otlp.trace_write.input]             }         }          otelcol.exporter.otlp "trace_write" {             retry_on_failure {                 max_elapsed_time = "1m0s"             }              client {                 endpoint = "tempo.monitoring.svc.cluster.local:4317"                 tls {                   insecure = true                 }                             }         }   extraPorts:   - name: "faro"     port: 8030     targetPort: 8030     protocol: "TCP" ingress:   enabled: true   path: /   faroPort: 8030   pathType: Prefix   hosts:     - alloy.local 

Выполним установку Grafana Alloy с помощью команды:

$ helm install alloy grafana/alloy --namespace=monitoring --values values-alloy.yaml

Проверим корректность установки Grafana Alloy с помощью web-интерфейса, для этого выполним перенаправление порта с помощью команды:

$ kubectl port-forward svc/alloy 8080:12345 -n monitoring

Далее в браузере перейдём по адресу http://localhost:8080/ и увидим успешное подключение всех компонентов:

Установка Grafana

Выполним подготовку значений Helm в файле values-grafana.yaml для установки Grafana, в созданном values файле добавлены значения источников данных Loki и Tempo, а также выполнено создание постоянного хранилища и ingress:

persistence:   enabled: true ingress:   enabled: true   hosts:   - grafana.local datasources:  datasources.yaml:    apiVersion: 1    datasources:    - name: loki      type: loki      url: http://loki.monitoring.svc.cluster.local:3100      access: proxy      isDefault: true    - name: tempo      type: tempo      url: http://tempo.monitoring.svc.cluster.local:3100      access: proxy

Выполним установку Grafana:

$ helm install grafana grafana/grafana --namespace=monitoring --values values-grafana.yaml

После завершения установки Grafana выполним получения пароля для пользователя admin с помощью команды:

$ kubectl get secret --namespace monitoring grafana -o jsonpath="{.data.admin-password}" | base64 --decode ; echo

Перейдём в web-интерфейс Grafana по адресу добавленному в ingress, далее в разделе Dashborad, выберем New — Import и выполним импорт дашборда для отображения будущих собираемых метрик. JSON дашборда для Grafana Faro доступен в официальном GitHub репозитории.

Подключение Grafana Faro в приложении

Выполним установку пакетов Grafana Faro используя команду:

$ npm install --save @grafana/faro-web-sdk @grafana/faro-web-tracing

Далее в Frontend JavaScript приложении выполним добавление кода осуществляющий инициализацию Grafana Faro для сбора метрик и трейсов. В коде необходимо указание: названия приложения, его версии, а также API ключа и адреса ингресса Grafana Alloy созданного нами ранее при его установке:

import { getWebInstrumentations, initializeFaro } from '@grafana/faro-web-sdk'; import { TracingInstrumentation } from '@grafana/faro-web-tracing';  const faro = initializeFaro({   url: 'http://alloy.local/collect',   apiKey: 'api-key-app',   instrumentations: [...getWebInstrumentations(), new TracingInstrumentation()],   app: {     name: 'example-frontend-app',     version: '1.0.0',   }, });

Просмотр данных мониторинга

Выполним запуск Frontend JavaScript приложения и перейдём в импортируемый нами ранее дашборд Grafana в котором мы увидим поступающие данные мониторинга:

Полные логи поступающие из Frontend приложения можно увидеть в Grafana перейдя в раздел Explore, далее выбрав источник Loki и выполнив запрос LogQL-{app="название_frontend_приложения"}

Поступающие трейсы в Tempo можно увидеть выбрав источник Tempo, далее в Query type необходимо выбрать TraceQL и ввести запрос- {rootServiceName="название_frontend_приложения"}

Дополнительная документация по использованию Grafana Faro:


ссылка на оригинал статьи https://habr.com/ru/articles/812065/