Firebase Genkit ライブラリは、OpenTelemetry でインストルメント化され、トレース、指標、ログの収集をサポートします。Genkit ユーザーは、OpenTelemetry Go SDK を特定の OpenTelemetry 対応システムにエクスポートするように構成するプラグインをインストールすることで、このテレメトリー データをモニタリング ツールと可視化ツールにエクスポートできます。
Genkit には、Google Cloud Monitoring と Cloud Logging にデータをエクスポートするように OpenTelemetry を構成するプラグインが含まれています。他のモニタリング システムをサポートするには、このページで説明されているように、テレメトリー プラグインを記述して Genkit を拡張できます。
始める前に
テレメトリー プラグインなど、あらゆる種類の Genkit プラグインの作成については、Genkit プラグインの作成をご覧ください。特に、すべてのプラグインは Init
関数をエクスポートする必要があります。この関数は、ユーザーがプラグインを使用する前に呼び出すことが想定されています。
エクスポータとロガー
前述のように、テレメトリー プラグインの主な役割は、OpenTelemetry(Genkit がすでにインストルされている)を設定して、特定のサービスにデータをエクスポートすることです。そのためには、次のものが必要です。
- 任意のサービスにデータをエクスポートする OpenTelemetry の
SpanExporter
インターフェースの実装。 - 任意のサービスにデータをエクスポートする OpenTelemetry の
metric.Exporter
インターフェースの実装。 - 任意のサービスにログをエクスポートする
slog.Logger
またはslog.Handler
インターフェースの実装。
エクスポート先のサービスによっては、比較的、小規模な作業になる場合もあれば、大規模な作業になる場合もあります。
OpenTelemetry は業界標準であるため、多くのモニタリング サービスには、これらのインターフェースを実装するライブラリがすでに用意されています。たとえば、Genkit の googlecloud
プラグインは、Google Cloud チームが管理する opentelemetry-operations-go
ライブラリを使用しています。同様に、多くのモニタリング サービスは、標準の slog
インターフェースを実装するライブラリを提供しています。
一方、そのようなライブラリがサービスで使用できない場合、必要なインターフェースを実装するのは大規模なプロジェクトになる可能性があります。
OpenTelemetry レジストリまたはモニタリング サービスのドキュメントで、統合がすでに利用可能かどうかを確認します。
これらの統合を自分で構築する必要がある場合は、公式の OpenTelemetry エクスポータのソースと slog
ハンドラの作成ガイドをご覧ください。
プラグインのビルド
依存関係
すべてのテレメトリー プラグインは、Genkit コア ライブラリといくつかの OpenTelemetry ライブラリをインポートする必要があります。
import {
// Import the Genkit core library.
"github.com/firebase/genkit/go/core"
// Import the OpenTelemetry libraries.
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/sdk/metric"
"go.opentelemetry.io/otel/sdk/trace"
}
既存の OpenTelemetry または slog
統合を基にプラグインを構築する場合は、それらをインポートする必要もあります。
Config
テレメトリー プラグインは、少なくとも次の構成オプションをサポートする必要があります。
type Config struct {
// Export even in the dev environment.
ForceExport bool
// The interval for exporting metric data.
// The default is 60 seconds.
MetricInterval time.Duration
// The minimum level at which logs will be written.
// Defaults to [slog.LevelInfo].
LogLevel slog.Leveler
}
以下の例では、これらのオプションを利用できることを前提としています。また、それらのオプションを処理する方法についても説明します。
ほとんどのプラグインには、エクスポート先のサービス(API キー、プロジェクト名など)の構成設定も含まれています。
Init()
テレメトリー プラグインの Init()
関数は、次のすべてを行う必要があります。
Genkit が開発環境で実行されている場合(
genkit start
で実行している場合など)で、Config.ForceExport
オプションが設定されていない場合は、早期リターンします。shouldExport := cfg.ForceExport || os.Getenv("GENKIT_ENV") != "dev" if !shouldExport { return nil }
トレース スパンのエクスポータを初期化し、Genkit に登録します。
spanProcessor := trace.NewBatchSpanProcessor(YourCustomSpanExporter{}) core.RegisterSpanProcessor(spanProcessor)
指標エクスポータを初期化し、OpenTelemetry ライブラリに登録します。
r := metric.NewPeriodicReader( YourCustomMetricExporter{}, metric.WithInterval(cfg.MetricInterval), ) mp := metric.NewMeterProvider(metric.WithReader(r)) otel.SetMeterProvider(mp)
PeriodicReader
を初期化するときに、ユーザーが設定した収集間隔(Config.MetricInterval
)を使用します。slog
ハンドラをデフォルトのロガーとして登録します。logger := slog.New(YourCustomHandler{ Options: &slog.HandlerOptions{Level: cfg.LogLevel}, }) slog.SetDefault(logger)
ユーザー指定の最小ログレベル(
Config.LogLevel
)に従うようにハンドラを構成する必要があります。
個人情報(PII)の削除
ほとんどの生成 AI フローは、なんらかのユーザー入力から始まるため、一部のフロー トレースには個人を特定できる情報(PII)が含まれている可能性が高くなります。ユーザーの情報を保護するには、トレースから PII を削除してからエクスポートする必要があります。
独自のスパン エクスポータを構築する場合は、この機能を組み込むことができます。
既存の OpenTelemetry 統合を基にプラグインを構築する場合は、このタスクを実行するカスタム エクスポータで提供されたスパン エクスポータをラップできます。たとえば、googlecloud
プラグインは、次のようなラッパーを使用してエクスポートする前に、すべてのスパンから genkit:input
属性と genkit:output
属性を削除します。
type redactingSpanExporter struct {
trace.SpanExporter
}
func (e *redactingSpanExporter) ExportSpans(ctx context.Context, spanData []trace.ReadOnlySpan) error {
var redacted []trace.ReadOnlySpan
for _, s := range spanData {
redacted = append(redacted, redactedSpan{s})
}
return e.SpanExporter.ExportSpans(ctx, redacted)
}
func (e *redactingSpanExporter) Shutdown(ctx context.Context) error {
return e.SpanExporter.Shutdown(ctx)
}
type redactedSpan struct {
trace.ReadOnlySpan
}
func (s redactedSpan) Attributes() []attribute.KeyValue {
// Omit input and output, which may contain PII.
var ts []attribute.KeyValue
for _, a := range s.ReadOnlySpan.Attributes() {
if a.Key == "genkit:input" || a.Key == "genkit:output" {
continue
}
ts = append(ts, a)
}
return ts
}
トラブルシューティング
想定どおりの場所にデータが表示されない場合は、OpenTelemetry が提供する便利な診断ツールが問題の原因特定に役立ちます。