Bỏ qua, đến nội dung

@digiforce-nc/telemetry

Package@digiforce-nc/telemetry
Depends on@digiforce-nc/utils

1) Tổng quan

@digiforce-nc/telemetry tích hợp OpenTelemetry vào Digiforce, cung cấp khả năng monitoring thông qua metrics (đo lường) và distributed tracing (theo dõi request qua nhiều service). Package đóng vai trò wrapper giúp đơn giản hóa việc thiết lập OpenTelemetry trong hệ sinh thái Digiforce.

OpenTelemetry

OpenTelemetry là tiêu chuẩn observability mở. Digiforce sử dụng nó để bạn có thể tích hợp với bất kỳ backend nào: Prometheus, Grafana, Jaeger, Datadog, New Relic, v.v.


2) Telemetry API

init(options)

Khởi tạo telemetry subsystem:

typescript
import { Telemetry } from '@digiforce-nc/telemetry';

const telemetry = new Telemetry({
  serviceName: 'digiforce-app',
  version: '1.0.0',
  enabled: true,
});

await telemetry.init();
OptionKiểuMô tả
serviceNamestringTên service hiển thị trong traces/metrics
versionstringPhiên bản ứng dụng
enabledbooleanBật/tắt telemetry

start()

Bắt đầu thu thập telemetry data:

typescript
await telemetry.start();
// Metrics bắt đầu được ghi nhận
// Traces bắt đầu được capture

shutdown()

Dừng và flush tất cả data pending:

typescript
await telemetry.shutdown();
// Đảm bảo metrics/traces cuối cùng được gửi đi trước khi process exit

addInstrumentation(instrumentation)

Thêm auto-instrumentation cho thư viện bên thứ ba:

typescript
import { HttpInstrumentation } from '@opentelemetry/instrumentation-http';
import { KoaInstrumentation } from '@opentelemetry/instrumentation-koa';

telemetry.addInstrumentation(new HttpInstrumentation());
telemetry.addInstrumentation(new KoaInstrumentation());

3) Metric API

registerMeter(name)

Đăng ký một meter (nhóm metrics) mới:

typescript
telemetry.registerMeter('http');

getMeter(name)

Lấy meter đã đăng ký để tạo instruments:

typescript
const meter = telemetry.getMeter('http');

// Counter - đếm số lần xảy ra
const requestCounter = meter.createCounter('http.requests.total', {
  description: 'Tổng số HTTP requests',
});

// Histogram - đo phân bố giá trị
const latencyHistogram = meter.createHistogram('http.request.duration', {
  description: 'Thời gian xử lý request (ms)',
  unit: 'ms',
});

// UpDownCounter - giá trị tăng/giảm
const activeConnections = meter.createUpDownCounter('http.connections.active', {
  description: 'Số kết nối đang hoạt động',
});

addReader(reader)

Thêm metric reader (export destination):

typescript
import { PrometheusExporter } from '@opentelemetry/exporter-prometheus';

const reader = new PrometheusExporter({ port: 9464 });
telemetry.addReader(reader);

4) Trace API

registerTraceProvider()

Đăng ký trace provider cho hệ thống:

typescript
telemetry.registerTraceProvider();

getTracer(name)

Lấy tracer để tạo spans:

typescript
const tracer = telemetry.getTracer('http-handler');

async function handleRequest(ctx) {
  const span = tracer.startSpan('handle-request', {
    attributes: {
      'http.method': ctx.method,
      'http.url': ctx.url,
    },
  });

  try {
    await processRequest(ctx);
    span.setStatus({ code: SpanStatusCode.OK });
  } catch (error) {
    span.setStatus({ code: SpanStatusCode.ERROR, message: error.message });
    span.recordException(error);
    throw error;
  } finally {
    span.end();
  }
}

addExporter(exporter)

Thêm trace exporter:

typescript
import { JaegerExporter } from '@opentelemetry/exporter-jaeger';
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';

// Export sang Jaeger
telemetry.addExporter(new JaegerExporter({
  endpoint: 'http://jaeger:14268/api/traces',
}));

// Hoặc export qua OTLP protocol
telemetry.addExporter(new OTLPTraceExporter({
  url: 'http://collector:4318/v1/traces',
}));

5) Distributed tracing flow


6) Prometheus integration

Plugin @digiforce-nc/plugin-telemetry-prometheus tích hợp sẵn Prometheus metrics:

Metrics có sẵn

MetricKiểuMô tả
http_requests_totalCounterTổng số HTTP request
http_request_duration_secondsHistogramThời gian xử lý request
db_query_totalCounterTổng số database query
db_query_duration_secondsHistogramThời gian thực thi query
active_usersGaugeSố user đang hoạt động

Cấu hình

bash
# .env
TELEMETRY_ENABLED=true
TELEMETRY_SERVICE_NAME=digiforce-app
TELEMETRY_PROMETHEUS_PORT=9464
TELEMETRY_TRACE_EXPORTER=otlp
TELEMETRY_OTLP_ENDPOINT=http://collector:4318

7) Code example: Custom metrics cho plugin

typescript
import { Plugin } from '@digiforce-nc/server';

class OrderMetricsPlugin extends Plugin {
  async load() {
    const telemetry = this.app.telemetry;

    telemetry.registerMeter('orders');
    const meter = telemetry.getMeter('orders');

    const orderCounter = meter.createCounter('orders.created.total', {
      description: 'Tổng số đơn hàng được tạo',
    });

    const orderValue = meter.createHistogram('orders.value', {
      description: 'Giá trị đơn hàng',
      unit: 'VND',
    });

    this.app.resourcer.use(async (ctx, next) => {
      await next();

      if (ctx.action.resourceName === 'orders' && ctx.action.actionName === 'create') {
        orderCounter.add(1, {
          status: ctx.response.status === 200 ? 'success' : 'error',
        });

        if (ctx.body?.data?.totalAmount) {
          orderValue.record(ctx.body.data.totalAmount);
        }
      }
    });
  }
}

Performance

Telemetry thêm overhead nhỏ cho mỗi request. Trong môi trường high-throughput, cân nhắc sampling rate cho traces (không cần trace 100% requests).