OpenTelemetry 설정
OpenTelemetry 설정 (Setup OpenTelemetry)
Backstage는 OpenTelemetry를 사용해 트레이스와 메트릭을 보고함으로써 컴포넌트를 계측합니다.
출처: 문서
본문
Backstage는 OpenTelemetry를 사용해 트레이스와 메트릭을 보고함으로써 컴포넌트를 계측합니다.
이 튜토리얼은 Backstage 백엔드 패키지에서 exporter를 설정하는 방법을 보여줍니다. 데모 목적으로 Prometheus exporter를 사용하지만, 요구에 맞게 다른 것을 사용하도록 솔루션을 조정할 수 있습니다. 예를 들어 OTLP exporter에 관한 글을 참조하세요. 이 튜토리얼은 Jaeger가 이상적인 대상인 JSON/HTTP exporter를 사용한 트레이스 내보내기도 포함하지만, OTLP exporter 문서에서 지원 도구를 확인해 요구에 맞게 조정할 수도 있습니다.
의존성 설치 (Install dependencies)
OpenTelemetry Node SDK와 auto-instrumentations-node 패키지를 사용할 것입니다.
catalog 같은 Backstage 패키지는 OpenTelemetry API를 사용해 사용자 정의 트레이스와 메트릭을 보냅니다. auto-instrumentations-node는 Express 같은 라이브러리에서 호출되는 코드에 대한 스팬을 자동으로 생성합니다.
yarn --cwd packages/backend add \ @opentelemetry/sdk-node \ @opentelemetry/auto-instrumentations-node \ @opentelemetry/exporter-prometheus \ @opentelemetry/exporter-trace-otlp-http
구성 (Configure)
packages/backend/src 폴더에 instrumentation.js 파일을 만드세요.
in packages/backend/src/instrumentation.js
// Prevent from running more than once (due to worker threads)const { isMainThread } = require('node:worker_threads');if (isMainThread) { const { NodeSDK } = require('@opentelemetry/sdk-node'); const { getNodeAutoInstrumentations, } = require('@opentelemetry/auto-instrumentations-node'); const { PrometheusExporter } = require('@opentelemetry/exporter-prometheus'); const { OTLPTraceExporter, } = require('@opentelemetry/exporter-trace-otlp-http'); // By default exports the metrics on localhost:9464/metrics const prometheusExporter = new PrometheusExporter(); // We post the traces to localhost:4318/v1/traces const otlpTraceExporter = new OTLPTraceExporter({ // Default Jaeger URL trace endpoint. url: 'http://localhost:4318/v1/traces', }); const sdk = new NodeSDK({ metricReader: prometheusExporter, traceExporter: otlpTraceExporter, instrumentations: [getNodeAutoInstrumentations()], }); sdk.start();}
아마 getNodeAutoInstrumentations() 안의 모든 계측이 필요하지는 않을 것이므로 문서를 확인하고 적절히 조정하세요.
뷰 (Views)
OpenTelemetry의 기본 히스토그램 버킷은 밀리초 단위이지만, Catalog 처리용으로 생성된 히스토그램은 초 단위로 메트릭을 내보냅니다. 필요에 맞게 조정하고 싶을 수 있습니다. 이렇게 하려면 다음과 같이 Views 기능을 사용할 수 있습니다.
const prometheus = new PrometheusExporter();const sdk = new NodeSDK({ metricReader: prometheus, views: [ new View({ instrumentName: 'catalog.test', aggregation: new ExplicitBucketHistogramAggregation([ 0.01, 0.1, 0.5, 1, 5, 10, 25, 50, 100, 500, 1000, ]), }), ],});
위 내용은 모든 히스토그램 버킷이 동일한 구성을 사용하게 만듭니다. 더 집중적인 접근을 원한다면 다음과 같이 할 수 있습니다.
const prometheus = new PrometheusExporter();const sdk = new NodeSDK({ metricReader: prometheus, views: [ new View({ instrumentName: 'catalog.test', aggregation: new ExplicitBucketHistogramAggregation([ 0, 0.01, 0.05, 0.1, 0.25, 0.5, 1, 2, 5, 10, 30, 60, 120, 300, 1000, ]), }), ],});
로컬 개발 설정 (Local Development Setup)
어떤 라이브러리를 가져오기 전에 NodeSDK와 자동 계측을 설정하는 것이 중요합니다. 그래서 애플리케이션을 시작할 때 nodejs --require 플래그를 사용할 것입니다.
로컬 개발을 위해 packages/backend/package.json에 필요한 플래그를 추가할 수 있습니다.
packages/backend/package.json
"scripts": { "start": "backstage-cli package start --require ./src/instrumentation.js", ...
이제 평소처럼 yarn start로 Backstage 인스턴스를 시작할 수 있으며 http://localhost:9464/metrics 에서 메트릭을 볼 수 있습니다.
문제 해결 (Troubleshooting)
메트릭이나 트레이스를 작동시키는 데 문제가 있다면 OpenTelemetry의 유용한 진단 도구를 사용할 수 있습니다.
먼저 @opentelemetry/api 패키지가 필요합니다.
yarn --cwd packages/backend add @opentelemetry/api
그런 다음 sdk.start() 호출 전에 다음 스니펫을 추가합니다.
const { diag, DiagConsoleLogger, DiagLogLevel } = require('@opentelemetry/api');diag.setLogger(new DiagConsoleLogger(), DiagLogLevel.DEBUG);
그러면 OpenTelemetry 디버그 로그가 추가되어 무언가가 예상대로 작동하지 않는 이유를 더 잘 파악하는 데 도움이 됩니다.
로그 밀도 때문에 이를 프로덕션에 배포하는 것은 권장하지 않습니다.
프로덕션 설정 (Production Setup)
.dockerignore에 다음 줄을 추가하세요.
!packages/backend/src/instrumentation.js
이렇게 하면 권장되는 .dockerignore 설정을 따를 때 Docker 빌드가 계측 파일을 무시하지 않습니다.
Dockerfile에서 작업 디렉터리 루트로 instrumentation.js 파일을 복사하세요.
COPY --chown=${NOT_ROOT_USER}:${NOT_ROOT_USER} packages/backend/src/instrumentation.js ./
그리고 파일을 가리키는 --require 플래그를 CMD 배열에 추가하세요.
CMD ["node", "packages/backend", "--config", "app-config.yaml"]CMD ["node", "--require", "./instrumentation.js", "packages/backend", "--config", "app-config.yaml"]
일부 OpenTelemetry 기능을 비활성화하거나 구성해야 한다면 조정할 수 있는 환경 변수가 많이 있습니다.
사용 가능한 메트릭 (Available Metrics)
다음 메트릭을 사용할 수 있습니다.
-
catalog_entities_count: 카탈로그의 엔티티 총 개수 -
catalog_registered_locations_count: 카탈로그의 등록된 위치 총 개수 -
catalog_relations_count: 엔티티 간 관계 총 개수 -
catalog.processed.entities.count: 처리된 엔티티 개수 -
catalog.processing.duration: 전체 처리 흐름을 실행하는 데 걸린 시간 -
catalog.processors.duration: 카탈로그 프로세서를 실행하는 데 걸린 시간 -
catalog.processing.queue.delay: 처리를 예약한 시점부터 실제 처리가 시작될 때까지의 지연량 -
catalog.stitched.entities.count: 스티칭된 엔티티 개수 -
catalog.stitching.duration: 전체 스티칭 흐름을 실행하는 데 걸린 시간 -
catalog.stitching.queue.length: 현재 스티칭 대기열에 있는 엔티티 수 -
catalog.stitching.queue.delay: 스티칭을 예약한 시점부터 실제 스티칭이 시작될 때까지의 지연량 -
scaffolder.task.count: 태스크 실행 횟수 -
scaffolder.task.duration: 태스크 실행 시간 -
scaffolder.step.count: 스텝 실행 횟수 -
scaffolder.step.duration: 스텝 실행 시간 -
backend_tasks.task.runs.count: 태스크가 실행된 총 횟수 -
backend_tasks.task.runs.duration: 태스크 실행 시간의 히스토그램 -
backend_tasks.task.runs.started: 각 태스크(taskId라벨)가 마지막으로 시작된 Unix epoch 시간(초)을 기록하는 게이지 -
backend_tasks.task.runs.completed: 각 태스크(taskId라벨)가 마지막으로 완료된 Unix epoch 시간(초)을 기록하는 게이지
참고 자료 (References)
-
Getting started with OpenTelemetry Node.js
-
OpenTelemetry NodeSDK API