Genkit Telemetri Eklentisi Yazma

OpenTelemetry, izlerin, metriklerin ve günlüklerin toplanmasını destekler. Firebase Genkit, Düğüm.js SDK'dır.

Yapılandırma

Telemetri dışa aktarımını kontrol etmek için eklentinizin PluginOptions öğesi Genkit'in yapılandırmasındaki telemetry blokuna uyan telemetry nesnesi.

export interface InitializedPlugin {
  ...
  telemetry?: {
    instrumentation?: Provider<TelemetryConfig>;
    logger?: Provider<LoggerConfig>;
  };
}

Bu nesne iki ayrı yapılandırma sağlayabilir:

  • instrumentation: Traces ve için OpenTelemetry yapılandırması sağlar Metrics.
  • logger: Genkit tarafından yazma işlemi için kullanılan temel logger'ı sağlar. Genkit akışlarının girişleri ve çıkışları dahil olmak üzere yapılandırılmış günlük verileri.

Node.js için günlük kaydı işlevi nedeniyle bu ayırma şu anda gereklidir OpenTelemetry SDK'sı hâlâ geliştirme aşamasındadır. Bir eklentinin, verilerin nerede depolandığını kontrol edebilmesi için günlük kaydı ayrı olarak sağlanır çok önemlidir.

import { genkitPlugin, Plugin } from '@genkit-ai/core';

...

export interface MyPluginOptions {
  // [Optional] Your plugin options
}

export const myPlugin: Plugin<[MyPluginOptions] | []> = genkitPlugin(
  'myPlugin',
  async (options?: MyPluginOptions) => {
    return {
      telemetry: {
        instrumentation: {
          id: 'myPlugin',
          value: myTelemetryConfig,
        },
        logger: {
          id: 'myPlugin',
          value: myLogger,
        },
      },
    };
  }
);

export default myPlugin;

Yukarıdaki kod bloğuyla eklentiniz artık Genkit'e telemetri verileri sağlayacak yapılandırma dosyaları bulunur.

Enstrümantasyon

İzlerin ve metriklerin dışa aktarılmasını kontrol etmek için eklentinizin telemetry nesnesinde,instrumentation TelemetryConfig arayüzü:

interface TelemetryConfig {
  getConfig(): Partial<NodeSDKConfiguration>;
}

Bu,Partial<NodeSDKConfiguration> 3D modelleri başlatmak için Genkit çerçevesi NodeSDK. Bu, OpenTelemetry entegrasyonunun kullanılma şekli üzerinde eklentiye tam kontrol sağlar tarafından geliştirilmiştir.

Örneğin, aşağıdaki telemetri yapılandırması basit bir bellek içi izleme ve metrik dışa aktarıcı sağlar:

import { AggregationTemporality, InMemoryMetricExporter, MetricReader, PeriodicExportingMetricReader } from '@opentelemetry/sdk-metrics';
import { AlwaysOnSampler, BatchSpanProcessor, InMemorySpanExporter } from '@opentelemetry/sdk-trace-base';
import { NodeSDKConfiguration } from '@opentelemetry/sdk-node';
import { Resource } from '@opentelemetry/resources';
import { TelemetryConfig } from '@genkit-ai/core';

...

const myTelemetryConfig: TelemetryConfig = {
  getConfig(): Partial<NodeSDKConfiguration> {
    return {
      resource: new Resource({}),
      spanProcessor: new BatchSpanProcessor(new InMemorySpanExporter()),
      sampler: new AlwaysOnSampler(),
      instrumentations: myPluginInstrumentations,
      metricReader: new PeriodicExportingMetricReader({
        exporter: new InMemoryMetricExporter(AggregationTemporality.CUMULATIVE),
      }),
    };
  },
};

Logger

Genkit çerçevesi tarafından yapılandırılmış günlük verileri yazmak için kullanılan logger’ı kontrol etmek amacıyla eklenti, telemetry nesnesindelogger LoggerConfig arayüzü:

interface LoggerConfig {
  getLogger(env: string): any;
}
{
  debug(...args: any);
  info(...args: any);
  warn(...args: any);
  error(...args: any);
  level: string;
}

En popüler günlük kaydı çerçeveleri buna uygundur. Bu çerçevelerden biri winston: bir yapılandırmanın günlük verilerini doğrudan seçtiğiniz bir konuma aktarabilen bağlayıcılar içerir.

Örneğin, günlük verilerini konsola yazan bir winston logger'ı sağlamak için, eklenti günlüğünüzü aşağ��dakileri kullanacak şekilde güncelleyebilirsiniz:

import * as winston from 'winston';

...

const myLogger: LoggerConfig = {
  getLogger(env: string) {
    return winston.createLogger({
      transports: [new winston.transports.Console()],
      format: winston.format.printf((info): string => {
        return `[${info.level}] ${info.message}`;
      }),
    });
  }
};

Günlükleri ve İzleri bağlama

