Menulis plugin telemetri Genkit

Library Firebase Genkit diinstrumentasikan dengan OpenTelemetry untuk mendukung pengumpulan trace, metrik, dan log. Pengguna Genkit dapat mengekspor ini data telemetri ke alat pemantauan dan visualisasi dengan menginstal plugin yang mengonfigurasi OpenTelemetry Go SDK untuk mengekspor ke sistem yang mendukung OpenTelemetry tertentu.

Genkit menyertakan plugin yang mengonfigurasi OpenTelemetry untuk mengekspor data Google Cloud Monitoring dan Cloud Logging. Untuk mendukung sistem pemantauan lain, Anda dapat memperluas genkit dengan menulis plugin telemetri, sebagaimana dijelaskan di halaman ini.

Sebelum memulai

Baca Menulis plugin Genkit untuk mengetahui informasi tentang penulisan segala jenis plugin Genkit, termasuk plugin telemetri. Secara khusus, perhatikan bahwa setiap plugin harus mengekspor fungsi Init, yang diharapkan akan dipanggil oleh pengguna sebelum menggunakan plugin.

Pengekspor dan Pencatat

Seperti disebutkan sebelumnya, tugas utama plugin telemetri adalah mengonfigurasi OpenTelemetry (yang telah diinstrumentasikan dengan Genkit) untuk mengekspor data ke layanan tertentu. Untuk melakukannya, Anda memerlukan hal berikut:

  • Implementasi SpanExporter OpenTelemetry antarmuka yang mengekspor data ke layanan pilihan Anda.
  • Implementasi metric.Exporter OpenTelemetry antarmuka yang mengekspor data ke layanan pilihan Anda.
  • slog.Logger atau implementasi slog.Handler , yang mengekspor log ke layanan pilihan Anda.

Bergantung pada layanan tujuan ekspor, layanan ini mungkin sedikit atau besar.

Karena OpenTelemetry adalah standar industri, banyak layanan pemantauan memiliki library yang mengimplementasikan antarmuka ini. Misalnya, googlecloud plugin untuk Genkit memanfaatkan opentelemetry-operations-go library, yang dikelola oleh tim Google Cloud. Demikian pula, banyak layanan pemantauan menyediakan library yang mengimplementasikan antarmuka slog standar.

Di sisi lain, jika tidak ada perpustakaan seperti itu yang tersedia untuk layanan Anda, menerapkan antarmuka yang diperlukan bisa menjadi proyek yang besar.

Memeriksa registry OpenTelemetry atau dokumen layanan pemantauan untuk melihat apakah integrasi sudah tersedia.

Jika Anda perlu membangun integrasi ini sendiri, lihat sumber pengekspor resmi OpenTelemetry dan halaman Panduan untuk Menulis Pengendali slog.

Membuat plugin

Dependensi

Setiap plugin telemetri perlu mengimpor library inti Genkit dan Library 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"
}

Jika Anda membangun plugin berdasarkan OpenTelemetry atau slog yang sudah ada integrasi, Anda juga perlu mengimpornya.

Config

Setidaknya plugin telemetri harus mendukung konfigurasi berikut opsi:

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
}

Contoh berikut mengasumsikan bahwa Anda membuat opsi ini tersedia dan akan memberikan beberapa panduan tentang cara menanganinya.

Sebagian besar plugin juga akan menyertakan setelan konfigurasi untuk layanan tempatnya yang ingin diekspor (kunci API, nama project, dan sebagainya).

Init()

Fungsi Init() plugin telemetri harus melakukan semua hal berikut:

  • Kembali lebih awal jika Genkit berjalan di lingkungan pengembangan (seperti saat berjalan dengan genkit start) dan opsi Config.ForceExport tidak tetapkan:

    shouldExport := cfg.ForceExport || os.Getenv("GENKIT_ENV") != "dev"
    if !shouldExport {
    	return nil
    }
    
  • Lakukan inisialisasi pengekspor span trace Anda dan daftarkan dengan Genkit:

    spanProcessor := trace.NewBatchSpanProcessor(YourCustomSpanExporter{})
    core.RegisterSpanProcessor(spanProcessor)
    
  • Melakukan inisialisasi pengekspor metrik dan mendaftarkannya ke OpenTelemetry {i>library<i}:

    r := metric.NewPeriodicReader(
    	YourCustomMetricExporter{},
    	metric.WithInterval(cfg.MetricInterval),
    )
    mp := metric.NewMeterProvider(metric.WithReader(r))
    otel.SetMeterProvider(mp)
    

    Gunakan interval pengumpulan yang dikonfigurasi pengguna (Config.MetricInterval) saat melakukan inisialisasi PeriodicReader.

  • Daftarkan pengendali slog Anda sebagai logger default:

    logger := slog.New(YourCustomHandler{
    	Options: &slog.HandlerOptions{Level: cfg.LogLevel},
    })
    slog.SetDefault(logger)
    

    Anda harus mengonfigurasi pengendali agar mengikuti log minimum yang ditentukan pengguna level (Config.LogLevel).

Penyamaran PII

Karena sebagian besar alur AI generatif dimulai dengan input pengguna, maka kemungkinan bahwa beberapa pelacakan alur berisi informasi identitas pribadi informasi (PII). Untuk melindungi akun Anda harus menyamarkan PII dari trace sebelum mengekspornya.

Jika membangun pengekspor span sendiri, Anda dapat membangun fungsi ini ke dalamnya.

Jika Anda membangun plugin berdasarkan integrasi OpenTelemetry yang ada, Anda dapat menggabungkan pengekspor span yang disediakan dengan pengekspor kustom yang melakukan hal ini tugas Anda. Misalnya, plugin googlecloud menghapus genkit:input dan Atribut genkit:output dari setiap span sebelum mengekspornya menggunakan wrapper mirip dengan contoh berikut ini:

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
}

Pemecahan masalah

Jika Anda mengalami kesulitan untuk memunculkan data di tempat yang Anda harapkan, OpenTelemetry menyediakan alat diagnostik yang berguna yang membantu menemukan sumber masalahnya.