As bibliotecas do Firebase Genkit são instrumentadas com o OpenTelemetry. para dar suporte à coleta de traces, métricas e registros. Os usuários do Genkit podem exportar isto dados de telemetria para ferramentas de monitoramento e visualização, instalando um plug-in que configura o SDK do OpenTelemetry Go. para exportar para um sistema compatível com OpenTelemetry.
O Genkit inclui um plug-in que configura o OpenTelemetry para exportar dados para o Google Cloud Monitoring e Cloud Logging. Para o suporte a outros sistemas de monitoramento, é possível ampliar o Genkit escrevendo um plug-in de telemetria, conforme descrito nesta página.
Antes de começar
Leia Como escrever plug-ins do Genkit (em inglês) para informações sobre como escrever
qualquer tipo de plug-in Genkit, incluindo plug-ins de telemetria. Observe especificamente que
cada plug-in precisa exportar uma função Init
, que os usuários precisam chamar
antes de usar o plug-in.
Exportadores e loggers
Como já mencionamos, a principal função de um plug-in de telemetria é configurar OpenTelemetry, que já foi instrumentado no Genkit, para exportar dados a um serviço específico. Para isso, você precisa do seguinte:
- Uma implementação do
SpanExporter
do OpenTelemetry que exporta dados para o serviço de sua escolha. - Uma implementação do
metric.Exporter
do OpenTelemetry que exporta dados para o serviço de sua escolha. - Um
slog.Logger
ou uma implementação da interfaceslog.Handler
que exporta registros para o serviço que você escolher.
Dependendo do serviço para o qual você quer exportar, pode ser um um esforço relativamente pequeno ou grande.
Como o OpenTelemetry é um padrão do setor, muitos serviços de monitoramento já
têm bibliotecas que implementam essas interfaces. Por exemplo, o plug-in googlecloud
para Genkit faz uso do
opentelemetry-operations-go
, mantido pela equipe do Google Cloud.
Da mesma forma, muitos serviços de monitoramento oferecem bibliotecas que implementam as
interfaces slog
padrão.
Por outro lado, se não houver bibliotecas desse tipo disponíveis para seu serviço, implementar as interfaces necessárias pode ser um projeto substancial.
Verifique o registro do OpenTelemetry. ou os documentos do serviço de monitoramento para conferir se as integrações já estão disponíveis.
Se você precisar criar essas integrações por conta própria, dê uma olhada na fonte
dos exportadores oficiais do OpenTelemetry
e a página Um guia para criar gerenciadores slog
.
Compilação do plug-in
Dependências
Todo plug-in de telemetria precisa importar a biblioteca principal do Genkit e vários Bibliotecas do 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"
}
Se você estiver criando um plug-in baseado em um OpenTelemetry ou uma integração slog
,
você também precisará importá-los.
Config
Um plug-in de telemetria precisa, no mínimo, ser compatível com a seguinte configuração: opções:
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
}
Os exemplos a seguir presumem que você está disponibilizando essas opções e que algumas orientações sobre como lidar com eles.
A maioria dos plugins também incluirá definições de configuração para o serviço para o qual está sendo exportado (chave de API, nome do projeto e assim por diante).
Init()
A função Init()
de um plug-in de telemetria precisa realizar todas as ações a seguir:
Retorne antecipadamente se o Genkit estiver sendo executado em um ambiente de desenvolvimento (como quando está em execução com
genkit start
) e a opçãoConfig.ForceExport
não estiver definida:shouldExport := cfg.ForceExport || os.Getenv("GENKIT_ENV") != "dev" if !shouldExport { return nil }
Inicialize seu exportador de períodos de trace e registre-o com o Genkit:
spanProcessor := trace.NewBatchSpanProcessor(YourCustomSpanExporter{}) core.RegisterSpanProcessor(spanProcessor)
Inicializar e registrar o exportador de métricas na biblioteca OpenTelemetry:
r := metric.NewPeriodicReader( YourCustomMetricExporter{}, metric.WithInterval(cfg.MetricInterval), ) mp := metric.NewMeterProvider(metric.WithReader(r)) otel.SetMeterProvider(mp)
Use o intervalo de coleta configurado pelo usuário (
Config.MetricInterval
) quando inicializar oPeriodicReader
.Registre o gerenciador
slog
como o registrador padrão:logger := slog.New(YourCustomHandler{ Options: &slog.HandlerOptions{Level: cfg.LogLevel}, }) slog.SetDefault(logger)
Você deve configurar seu manipulador para respeitar o nível mínimo de log especificado pelo usuário (
Config.LogLevel
).
Encobrimento de PII
Como a maioria dos fluxos de IA generativa começa com algum tipo de entrada do usuário, é possibilidade provável de que alguns rastreamentos de fluxo contenham informações (PII). Para proteger as informações dos seus usuários, você deve remover as PII dos rastros antes de exportá-los.
Se você estiver criando seu próprio exportador de períodos, poderá criar essa funcionalidade nele.
Se você estiver criando um plug-in com base em uma integração atual do OpenTelemetry,
pode unir o exportador de períodos fornecido com um exportador personalizado que realiza essa
tarefa. Por exemplo, o plug-in googlecloud
remove o genkit:input
e
os atributos genkit:output
de cada período antes de exportá-los usando um wrapper
semelhante a:
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
}
Solução de problemas
Se você estiver com problemas para fazer com que os dados apareçam no lugar esperado, o OpenTelemetry oferece uma ferramenta de diagnóstico útil. que ajuda a localizar a origem do problema.