Après avoir activé le niveau du code métriques en suivant les étapes de configuration des métriques de l'Agent Go au niveau du code, vous pouvez affiner la façon dont vos métriques sont collectées à l'aide instrumentation supplémentaires.
transactions instrumentées
Avec le niveau de code métrique activé, l'agent Go ajoutera des informations de contexte de source de code à toute transaction démarrée par un appel à la méthode StartTransaction
de l'application. Sans modifier aucun de vos codes d'instrumentation existants, cela signifie que l'emplacement du code source sera ajouté en fonction de la fonction qui a appelé StartTransaction
. Ceci est vrai même si StartTransaction
est appelé pour vous par un package d'instrumentation.
Toutefois, si vous souhaitez exercer un contrôle manuel sur la manière dont les métriques du niveau de code sont collectées pour une transaction particulière, vous pouvez ajouter un certain nombre de fonctions newrelic.TraceOption
comme décrit ci-dessous :
Suppression du niveau du code métriques pour une seule transaction
Si vous ne voulez pas de métriques de niveau de code pour une transaction particulière (par exemple, pour éviter la surcharge liée à la collecte des informations lorsque vous savez que vous n'aurez pas besoin de ces données), ajoutez une fonction WithoutCodeLevelMetrics
à la fin de l'appel StartTransaction
:
txn := app.StartTransaction("nothing-here-to-see", newrelic.WithoutCodeLevelMetrics())defer txn.End()
Ajuster le préfixe du chemin d'accès au fichier
Par défaut, l'agent Go signalera les chemins d'accès complets (absolus) des fichiers sources référencés par les métriques de niveau de code. Le guide de configuration contient des informations sur la manière dont vous pouvez tronquer les chemins d'accès aux fichiers globalement pour démarrer à partir du nom de répertoire de votre choix via le paramètre ConfigCodeLevelMetricsPathPrefixes
, mais vous devrez peut-être spécifier un préfixe de chemin d'accès aux fichiers différent pour les transactions individuelles. Si tel est le cas, ajoutez simplement une option WithPathPrefixes
à la transaction :
txn := app.StartTransaction("mytransaction", newrelic.WithPathPrefixes("otherproject/lib/src"))defer txn.End()
Cela signifie que, pour cette transaction uniquement, un chemin d'accès au fichier source, par exemple "/usr/src/otherproject/lib/src/main.go"
, est raccourci en "otherproject/lib/src/main.go"
.
Si vous avez plusieurs préfixes de chemin que vous souhaitez utiliser, transmettez-les simplement comme paramètre supplémentaire à WithPathPrefixes
:
txn := app.StartTransaction("mytransaction", newrelic.WithPathPrefixes("otherproject/lib/src", "myproject/src"))defer txn.End()
Ajuster le préfixe ignoré de l'heuristique de reconnaissance de fonction
Par défaut, l'agent Go contient une logique permettant de sauter les fonctions de la stack d'appels qui sont internes à l'agent lui-même, afin d'arriver à celle que vous êtes instrumenté. Le guideconfiguration contient des informations sur la manière dont vous pouvez modifier globalement cette heuristique via le paramètre ConfigCodeLevelMetricsIgnoredPrefixes
, mais vous souhaiterez peut-être fournir un préfixe d'espace de nommage ignoré personnalisé pour une seule transaction. Vous pouvez le faire en ajoutant une option WithIgnoredPrefixes
à la transaction :
txn := app.StartTransaction("mytransaction", newrelic.WithIgnoredPrefixes("github.com/ignore/this/"))defer txn.End()
Vous pouvez spécifier plusieurs arguments de chaîne à WithIgnoredPrefixes
s'il existe plusieurs packages dont les fonctions doivent être ignorées :
txn := app.StartTransaction("mytransaction", newrelic.WithIgnoredPrefixes("github.com/ignore/this/", "github.com/ignore/that/"))defer txn.End()
Avec ce changement, toutes les fonctions d'un package dont le nom commence par github.com/ignore/this/
(ou github.com/ignore/that/
dans le deuxième exemple) seront ignorées pour trouver la fonction instrumentée.
Marquer explicitement l'emplacement du code
Pour faciliter l'identification du point d'intérêt à signaler, ajoutez WithThisCodeLocation
à la fin de l'appel StartTransaction
(par exemple, si la transaction est réellement démarrée dans un autre framework). Cela forcera les métriques du niveau du code à signaler l'emplacement dans la source du code où WithThisCodeLocation
a été invoqué.
txn := app.StartTransaction("mytransaction", newrelic.WithThisCodeLocation())defer txn.End()
Marquer explicitement n’importe quel emplacement de code
Vous pouvez également contrôler entièrement l’emplacement dans votre code source à associer à une transaction. Essentiellement, vous pouvez marquer n'importe quel emplacement en appelant ThisCodeLocation
pour obtenir un « marqueur » pour cet emplacement. Ensuite, utilisez ce marqueur enregistré avec l'option WithCodeLocation
pour un appel StartTransaction
:
here := newrelic.ThisCodeLocation()...txn := app.StartTransaction("mytransaction", newrelic.WithCodeLocation(here))defer txn.End()
Si nécessaire, vous pouvez demander à ThisCodeLocation
d'ignorer un certain nombre de fonctions d'appel afin que l'emplacement signalé soit plus haut dans la stack d'appels. Par exemple, pour ignorer 1 appelant, de sorte que here
fasse référence à l'appelant de la fonction qui appelle ThisCodeLocation
, modifiez l'exemple ci-dessus en :
here := newrelic.ThisCodeLocation(1)...txn := app.StartTransaction("mytransaction", newrelic.WithCodeLocation(here))defer txn.End()
Marquer explicitement l'emplacement du code en fonction d'une valeur de fonction
Si le code que vous souhaitez instrumenter est disponible sous forme de valeur de type func
, comme le nom d'une fonction ou une valeur littérale de fonction, vous pouvez le spécifier comme emplacement pour le rapport des métriques du niveau de code en ajoutant une option WithFunctionLocation
à StartTransaction
, en passant la valeur func
comme paramètre :
func myfunction() { ... }...txn := app.StartTransaction("myfunction", newrelic.WithFunctionLocation(myfunction))
ou
someFunction := func() {...}...txn := app.StartTransaction("myfunction", newrelic.WithFunctionLocation(someFunction))
Vous pouvez également obtenir une valeur CodeLocation
à partir d'une valeur func
pour une utilisation ultérieure avec l'option WithCodeLocation
. Comparez ceci à l'utilisation indiquée ci-dessus pour enregistrer un emplacement de code avec ThisCodeLocation
pour référence ultérieure avec WithCodeLocation
. Cette fois, nous faisons la même chose mais avec une valeur func
à la place :
func myFunc() {...}...locationOfMyFunc, err := newrelic.FunctionLocation(myFunc)if err != nil { // handle the case that the location could not be determined // from the value passed to FunctionLocation.}...txn := app.StartTransaction("mytransaction", newrelic.WithCodeLocation(locationOfMyFunc))
Notez que FunctionLocation
renvoie une erreur si la valeur qui lui est transmise n'était pas une fonction valide ou si l'emplacement du code source n'a pas pu être obtenu à partir de celle-ci. En revanche, l'option WithFunctionLocation
définit le niveau du code métrique en fonction de la valeur transmise si possible, mais ne fait rien en silence si une erreur se produit.
Ajout d'options personnalisées aux gestionnaires encapsulés
Les mêmes options décrites ci-dessus qui peuvent être ajoutées à la fin de StartTransaction
peuvent également être ajoutées à WrapHandle
et WrapHandleFunc
pour ajuster le niveau de collecte des codes métriques associés aux transactions démarrées par eux, si vous le souhaitez (bien que dans la plupart des cas, les fonctions WrapHandle
et WrapHandleFunc
identifieront correctement l'emplacement du code instrumenté). Par exemple:
http.HandleFunc(newrelic.WrapHandleFunc(app, "/endpoint", endpointFunction, newrelic.WithThisCodeLocation()))
Modification des options trace après le début d'une transaction
Parfois, vous n'avez pas le luxe de connaître l'emplacement du code jusqu'à ce que la transaction ait déjà été démarrée (peut-être par un framework ou une fonction d'intégration en votre nom). Vous pouvez modifier les options de transaction sur une transaction existante en appelant sa méthode SetOption
. Les paramètres sont un ensemble de fonctions TraceOption
telles que décrites ci-dessus. Par exemple:
txn := newrelic.FromContext(r.context)txn.SetOption(newrelic.WithThisCodeLocation())
Améliorer les performances avec les fonctions de niveau du code métriques mises en cache
Souvent, le moyen le plus pratique d'instrumenter une transaction avec des métriques de niveau de code est d'appeler newrelic.WithThisCodeLocation()
(ou une fonction similaire à celle décrite ci-dessus) à l'intérieur de la fonction instrumentée. Cependant, si cette fonction doit être appelée plusieurs fois au cours de l'exécution de votre application, il serait préférable d'éviter la surcharge liée au calcul répété de l'emplacement du code source. Cela est particulièrement vrai si le code de transaction doit être exécuté simultanément dans plusieurs goroutines.
Pour atténuer ce problème, l’agent Go fournit des versions de mise en cache de plusieurs de ces fonctions. Ils fonctionnent de la même manière que leurs homologues non mis en cache, sauf qu'ils ne font que déterminer l'emplacement du code source la première fois qu'ils sont appelés, puis réutilisent simplement cette valeur à chaque fois suivante.
Pour utiliser cette fonctionnalité, vous devez créer une variable de stockage de cache en appelant NewCachedCodeLocation()
et la placer là où elle persistera entre les exécutions de la transaction instrumentée. Cette variable contiendra la valeur mise en cache pour cet emplacement de code. Utilisez ensuite simplement les méthodes FunctionLocation(functionValue)
ou ThisCodeLocation()
comme vous utiliseriez les fonctions autonomes du même nom, mais dans ce cas, ce sont des méthodes de votre variable CachedCodeLocation
. Ces méthodes sont thread-safe, vous pouvez donc les utiliser dans des goroutines simultanées sans leur ajouter de contrôles de simultanéité supplémentaires.
Par exemple, dans ce code, nous configurons une variable de cache qui est utilisée dans la fermeture assignée à la variable myFunc
.
cache := newrelic.NewCachedCodeLocation()
myFunc := func() { txn := app.StartTransaction("mytransaction", cache.WithThisCodeLocation()) defer txn.End() // go on to perform the transaction}
(Cet exemple suppose que app
est la valeur Application
de agent créée au démarrage de l'agent et est visible dans cet snippet de code.)
Nous pouvons maintenant appeler la fonction myFunc
plusieurs fois. Chaque invocation (éventuellement simultanée) de myFunc
a une référence à la variable cache
. La première invocation pour exécuter cache.WithThisCodeLocation()
calculera l'emplacement de la source du code à ce stade et le stockera dans la variable cache
. Les exécutions ultérieures de myFunc
réutiliseront la valeur précédemment stockée dans cache
.
Notez que vous devez utiliser une variable de cache différente pour chaque emplacement de code que vous souhaitez utiliser, car le but est d'évaluer cet emplacement une seule fois, puis d'utiliser la valeur mise en cache à partir de là. La variable de cache n'est pas destinée à être copiée ou utilisée autrement que comme documenté ici et dans la documentation du package du module.
Veuillez vous référer à la documentation complète du package de modules Go pour plus de détails sur toutes les fonctions et méthodes de métriques au niveau du code mis en cache que vous pouvez utiliser.