Genellikle günlük özetlerinizin Eklentiniz tarafından dışa aktarılan OpenTelemetry izleri. Çünkü günlük ifadeleri doğrudan OpenTelemetry çerçevesi tarafından dışa aktarıldığından seçin. Neyse ki OpenTelemetry, izin belgesini kopyalayacak araçları ve winston gibi popüler günlük kaydı çerçeveleri için kimlikleri günlük ifadelerine ekleyin. ve pino yer alır. @opentelemetry/auto-instrumentations-node paketi kullanıldığında, bunları (ve diğer) araçları otomatik olarak yapılandırabilirsiniz, ancak bazı durumlarda, izler ve alanlar için alan adlarını ve değerlerini kontrol etmeniz sağlar. Bunu yapmak için, cihaza kaydetmek üzere özel bir LogHook enstrümantasyonu TelemetryConfig tarafından sağlanan NodeSDK yapılandırması:

import { Instrumentation } from '@opentelemetry/instrumentation';
import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';
import { WinstonInstrumentation } from '@opentelemetry/instrumentation-winston';
import { Span } from '@opentelemetry/api';

const myPluginInstrumentations: Instrumentation[] =
  getNodeAutoInstrumentations().concat([
    new WinstonInstrumentation({
      logHook: (span: Span, record: any) => {
        record['my-trace-id'] = span.spanContext().traceId;
        record['my-span-id'] = span.spanContext().spanId;
        record['is-trace-sampled'] = span.spanContext().traceFlags;
      },
    }),
  ]);

Örnekte NodeSDK OpenTelemetry için tüm otomatik araçlar etkinleştirilir, ve ardından, izleme kodunu yazan veWinstonInstrumentation span kimliklerini günlük mesajındaki özel alanlara ekleyin.

Genkit çerçevesi, eklentinizin TelemetryConfig öğesinin ilk başlatılmış ancakLoggerConfig LoggerConfig içe aktarılana kadar temel günlük kaydedicinin başlatıldı. Örneğin, yukarıdaki LoggingConfig şu şekilde değiştirilebilir:

const myLogger: LoggerConfig = {
  async getLogger(env: string) {
    // Do not import winston before calling getLogger so that the NodeSDK
    // instrumentations can be registered first.
    const winston = await import('winston');

    return winston.createLogger({
      transports: [new winston.transports.Console()],
      format: winston.format.printf((info): string => {
        return `[${info.level}] ${info.message}`;
      }),
    });
  },
};

Tam Örnek

Aşağıda, yukarıda oluşturulan telemetri eklentisinin tam bir örneği verilmiştir. Örneğin, gerçek hayattan bir örnek görmek için @genkit-ai/google-cloud eklentisine göz atın.

import {
  genkitPlugin,
  LoggerConfig,
  Plugin,
  TelemetryConfig,
} from '@genkit-ai/core';
import { Span } from '@opentelemetry/api';
import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';
import { Instrumentation } from '@opentelemetry/instrumentation';
import { WinstonInstrumentation } from '@opentelemetry/instrumentation-winston';
import { Resource } from '@opentelemetry/resources';
import {
  AggregationTemporality,
  InMemoryMetricExporter,
  PeriodicExportingMetricReader,
} from '@opentelemetry/sdk-metrics';
import { NodeSDKConfiguration } from '@opentelemetry/sdk-node';
import {
  AlwaysOnSampler,
  BatchSpanProcessor,
  InMemorySpanExporter,
} from '@opentelemetry/sdk-trace-base';

export interface MyPluginOptions {
  // [Optional] Your plugin options
}

const myPluginInstrumentations: Instrumentation[] =
  getNodeAutoInstrumentations().concat([
    new WinstonInstrumentation({
      logHook: (span: Span, record: any) => {
        record['my-trace-id'] = span.spanContext().traceId;
        record['my-span-id'] = span.spanContext().spanId;
        record['is-trace-sampled'] = span.spanContext().traceFlags;
      },
    }),
  ]);

const myTelemetryConfig: TelemetryConfig = {
  getConfig(): Partial<NodeSDKConfiguration> {
    return {
      resource: new Resource({}),
      spanProcessor: new BatchSpanProcessor(new InMemorySpanExporter()),
      sampler: new AlwaysOnSampler(),
      instrumentations: myPluginInstrumentations,
      metricReader: new PeriodicExportingMetricReader({
        exporter: new InMemoryMetricExporter(AggregationTemporality.CUMULATIVE),
      }),
    };
  },
};

const myLogger: LoggerConfig = {
  async getLogger(env: string) {
    // Do not import winston before calling getLogger so that the NodeSDK
    // instrumentations can be registered first.
    const winston = await import('winston');

    return winston.createLogger({
      transports: [new winston.transports.Console()],
      format: winston.format.printf((info): string => {
        return `[${info.level}] ${info.message}`;
      }),
    });
  },
};

export const myPlugin: Plugin<[MyPluginOptions] | []> = genkitPlugin(
  'myPlugin',
  async (options?: MyPluginOptions) => {
    return {
      telemetry: {
        instrumentation: {
          id: 'myPlugin',
          value: myTelemetryConfig,
        },
        logger: {
          id: 'myPlugin',
          value: myLogger,
        },
      },
    };
  }
);

export default myPlugin;

Sorun giderme

Verilerin beklediğiniz yerde görünmesini sağlama konusunda sorun yaşıyorsanız OpenTelemetry size Teşhis aracı bir çözüm bulmanız gerekir.