Go Collecteur : FAQ sur les opérations courantes
Vous trouverez dans les sections suivantes des informations sur les opérations courantes du collecteur « Go » :
Configuration
Nous répondons ici à quelques questions courantes concernant la configuration du collecteur « Go ».
Général
Les sections suivantes traitent des questions générales relatives à la configuration du collecteur d' Go s :
Comment initialiser Go Collector ?
Pour initialiser le collecteur d' Go s, appelez instana.InitSensor() au début de votre main() fonction en lui fournissant un objet *instana.Options de configuration :
import instana "github.com/instana/go-sensor"
func main() {
instana.InitSensor(&instana.Options{
// ...
})
// ...
}
Le collecteur « Go » utilise les valeurs de instana.DefaultOptions() pour les champs non initialisés de l'objet de configuration fourni à la instana.InitSensor() fonction.
Comment intégrer un collecteur d' Go s dans une sonde de disponibilité?
Pour vous assurer que le collecteur d' Go s a terminé le processus d'annonce et qu'il est prêt à collecter les traces avant d'envoyer le trafic vers une instance, utilisez la instana.Ready() méthode :
// Every 100ms whether Go Collector is ready and return on success
func awaitInstanaReady(ctx context.Context) error {
ticker := time.NewTicker(100*time.Millisecond)
defer ticker.Stop()
for {
select {
case <-ticker.C:
if instana.Ready() {
return nil
}
case <-ctx.Done():
return ctx.Err()
}
}
return nil
}
Comment s'assurer que toutes les données de suivi ont bien été envoyées avant l'arrêt du système?
Pour s'assurer que toutes les traces collectées ont bien été envoyées à l'agent hôte ou à l'acceptateur sans serveur, le collecteur Go API propose la instana.Flush() méthode. Cette méthode force le client de l'agent à envoyer immédiatement toutes les données mises en mémoire tampon. Il s'agit d'une opération bloquante, et il est recommandé de définir un délai d'attente ou une échéance pour cette opération, afin que votre service puisse se fermer correctement:
func main() {
var srv http.Server
// Initialize and use http.Server
// ...
// Server shutdown sequence:
// 1. Finalize all pending requests and close the server
shutdownCtx, _ := context.WithTimeout(ctx, 5 * time.Second)
if err := srv.Shutdown(shutdownCtx); err != nil {
// ...
}
// 2. Flush all buffered traces to the agent
flushCtx, _ := context.WithTimeout(ctx, 5 * time.Second)
if err := instana.Flush(flushCtx); err != nil {
// ...
}
// ...
}
Lorsqu'un service est exécuté sur AWS Lambda, instana.Flush() il est automatiquement appelé par le collecteur Go une fois que le gestionnaire a terminé son travail; il n'est donc pas nécessaire de le faire manuellement.
instana.Flush() cela peut perturber le cycle de transmission des données du collecteur d' Go s; il n'est donc pas recommandé de l'utiliser, car cela affecterait la transmission des données de trace pendant la durée de vie du service, par exemple à la fin du traitement d'une requête HTTP. Il n'y a aucune garantie que le collecteur Go continue de fonctionner après l'appel de cette méthode.Comment configurer Go Collector pour qu'il s'exécute dans un environnement sans serveur ?
Pour utiliser Go Collector pour contrôler un service exécuté dans un environnement sans serveur, tel que Fargate AWS ou Google Cloud Run, veillez à ce que les variables d'environnement INSTANA_ENDPOINT_URL et INSTANA_AGENT_KEY soient définies dans votre définition de tâche. Pour plus d'informations sur cette procédure, reportez-vous à la section correspondante de la documentation Instana :
- Configuration des définitions de tâches d' AWS Fargate
- Configuration des fonctions d' AWS Lambda
- Configuration des services d' Google Cloud Run
INSTANA_AGENT_HOSTINSTANA_AGENT_PORT et seront ignorées lorsqu'une application s'exécute en mode sans serveur.Les services exécutés dans des environnements sans serveur n'utilisent pas d'agent hôte pour envoyer les métriques et les données de traçage au backend d' Instana; par conséquent, la méthode habituelle de configuration du collecteur intégré via configuration.yaml un fichier n'est pas applicable. À la place, il existe un ensemble de variables d'environnement qui peuvent éventuellement être configurées dans la définition de tâche de service :
| Variable d"environnement | Valeur par défaut | Description |
|---|---|---|
INSTANA_TIMEOUT |
500 |
Délai d'attente de connexion sur serveur Instana (en millisecondes) |
INSTANA_SECRETS |
contains-ignore-case:secret,key,password |
Le filtre de secrets ; également appliqué aux variables d'environnement de processus) |
INSTANA_EXTRA_HTTP_HEADERS |
aucun | Liste d'en-têtes HTTP séparés par un point-virgule à collecter à partir des demandes entrantes |
INSTANA_ENDPOINT_PROXY |
aucun | URL de proxy à utiliser pour se connecter au serveur Instana |
INSTANA_TAGS |
aucun | Liste de balises séparées par une virgule avec des valeurs facultatives à associer à la tâche ECS |
INSTANA_ZONE |
<Current AWS availability zone> |
Un nom de zone Instana personnalisé pour ce service |
Pour une description plus détaillée de ces variables et de leur format de valeur, veuillez consulter la documentation disponible à l'adresse Instana.
Comment configurer Go Collector pour expurger les données sensibles ?
Certains encapsuleurs d'instrumentation fournis par Instana, par exemple les encapsuleurs de serveur et de client HTTP, collectent des données qui peuvent contenir des informations sensibles, comme des mots de passe, des clés et des secrets. Pour éviter toute fuite de ces valeurs, le collecteur d' Go s les remplace par <redacted> avant de les envoyer à l'agent. La liste des correspondances de noms de paramètres est définie dans com.instana.secrets la section du fichier de configuration del'agent hôte et sera transmise au traceur intégré à l'application pendant la phase d'annonce (nécessite le plugin de traçage de l'agent Gocom.instana.sensor-golang-trace v1.3.0 ou une version ultérieure).
Le paramètre par défaut du comparateur de secrets est contains-ignore-case avec la liste de termes suivante: key, password, secret. Cela occulterait la valeur d'un paramètre dont le nom contient l'une de ces chaînes en ignorant la casse.
Comment collecter des en-têtes d' HTTP s supplémentaires?
Les wrappers d'instrumentation d' HTTP s peuvent collecter les en-têtes d' HTTP s et les envoyer avec les segments de requêtes entrantes ou sortantes. La liste des noms d'en-tête insensibles à la casse peut être fournie à la fois dans (instana.Options).Tracer.CollectableHTTPHeaders champ de l'objet d'options qui est transmis à instana.InitSensor() et dans le fichier de configuration de l'agent hôte. Ce dernier paramètre prévaut et nécessite le plugin de traçage de l'agent Go com.instana.sensor-golang-tracev1.3.0 ou une version ultérieure :
instana.InitSensor(&instana.Options{
// ...
Tracer: instana.TracerOptions{
// ...
CollectableHTTPHeaders: []string{"x-request-id", "x-loadtest-id"},
},
})
Cette configuration correspond aux paramètres suivants dans le fichier de configuration de l'agent hôte :
com.instana.tracing:
extra-http-headers:
- 'x-request-id'
- 'x-loadtest-id'
Par défaut, l'instrumentation HTTP ne collecte aucun en-tête.
Journalisation
Le collecteur « Go » utilise un enregistreur à niveaux pour consigner les erreurs internes et les informations de diagnostic. Le github.com/instana/go-sensor/logger.Logger par défaut utilise log.Logger configuré avec log.Lstdflags comme système de back end et écrit des messages dans os.Stderr.
Comment utiliser un gestionnaire de journalisation tiers pour afficher les journaux de Go Collector ?
Vous pouvez configurer le collecteur d' Go s pour qu'il utilise un enregistreur tiers conforme à instana.LeveledLogger l'interface. Par exemple, pour github.com/sirupsen/logrus ou go.uber.org/zap , utilisez la méthode [ instana.SetLogger()][ instana.SetLogger ] :
import (
"github.com/uber-go/zap"
instana "github.com/instana/go-sensor"
)
func main() {
logger, _ := zap.NewProduction()
defer logger.Sync()
instana.SetLogger(logger)
}
INSTANA_DEBUG d'environnement n'a aucun effet lorsque l'on utilise un outil de journalisation tiers. Veuillez consulter la documentation de votre module gestionnaire de journaux tiers pour savoir comment définir le niveau de débogage via une variable d'environnement ou un fichier de configuration.Comment activer les journaux de débogage pour Go Collector sans modifier le code de l'application ?
Pour permettre à Go Collector d'écrire des journaux de débogage sans modifier le code de l'application, affectez à la variable d'environnement INSTANA_DEBUG une valeur non vide, par exemple :
export INSTANA_DEBUG=true
./your-app
La quantité de journaux de débogage que Go Collector produit dépend de votre application et peut être significative. Nous vous recommandons d'activer temporairement les journaux de débogage afin de recueillir des informations avant de signaler un problème au service d'assistance d' Instana.
logger.Logger pour générer des messages de journalisation internes, et il remplace toute tentative de modification du niveau de journalisation depuis le code de l'application.Comment récupérer les erreurs et les avertissements consignés liés à des appels incorrects?
Instana Go Collector propose une interface d'instrumentation permettant github.com/sirupsen/logrus de collecter et d'envoyer automatiquement les enregistrements des journaux d'erreurs et d'avertissements à l'agent. github.com/instana/go-sensor/instrumentation/instalogrus fournit une implémentation de logrus.Hook qui traite tous les enregistrements d'erreur ou d'avertissement et les associe à la portée indiquée dans l'enregistrement context.Context. Voici un exemple expliquant comment instrumenter le logrus.Loggerglobal et l'utiliser à l'intérieur de http.Handlerinstrumenté:
func main() {
// ...
// Register instalogrus hook within the global logger
logrus.AddHook(instalogrus.NewHook(sensor))
}
func myMethod(w http.ResponseWriter, req *http.Request) {
// ...
// When logging an error, make sure to provide the context.Context containing
// an active span, so that instrumentation hook could associate this message
// with a call.
logrus.WithContext(req.Context()).Error("something went wrong")
// ...
}
Pour des exemples plus détaillés, consultez la documentation du package.
Instana AutoProfile™
Instana AutoProfile™ génère et transmet des profils de processus à Instana. Contrairement aux profileurs de développement et aux profileurs à la demande, où l'utilisateur doit lancer manuellement le profilage, il planifie automatiquement et exécute en continu le profilage correspondant aux environnements de production critiques.
Comment activer en permanence le profilage continu à partir du code de l'application ?
Pour activer de manière permanente le profilage continu pour votre service, fournissez EnableAutoProfile: true lors de l'initialisation du détecteur :
func main() {
instana.InitSensor(&instana.Options{
EnableAutoProfile: true,
// ... other options
})
// ...
}
Comment activer/désactiver temporairement le profilage à partir du code de l'application ?
Pour activer ou désactiver temporairement AutoProfile™ à partir de votre code, appelez autoprofile.Enable() et autoprofile.Disable() :
func expensiveCalculation() {
autoprofile.Enable()
defer autoprofile.Disable()
// ...
}
Comment activer le profilage continu sans modifier le code de l'application ?
Pour activer la fonctionnalité « AutoProfile™ » pour une application sans modifier le code, définissez la INSTANA_AUTO_PROFILE=true variable d'environnement suivante :
export INSTANA_AUTO_PROFILE=true
./your-app
INSTANA_DEBUG , cette valeur a la priorité et remplace toute tentative de désactivation du profilage depuis le code de l'application.Instrumentation
Votre code d'application nécessite des modifications pour collecter et envoyer les données de traçage à Instana. Ce processus s'appelle l'instrumentation du code.
Go Collector offre deux options pour instrumenter le code :
- Utilisation des encapsuleurs de code fournis. C'est la façon la plus simple d'utiliser votre code qui nécessite très peu de changements. Instana vise à fournir des modules d'instrumentation pour les bibliothèques tierces les plus courantes, telles que les pilotes de bases de données, les frameworks d' HTTP, etc. Si vous utilisez une bibliothèque qui ne dispose pas encore d'un module d'instrumentation correspondant, pensez à soumettre une demande de fonctionnalité via la rub rique « Soumettre une idée » du site Instana.
- En utilisant l'outil « OpenTracing » API. Une approche de plus bas niveau qui peut nécessiter des modifications substantielles de votre code de base. Cependant, elle offre également une grande flexibilité lorsqu'il s'agit d'instrumenter vos parties de code spécifiques à l'entreprise.
Veuillez noter qu'Instana utilise un ensemble très spécifique de balises span pour garantir une corrélation et une représentation correctes des appels dans l'infrastructure. Préférez l'approche des encapsuleurs de code fournis plutôt que l'API OpenTracing pour tirer le meilleur parti de vos données de traçage. Si nécessaire, vous pouvez envisager de combiner les encapsuleurs de code avec l'approche de bas niveau, afin de tirer parti du code déjà existant et géré, tout en restant flexible pour instrumenter vos parties de code spécifiques à l'entreprise.
Services HTTP
Go Collector fournit l'instrumentation pour les clients et les serveurs qui utilisent le package net/http. Une fois activée (voir ci-dessous), cette solution de surveillance recueille automatiquement des informations sur les requêtes entrantes et sortantes et les transmet à l'agent Instana.
Les modules d'instrumentation destinés aux frameworks d' HTTP s tiers sont fournis sous forme de modules Go distincts et offrent un moyen plus pratique d'instrumenter un service d' HTTP.
Comment instrumenter un gestionnaire de serveur HTTP ?
Avec la prise en charge de l'encapsulage d'un http.HandlerFunc, Instana ajoute rapidement la possibilité de tracer les demandes et de collecter les span enfants, exécutés dans le contexte du span de demande.
Des modifications minimales sont nécessaires pour qu'Instana puisse capturer les informations nécessaires. En encapsulant simplement le fichier http.HandlerFunc actuellement existant, Instana collecte et injecte automatiquement les informations nécessaires.
Cela dit, une simple fonction de gestionnaire comme celle qui suit sera simplement encapsulée et enregistrée comme d'habitude.
L'exemple de code suivant montre comment instrumenter un gestionnaire HTTP à l'aide de instana.TracingHandlerFunc() :
sensor := instana.NewSensor("my-http-server")
http.HandleFunc("/", instana.TracingHandlerFunc(sensor, "/", func(w http.ResponseWriter, req *http.Request) {
// ...
}))
Si votre gestionnaire est implémenté en tant que http.Handler, transmettez sa méthode ServeHTTP à la place :
h := http.FileServer(http.Dir("./"))
http.HandleFunc("/files", instana.TracingHandlerFunc(sensor, "index", h.ServeHTTP))
Consultez le example/http-database-greeter pour voir l'exemple complet.
Comment instrumenter un client HTTP ?
La demande de données ou d'informations auprès d'autres systèmes, souvent externes, se fait généralement par le biais de demandes HTTP. Pour s'assurer que les traces contiennent tous les spans, en particulier sur tous les différents systèmes, certaines informations sur les spans doivent être injectées dans les en-têtes de la demande HTTP avant de l'envoyer. L'outil « Go Collector » de Instana permet d'automatiser ce processus autant que possible.
Pour qu'Instana injecte des informations dans les en-têtes de demande, créez http.Client, encapsulez-le dans Transport avec instana.RoundTripper() et utilisez-le comme dans l'exemple suivant.
req, err := http.NewRequest("GET", url, nil)
client := &http.Client{
Transport: instana.RoundTripper(sensor, nil),
}
ctx := instana.ContextWithSpan(context.Background(), parentSpan)
resp, err := client.Do(req.WithContext(ctx))
L'objet fourni parentSpan correspond à la requête entrante provenant du gestionnaire de requêtes (voir l'exemple précédent) et contient les informations de traçage et de span nécessaires pour créer un span enfant et l'injecter dans la requête.
Clients de base de données
Le collecteur « Go » fournit instana.InstrumentSQLDriver() et instana.WrapSQLConnector() (depuis Go v1.10+ ) pour instrumenter les appels à la base de données SQL effectués avec database/sql. Le traceur capture ensuite automatiquement les appels Query et Exec, collecte les informations sur la demande, telles que l'instruction, le temps d'exécution, etc. et les envoie pour les afficher dans la trace.
Pour instrumenter un client de base de données noSQL, tel que MongoDB, vérifiez s'il existe un module d'instrumentation fourni pour votre pilote.
Comment instrumenter une connexion de base de données créée avec sql.Open() ?
Pour instrumenter un pilote de base de données, enregistrez-le d'abord à l'aide de instana.InstrumentSQLDriver() et remplacez l'appel à sql.Open() par instana.SQLOpen(). Voici un exemple de procédure à effectuer pour le pilote PostgreSQL github.com/lib/pq :
// Create a new instana.Sensor instance
sensor := instana.NewSensor("my-database-app")
// Instrument the driver
instana.InstrumentSQLDriver(sensor, "postgres", &pq.Driver{})
// Create an instance of *sql.DB to use for database queries
db, err := instana.SQLOpen("postgres", "postgres://...")
Le pilote instrumenté est enregistré sous le nom <original_name>_with_instana, par exemple, dans l'exemple précédent, le nom serait postgres_with_instana.
Consultez le example/http-database-greeter pour voir l'exemple complet.
Comment instrumenter un client de base de données créé avec sql.OpenDB() ?
À partir de Go v1.10 database/sql fournit une nouvelle façon d'initialiser *sql.DB qui ne nécessite pas l'utilisation du registre de pilotes global. Si la bibliothèque de pilotes de base de données fournit un type qui satisfait à l'interface database/sql/driver.Connector, elle peut être utilisée pour créer une connexion de base de données.
Pour instrumenter une instance de driver.Connector, encapsulez-la à l'aide de instana.WrapSQLConnector(). Voici un exemple de ce que vous pouvez faire pour le pilote MySQL github.com/go-sql-driver/mysql/ :
// Create a new instana.Sensor instance
sensor := instana.NewSensor("my-database-app")
// Initialize a new connector
connector, err := mysql.NewConnector(cfg)
// ...
// Wrap the connector before passing it to sql.OpenDB()
db, err := sql.OpenDB(instana.WrapSQLConnector(sensor, "mysql://...", connector))
Comment instrumenter un client MongoDB?
Le github.com/instana/go-sensor/instrumentation/instamongo module fournit des méthodes de construction qui créent une nouvelle instance de go.mongodb.org/mongo-driver `client` et l'équipent d'un ` Instana `.
Consultez la documentation du module pour obtenir des exemples détaillés et des instructions d'utilisation.
Comment instrumenter un client Redis?
Le
github.com/instana/go-sensor/instrumentation/instaredismodule fournit des wrappers de fonction pourgo-rediscet instrument, une instance deredis.Clientou deredis.ClusterClient, en ajoutant des hooks au client redis.Consultez la documentation du module pour obtenir des exemples détaillés et des instructions d'utilisation.
Le
github.com/instana/go-sensor/instrumentation/instaredigomodule fournit des wrappers pourredigocet instrument, ainsi qu'une instance deredis.Conn.Consultez la documentation du module pour obtenir des exemples détaillés et des instructions d'utilisation.
Services gRPC
Ce github.com/instana/go-sensor/instrumentation/instagrpc module fournit des intercepteurs unaires et de flux permettant d'instrumenter les serveurs et les clients d' gRPC s qui utilisent google.golang.org/grpc .
Comment utiliser un serveur gRPC ?
Ce github.com/instana/go-sensor/instrumentation/instagrpc module fournit à la fois des intercepteurs de flux et des intercepteurs de fonction unaire. La documentation dumodule fournit des explications détaillées sur la manière de l'utiliser pour instrumenter un serveur gRPC implémenté avec google.golang.org/grpc .
Consultez le example/grpc-client-server pour voir l'exemple complet.
Comment utiliser un client gRPC ?
Ce github.com/instana/go-sensor/instrumentation/instagrpc module fournit à la fois des intercepteurs de flux et des intercepteurs de fonction unaire. La documentation dumodule fournit des explications détaillées sur la manière de l'utiliser pour instrumenter un client gRPC implémenté avec google.golang.org/grpc .
Consultez le example/grpc-client-server pour voir l'exemple complet.
Services de messagerie
Comment implémenter un modèle producteur/consommateur de type « Kafka »?
Le github.com/instana/go-sensor/instrumentation/instasarama module fournit des méthodes de construction qui permettent de créer une nouvelle instance de clients producteur/consommateur et de l'instrumenter à l'aide d' Instana.
Consultez le example/kafka-producer-consumer pour voir l'exemple complet.
Comment implémenter un modèle producteur/consommateur de type « RabbitMQ »?
Le github.com/instana/go-sensor/instrumentation/instaamqp module propose une fonction d'encapsulation autour de amqp.Channel qui renvoie une instaamqp.AmqpChannel instance. Cet objet ` Instana ` fournit des fonctionnalités d'instrumentation pour les méthodes amqp.Channel.Publish amqp.Channel.Consume et qui permettent de suivre les données issues des messages envoyés et reçus.
Consultez l'exemple complet à l'adresse github.com/instana/go-sensor/blob/main/instrumentation/instaamqp .
Renommer un service
Pour modifier le nom du service d'un appel dans Instana, ajoutez la service balise à son élément span, comme indiqué dans l'exemple suivant :
span.SetTag("service", "name")
Instrumentation manuelle avec API OpenTracing
Instana Go Collector offre une interface compatible avec github.com/opentracing/opentracing-go , et peut donc être utilisé comme traceur global. Il est toutefois recommandé d'utiliser les wrappers de code fournis par Instana. Ils ont défini de nombreuses informations sémantiques, ce qui permet à Instana d'avoir une vision aussi précise que possible de l'application. L'envoi de balises appropriées est particulièrement important lorsque vous corrélez des appels à l'infrastructure. En effet, la plupart des balises sont des chaînes et vous pouvez donc faire des erreurs.
Comment utiliser une méthode ?
Une instrumentation minimale d'une méthode avec Go Collector s'effectue en deux étapes :
- Commencez une nouvelle ligne avec
instana.Sensor. - Finalisez l'intervalle avant que la méthode ne soit renvoyée.
Les étapes facultatives incluent la collecte des détails relatifs à cet appel pour les associer à l'intervalle actif et l'injection de l'intervalle actif dans context.Context afin de garantir la continuation de la trace.
func MyMethod(sensor *instana.Sensor) {
// Start a new span associated with this method execution
span := sensor.Tracer().StartSpan("my-method")
// Schedule span finalization to send it to Instana agent
defer span.Finish()
// Optionally attach any relevant information that would help you to identify this call later
span.SetTag("key1", "value1")
span.SetTag("answer", 42)
// ...
}
Consultez le example/opentracing pour un exemple plus détaillé.
Comment poursuivre la trace à l'intérieur d'un sous-appel ?
Pour associer un sous-appel à un intervalle actif, fournissez son contexte via l'option de début d'intervalle opentracing.ChildOf() lors du démarrage de l'intervalle de sous-appel:
var spanOpts []opentracing.StartSpanOption
// Check whether there is an active trace by fetching the currently active span from context
if parent, ok := instana.SpanFromContext(ctx); ok {
spanOpts = append(spanOpts, opentracing.ChildOf(parent.Context()))
}
// Start the subcall span
span := tracer.StartSpan("my-func", spanOpts...)
Il incombe à l'appelant de s'assurer que l'instance de context.Context fournie au destinataire contient la portée active dans laquelle a instana.ContextWithSpan() été injecté :
// And inject it into context, so any subcalls could use it as a parent
SubCall(instana.ContextWithSpan(ctx, span))
Comment obtenir le scan a portéeparent à l'intérieur de la méthode encapsulée ?
Les wrappers de code fournis par Instana utilisent context.Context pour intégrer la balise span parente dans un sous-appel. En d'autres termes, à l'intérieur d'une fonction de gestionnaire ou de rappel instrumentée, vous pouvez partir du principe que instana.SpanFromContext() renvoie la plage lancée par la méthode d'encapsulation :
parentSpan, ok := instana.SpanFromContext(ctx)
context.Context à la méthode du gestionnaire, le code de l'encapsuleur peut utiliser d'autres méthodes pour injecter le contexte du span actif. Consultez la documentation du module d'encapsuleur correspondant pour savoir comment obtenir le contexte du span parent dans ce cas.