Este producto no es compatible con el sitio Datadog seleccionado. ().
Información general
Esta página describe cómo instrumentar su aplicación Go con el SDK de Feature Flags de Datadog. El SDK de Go se integra con OpenFeature, un estándar abierto para la gestión de feature flags, y recibe actualizaciones de flags a través de Remote Configuration en el tracer de Go de Datadog (dd-trace-go).
Esta guía explica cómo instalar y habilitar el SDK, crear un cliente de OpenFeature y evaluar feature flags en su aplicación.
Requisitos previos
Antes de configurar el SDK de Feature Flags de Go, asegúrese de tener:
Datadog Go SDKdd-trace-go versión 2.4.0 o posterior
Establezca las siguientes variables de entorno:
# Required: Enable the feature flags providerDD_EXPERIMENTAL_FLAGGING_PROVIDER_ENABLED=true# Optional: Enable flag evaluation metricsDD_METRICS_OTEL_ENABLED=true# Required: Service identificationDD_SERVICE=<YOUR_SERVICE_NAME>
DD_ENV=<YOUR_ENVIRONMENT>
El EXPERIMENTAL_ prefijo se conserva por compatibilidad con versiones anteriores; el proveedor en sí es estable.
Para configurar feature_flag.evaluations, incluyendo la versión requerida del tracer y la configuración de OTLP del Agente, consulte Set Up Server-Side Flag Evaluation Metrics. Para obtener más información sobre los gráficos disponibles, consulte Feature Flag Graphs.
Instalación
Instale el paquete del proveedor de Datadog OpenFeature:
go get github.com/DataDog/dd-trace-go/v2/openfeature
También necesita el SDK de OpenFeature para Go:
go get github.com/open-feature/go-sdk/openfeature
Inicializar el SDK
Inicie el tracer de Datadog para Go y registre el proveedor de Datadog OpenFeature. El tracer debe iniciarse primero porque habilita Remote Configuration, la cual entrega las configuraciones de flags a su aplicación.
Inicialización bloqueante
Use SetProviderAndWait para bloquear la evaluación hasta que se reciba la configuración inicial de flags. Esto asegura que las flags estén listas antes de que su aplicación comience a manejar solicitudes.
packagemainimport("log""github.com/DataDog/dd-trace-go/v2/ddtrace/tracer"ddopenfeature"github.com/DataDog/dd-trace-go/v2/openfeature""github.com/open-feature/go-sdk/openfeature")funcmain(){// Start the Datadog tracer (enables Remote Config)tracer.Start()defertracer.Stop()// Create the Datadog OpenFeature providerprovider,err:=ddopenfeature.NewDatadogProvider(ddopenfeature.ProviderConfig{})iferr!=nil{log.Fatalf("Failed to create provider: %v",err)}ifddProvider,ok:=provider.(*ddopenfeature.DatadogProvider);ok{deferddProvider.Shutdown()}// Register the provider and wait for initialization (default 30s timeout)iferr:=openfeature.SetProviderAndWait(provider);err!=nil{log.Fatalf("Failed to set provider: %v",err)}// Create the OpenFeature clientclient:=openfeature.NewClient("my-service")// Your application code here}
Para especificar un tiempo de espera personalizado, use SetProviderAndWaitWithContext:
ctx,cancel:=context.WithTimeout(context.Background(),10*time.Second)defercancel()iferr:=openfeature.SetProviderAndWaitWithContext(ctx,provider);err!=nil{log.Fatalf("Failed to set provider: %v",err)}
Inicialización no bloqueante
Use SetProvider para registrar el proveedor sin esperar. Las evaluaciones de flags devuelven valores predeterminados hasta que se recibe la configuración.
packagemainimport("log""github.com/DataDog/dd-trace-go/v2/ddtrace/tracer"ddopenfeature"github.com/DataDog/dd-trace-go/v2/openfeature""github.com/open-feature/go-sdk/openfeature")funcmain(){// Start the Datadog tracer (enables Remote Config)tracer.Start()defertracer.Stop()// Create the Datadog OpenFeature providerprovider,err:=ddopenfeature.NewDatadogProvider(ddopenfeature.ProviderConfig{})iferr!=nil{log.Fatalf("Failed to create provider: %v",err)}ifddProvider,ok:=provider.(*ddopenfeature.DatadogProvider);ok{deferddProvider.Shutdown()}// Register the provider without waitingopenfeature.SetProvider(provider)// Create the OpenFeature clientclient:=openfeature.NewClient("my-service")// Your application code here// Flag evaluations return defaults until configuration is received}
Crear un cliente
Cree un cliente de OpenFeature para evaluar flags. Puede crear múltiples clientes con diferentes nombres para diferentes partes de su aplicación:
// Create a client for your applicationclient:=openfeature.NewClient("my-service")
Establezca el contexto de evaluación
Defina un contexto de evaluación que identifique al usuario o entidad para la segmentación de flags. El contexto de evaluación incluye atributos utilizados para determinar qué variaciones de flag deben devolverse:
Datadog Feature Flags requiere que los atributos del contexto de evaluación sean valores primitivos planos: cadenas, números y booleanos. No pase objetos o arreglos anidados; no son compatibles y pueden causar que los datos de exposición se descarten.
evalCtx:=openfeature.NewEvaluationContext("user-123",// Targeting key (typically user ID)map[string]interface{}{"email":"user@example.com","country":"US","tier":"premium","age":25,},)
La clave de segmentación se utiliza para una distribución de tráfico consistente (lanzamientos porcentuales). Los atributos adicionales permiten reglas de segmentación, como “habilitar para usuarios en EE. UU.” o “habilitar para usuarios de nivel premium” en el ejemplo anterior.
Evalúe Feature Flags
Después de configurar el proveedor y crear un cliente, puede evaluar Feature Flags en toda su aplicación. La evaluación de Feature Flags es local y rápida: el SDK utiliza datos de configuración almacenados en caché localmente, por lo que no se producen solicitudes de red durante la evaluación.
Cada Feature Flag se identifica mediante una clave (una cadena única) y se puede evaluar con un método tipado que devuelve un valor del tipo esperado. Si el Feature Flag no existe o no se puede evaluar, el SDK devuelve el valor predeterminado proporcionado.
Feature Flags booleanos
Utilice BooleanValue para Feature Flags que representen condiciones de encendido/apagado o verdadero/falso:
Para Feature Flags numéricos, utilice IntValue o FloatValue. Estos son apropiados cuando una funcionalidad depende de un parámetro numérico como un límite, porcentaje o multiplicador:
Para datos estructurados, use ObjectValue. Esto devuelve un valor que puede ser afirmado como tipo a mapas u otros tipos complejos:
config,err:=client.ObjectValue(ctx,"feature-config",map[string]interface{}{"maxRetries":3,"timeout":30,},evalCtx)iferr!=nil{log.Printf("Error evaluating flag: %v",err)}// Type assert to access the configurationifconfigMap,ok:=config.(map[string]interface{});ok{maxRetries:=configMap["maxRetries"]timeout:=configMap["timeout"]// Use configuration values}
Detalles de evaluación de Feature Flags
Cuando necesite más que solo el valor de Feature Flags, use los métodos *ValueDetails. Estos devuelven tanto el valor evaluado como los metadatos que explican la evaluación:
Los detalles de Feature Flags le ayudan a depurar el comportamiento de evaluación y a entender por qué un usuario recibió un valor determinado.
Pruebas
Puede realizar pruebas contra un entorno de prueba de Datadog dedicado con el DatadogProvider real, o cambiarlo por el proveedor en memoria de OpenFeature para controlar los valores de Feature Flags directamente en el código de prueba. Esta sección muestra el enfoque en memoria, que mantiene las pruebas herméticas y sin conexión. El proveedor en memoria se incluye en el módulo go-sdk ascendente bajo github.com/open-feature/go-sdk/openfeature/memprovider, por lo que no se requiere ninguna dependencia adicional.
Registre el proveedor en memoria bajo un cliente con nombre en lugar del proveedor global predeterminado. El proveedor predeterminado es global para el proceso, lo que interrumpe t.Parallel() y filtra el estado de Feature Flags entre pruebas. Un cliente con nombre limita el contexto del proveedor a cada prueba.
packagecheckoutimport("context""testing""github.com/open-feature/go-sdk/openfeature""github.com/open-feature/go-sdk/openfeature/memprovider")funcTestNewCheckoutFlow(t*testing.T){cases:=[]struct{namestringtierstringwantbool}{{"premium user sees new flow","premium",true},{"free user sees legacy","free",false},}for_,tc:=rangecases{t.Run(tc.name,func(t*testing.T){evalByTier:=func(flagmemprovider.InMemoryFlag,flatCtxopenfeature.FlattenedContext)(any,openfeature.ProviderResolutionDetail){ifflatCtx["tier"]=="premium"{returnflag.Variants["on"],openfeature.ProviderResolutionDetail{Reason:openfeature.TargetingMatchReason,Variant:"on"}}returnflag.Variants[flag.DefaultVariant],openfeature.ProviderResolutionDetail{Reason:openfeature.DefaultReason,Variant:flag.DefaultVariant}}provider:=memprovider.NewInMemoryProvider(map[string]memprovider.InMemoryFlag{"new-checkout-flow":{State:memprovider.Enabled,DefaultVariant:"off",Variants:map[string]any{"on":true,"off":false},ContextEvaluator:&evalByTier,},})name:="test-"+t.Name()iferr:=openfeature.SetNamedProviderAndWait(name,provider);err!=nil{t.Fatal(err)}t.Cleanup(func(){_=openfeature.SetNamedProviderAndWait(name,openfeature.NoopProvider{})})client:=openfeature.NewClient(name)got,err:=client.BooleanValue(context.Background(),"new-checkout-flow",false,openfeature.NewEvaluationContext("user-1",map[string]any{"tier":tc.tier}))iferr!=nil{t.Fatal(err)}ifgot!=tc.want{t.Errorf("got %v, want %v",got,tc.want)}})}}
ContextEvaluator se define como *func(...) — un puntero a una función. Defina el evaluador en una variable local y pase su dirección con &, como se muestra arriba. Omita ContextEvaluator por completo para devolver siempre DefaultVariant.
Lecturas adicionales
Documentación, enlaces y artículos útiles adicionales: