Ce produit n'est pas pris en charge par le site Datadog que vous avez sélectionné. ().
Vue d’ensemble
Cette page décrit comment instrumenter votre application Go avec le SDK Datadog Feature Flags. Le SDK Go s’intègre à OpenFeature, un standard ouvert pour la gestion des Feature Flags, et reçoit les mises à jour des flags via Remote Configuration dans le Datadog Go tracer (dd-trace-go).
Ce guide explique comment installer et activer le SDK, créer un client OpenFeature et évaluer les Feature Flags dans votre application.
Prérequis
Avant de configurer le SDK Go Feature Flags, assurez-vous de disposer des éléments suivants :
Installez le package du fournisseur Datadog OpenFeature :
go get github.com/DataDog/dd-trace-go/v2/openfeature
Vous avez également besoin de l’OpenFeature Go SDK :
go get github.com/open-feature/go-sdk/openfeature
Initialiser le SDK
Démarrez le Datadog Go tracer et enregistrez le fournisseur Datadog OpenFeature. Le Datadog Go tracer doit être démarré en premier, car il active Remote Configuration, qui transmet les configurations de flags à votre application.
Initialisation bloquante
Utilisez SetProviderAndWait pour bloquer l’évaluation jusqu’à ce que la configuration initiale des flags soit reçue. Cela garantit que les flags sont prêts avant que votre application ne commence à traiter les requêtes.
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}
Pour spécifier un délai d’attente personnalisé, utilisez 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)}
Initialisation non bloquante
Utilisez SetProvider pour enregistrer le fournisseur sans attendre. Les évaluations de flags renvoient des valeurs par défaut jusqu’à ce que la configuration soit reçue.
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}
Créer un client
Créez un client OpenFeature pour évaluer les flags. Vous pouvez créer plusieurs clients avec des noms différents pour différentes parties de votre application :
// Create a client for your applicationclient:=openfeature.NewClient("my-service")
Définir le contexte d’évaluation
Définissez un contexte d’évaluation qui identifie l’utilisateur ou l’entité pour le ciblage des Feature Flags. Le contexte d’évaluation inclut des attributs utilisés pour déterminer quelles variations de Feature Flags doivent être renvoyées :
Datadog Feature Flags nécessite que les attributs du contexte d'évaluation soient des valeurs primitives plates : chaînes de caractères, nombres et booléens. Ne transmettez pas d'objets ou de tableaux imbriqués ; ils ne sont pas pris en charge et peuvent entraîner la perte des données d'exposition.
evalCtx:=openfeature.NewEvaluationContext("user-123",// Targeting key (typically user ID)map[string]interface{}{"email":"user@example.com","country":"US","tier":"premium","age":25,},)
La clé de ciblage est utilisée pour une distribution cohérente du trafic (déploiements progressifs). Des attributs supplémentaires permettent de définir des règles de ciblage, telles que « activer pour les utilisateurs aux États-Unis » ou « activer pour les utilisateurs de niveau premium » dans l’exemple ci-dessus.
Évaluer les Feature Flags
Après avoir configuré le fournisseur et créé un client, vous pouvez évaluer les Feature Flags dans toute votre application. L’évaluation des Feature Flags est locale et rapide : le SDK utilise des données de configuration mises en cache localement, de sorte qu’aucune requête réseau n’est effectuée pendant l’évaluation.
Chaque Feature Flag est identifié par une clé (une chaîne unique) et peut être évalué avec une méthode typée qui renvoie une valeur du type attendu. Si le Feature Flag n’existe pas ou ne peut pas être évalué, le SDK renvoie la valeur par défaut fournie.
Feature Flags booléens
Utilisez BooleanValue pour les flags qui représentent des conditions activées/désactivées ou vrai/faux :
Pour les numeric flags, utilisez IntValue ou FloatValue. Ils sont appropriés lorsqu’une fonctionnalité dépend d’un paramètre numérique tel qu’une limite, un pourcentage ou un multiplicateur :
Pour les données structurées, utilisez ObjectValue. Ceci renvoie une valeur qui peut être type-assertée en maps ou d’autres types complexes :
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}
Détails de l’évaluation des Feature Flags
Lorsque vous avez besoin de plus que la simple valeur du flag, utilisez les méthodes *ValueDetails. Celles-ci renvoient à la fois la valeur évaluée et les métadonnées expliquant l’évaluation :
Les détails des indicateurs vous aident à déboguer le comportement d’évaluation et à comprendre pourquoi un utilisateur a reçu une valeur donnée.
Tests
Vous pouvez effectuer des tests sur un environnement de test Datadog dédié avec le DatadogProvider réel, ou le remplacer par le fournisseur en mémoire d’OpenFeature pour contrôler directement les valeurs des flags dans le code de test. Cette section présente l’approche en mémoire, qui permet de garder les tests hermétiques et hors ligne. Le fournisseur en mémoire est fourni dans le module go-sdk en amont sous github.com/open-feature/go-sdk/openfeature/memprovider, aucune dépendance supplémentaire n’est donc requise.
Enregistrez le fournisseur en mémoire sous un client nommé plutôt que sous le fournisseur global par défaut. Le fournisseur par défaut est global au processus, ce qui interrompt t.Parallel() et entraîne des fuites d’état des flags entre les tests. Un client nommé limite le fournisseur à chaque test.
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 est défini comme *func(...) — un pointeur vers une fonction. Définissez l’évaluateur dans une variable locale et transmettez son adresse avec &, comme indiqué ci-dessus. Omettez ContextEvaluator entièrement pour toujours renvoyer DefaultVariant.
Lectures complémentaires
Documentation, liens et articles supplémentaires utiles: