OpenTelemetry mendukung pengumpulan trace, metrik, dan log. Firebase Genkit dapat diperluas untuk mengekspor semua data telemetri ke sistem apa pun yang mendukung OpenTelemetry dengan menulis plugin telemetri yang mengonfigurasi Node.js SDK.
Konfigurasi
Untuk mengontrol ekspor telemetri, PluginOptions
plugin harus menyediakan
Objek telemetry
yang sesuai dengan blok telemetry
dalam konfigurasi Genkit.
export interface InitializedPlugin {
...
telemetry?: {
instrumentation?: Provider<TelemetryConfig>;
logger?: Provider<LoggerConfig>;
};
}
Objek ini dapat menyediakan dua konfigurasi terpisah:
instrumentation
: menyediakan konfigurasi OpenTelemetry untukTraces
danMetrics
.logger
: menyediakan pencatat log dasar yang digunakan oleh Genkit untuk menulis data log terstruktur, termasuk input dan output alur Genkit.
Pemisahan ini saat ini diperlukan karena fungsi logging untuk Node.js OpenTelemetry SDK masih dalam pengembangan. Logging disediakan secara terpisah sehingga plugin dapat mengontrol lokasi data secara eksplisit.
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;
Dengan blok kode di atas, plugin Anda sekarang akan menyediakan telemetri ke Genkit konfigurasi yang dapat digunakan oleh pengembang.
Instrumentasi
Untuk mengontrol ekspor trace dan metrik, plugin Anda harus menyediakan
Properti instrumentation
pada objek telemetry
yang sesuai dengan
Antarmuka TelemetryConfig
:
interface TelemetryConfig {
getConfig(): Partial<NodeSDKConfiguration>;
}
Ini menyediakan Partial<NodeSDKConfiguration>
yang akan digunakan oleh
framework Genkit untuk memulai
NodeSDK
.
Ini memberikan plugin kontrol penuh tentang bagaimana integrasi OpenTelemetry digunakan
oleh Genkit.
Misalnya, konfigurasi telemetri berikut menyediakan pengekspor metrik dan trace dalam memori yang sederhana:
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
Untuk mengontrol logger yang digunakan framework Genkit untuk menulis data log terstruktur,
plugin harus menyediakan properti logger
pada objek telemetry
yang sesuai dengan
Antarmuka LoggerConfig
:
interface LoggerConfig {
getLogger(env: string): any;
}
{
debug(...args: any);
info(...args: any);
warn(...args: any);
error(...args: any);
level: string;
}
Sebagian besar framework logging populer sesuai dengan fungsi ini. Salah satu kerangka kerja tersebut adalah winston, yang memungkinkan konfigurasi yang dapat langsung mendorong data log ke lokasi pilihan Anda.
Misalnya, untuk menyediakan {i>winston logger<i} yang menulis data log ke konsol, Anda dapat memperbarui logger plugin untuk menggunakan hal berikut:
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}`;
}),
});
}
};
Menautkan log dan Trace
Sering kali lebih baik untuk memiliki laporan
log Anda berkorelasi dengan
Rekaman aktivitas OpenTelemetry yang diekspor oleh plugin Anda. Karena laporan
log tidak
diekspor oleh kerangka kerja OpenTelemetry secara langsung. Hal ini tidak terjadi di luar
. Untungnya, OpenTelemetry mendukung instrumentasi yang akan menyalin jejak
dan menempelkan ID ke laporan log untuk framework logging populer seperti winston
dan pino. Dengan menggunakan paket @opentelemetry/auto-instrumentations-node
,
Anda dapat mengatur instrumentasi ini (dan yang lainnya)
secara otomatis dikonfigurasi, tetapi dalam
dalam beberapa kasus, Anda mungkin perlu mengontrol
nama dan nilai {i>field <i}untuk jejak dan
span. Untuk melakukan ini, Anda harus menyediakan
instrumentasi LogHook kustom untuk
konfigurasi NodeSDK yang disediakan oleh TelemetryConfig
Anda:
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;
},
}),
]);
Contoh ini mengaktifkan semua instrumentasi otomatis untuk NodeSDK
OpenTelemetry,
lalu menyediakan WinstonInstrumentation
kustom yang menulis rekaman aktivitas dan
yang menjangkau ID ke kolom
khusus pada pesan log.
Framework Genkit akan menjamin bahwa TelemetryConfig
plugin Anda akan
menginisialisasi sebelum LoggerConfig
plugin, tetapi Anda harus berhati-hati
memastikan bahwa pencatat log yang mendasarinya
tidak diimpor sampai LoggerConfig
diinisialisasi. Misalnya, loggingConfig di atas dapat diubah sebagai berikut:
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}`;
}),
});
},
};
Contoh Lengkap
Berikut adalah contoh lengkap plugin telemetri yang dibuat di atas. Sebagai
contoh nyata, lihat plugin @genkit-ai/google-cloud
.
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;
Pemecahan masalah
Jika Anda mengalami kesulitan mendapatkan data untuk muncul di tempat yang Anda harapkan, OpenTelemetry menyediakan Alat diagnostik yang membantu menemukan sumber masalahnya.