首页  >  文章  >  web前端  >  NestJS + Opentelemetry(采样)

NestJS + Opentelemetry(采样)

PHPz
PHPz原创
2024-08-19 17:16:03726浏览

格拉法纳云

在上一篇文章中,我在 Grafana Cloud 中拍摄、保存和查看了 Opentelemetry 数据

如果您使用免费版本的 Grafana Cloud,您每月可以获得大约 50GB 的日志和跟踪。如果是因为用户不多,所以不会积累太多trace(或者不记录日志)的服务,直接使用即可,但如果小规模引入的话,恐怕会积累太多日志并爆炸。

采样

抽样是指从整体中提取一部分。因此,任务是减少存储的遥测数据的数量。

为什么需要抽样

为什么需要采样?

NestJS + Opentelemetry (Sampling)

上图中的所有圆圈(轨迹)无需保存。仅存储重要的跟踪(错误或太长的执行时间)和一些代表整体的样本(一些正常的跟踪)就足够了。

抽样类型

采样大致可以分为头部采样和尾部采样。

头部采样

这是指从一开始就采样。一个典型的例子就是概率抽样。只留下了总痕迹的10%,其余的都没有追踪
  • JavaScript

默认提供TraceIdRatioBasedSampler。


劣势
import { TraceIdRatioBasedSampler } from '@opentelemetry/sdk-trace-node';

const samplePercentage = 0.1;

const sdk = new NodeSDK({
  // Other SDK configuration parameters go here
  sampler: new TraceIdRatioBasedSampler(samplePercentage),
});

在某些情况下,重要的痕迹会被删除,因为他们在没有询问的情况下就删除了它。
  • 尾部取样

    采样是从后面进行的。此时,由于可用信息较多,您可以根据想要的逻辑进行过滤。
  • 例如,错误跟踪始终会被采样。
  • 通常,一旦从收集器收到所有痕迹,就会进行采样。
  • 劣势

    实施可能会很困难。当系统改变、条件改变时,它总是必须改变。
  • 很难执行,因为它必须保持有状态才能采样。
  • 在某些情况下,尾部采样器是特定于供应商的。
  • 头像

让我们通过实现自定义跨度处理器来实现尾部采样。

SamplingSpanProcessor 实现

创建采样-span-processor.ts 文件


This._spanProcessor.onEnd(span);仅当status.code为2(错误)或比率概率获胜时。通过调用
import { Context } from "@opentelemetry/api";
import {
  SpanProcessor,
  ReadableSpan,
  Span,
} from "@opentelemetry/sdk-trace-node";

/**
 * Sampling span processor (including all error span and ratio of other spans)
 */
export class SamplingSpanProcessor implements SpanProcessor {
  constructor(
    private _spanProcessor: SpanProcessor,
    private _ratio: number
  ) {}

  /**
   * Forces to export all finished spans
   */
  forceFlush(): Promise<void> {
    return this._spanProcessor.forceFlush();
  }

  onStart(span: Span, parentContext: Context): void {
    this._spanProcessor.onStart(span, parentContext);
  }

  shouldSample(traceId: string): boolean {
    let accumulation = 0;
    for (let idx = 0; idx < traceId.length; idx++) {
      accumulation += traceId.charCodeAt(idx);
    }
    const cmp = (accumulation % 100) / 100;
    return cmp < this._ratio;
  }

  /**
   * Called when a {@link ReadableSpan} is ended, if the `span.isRecording()`
   * returns true.
   * @param span the Span that just ended.
   */
  onEnd(span: ReadableSpan): void {
    // Only process spans that have an error status
    if (span.status.code === 2) {
      // Status code 0 means "UNSET", 1 means "OK", and 2 means "ERROR"
      this._spanProcessor.onEnd(span);
    } else {
      if (this.shouldSample(span.spanContext().traceId)) {
        this._spanProcessor.onEnd(span);
      }
    }
  }

  /**
   * Shuts down the processor. Called when SDK is shut down. This is an
   * opportunity for processor to do any cleanup required.
   */
  async shutdown(): Promise<void> {
    return this._spanProcessor.shutdown();
  }
}
导出

OtelSDK更新

更新 main.ts 中的 spanProcessors。


  spanProcessors: [
    new SamplingSpanProcessor(
      new BatchSpanProcessor(traceExporter),
      samplePercentage
    ),
  ],

以上是NestJS + Opentelemetry(采样)的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn