Surveillance de Haskell

Découvrez l' Haskell de surveillance.

La prise en charge par Instana de la surveillance et du traçage des applications Haskell est documentée en détail sur la page GitHub du Trace SDK, accessible à l'adresse InstanaHaskell. Sa documentation sur API est disponible sur Hackage.

SDK Haskell Trace : ce qu'il est et ce qu'il n'est pas

Le kit SDK Instana Haskell Trace ne prend pas en charge l'instrumentation et le traçage automatiques à l'instar de la plupart des autres langages que nous prenons en charge. Au contraire, le SDK vous permet de créer manuellement des segments, à l'instar du SDK de traçage d' Instana pour Java. En plus d'offrir une API pratique pour créer des étendues, le kit SDK Haskell Trace prend également soin d'établir une connexion à l'agent Instana et d'envoyer des étendues à l'agent de façon efficace, sans incidence négative sur les performances de notre code en production. Dernier point, mais non le moindre, il collecte des métriques d'exécution et les communique à Instana.

Installation

Pour utiliser le kit SDK Instana Haskell Trace dans votre application, ajoutez instana-haskell-trace-sdk à vos dépendances (par exemple, dans la section build-depends de votre fichier Cabal). Si vous utilisez une pile , vous devrez peut-être ajouter le SDK (avec le numéro de version que vous souhaitez utiliser) à la section extra-deps dans votre fichier stack.yaml :

extra-deps:
- instana-haskell-trace-sdk-0.7.0.0

Selon le résolveur de pile que vous utilisez, vous devrez peut-être également ajouter aeson-extra à vos dépendances supplémentaires :

- aeson-extra-0.4.1.3@sha256:8ad8e4d28e46280ea98af2e94dcaaf524c396c9d91b1eba867961efc6e7f923f,2997

Utilisation

Exemple d'application : jetez un œil à Monad Shop pour découvrir le SDK de traçage Instana Haskell en action.

Initialisation

Avant d'utiliser le kit SDK, vous devez l'initialiser une fois, en principe au démarrage de l'application.

import qualified Instana.SDK.SDK as InstanaSDK

main :: IO ()
main = do
  -- ... initialize things ...

  -- initialize Instana
  instana <- InstanaSDK.initInstana

  -- ... initialize more things

La valeur instana :: Instana.SDK.InstanaContext renvoyée par InstanaSDK.initInstana est requise pour tous les appels supplémentaires, c'est-à-dire pour la création des étendues qui seront envoyées à l'agent. Le kit SDK va essayer de se connecter à un agent (en mode asynchrone, dans une unité d'exécution distincte) dès réception de l'appel initInstana.

Le kit SDK peut être configuré via des variables d'environnement et/ou directement dans le code en transmettant les paramètres de configuration à la fonction d'initialisation.

Si vous souhaitez transmettre des paramètres de configuration par programmation, utilisez initConfiguredInstana au lieu de initInstana :

import qualified Instana.SDK.SDK as InstanaSDK

main :: IO ()
main = do

  -- Example snippet for using the Instana SDK and providing a configuration
  -- (agent host, port, ...) directly in code. You only need to specify the
  -- configuration values you are interested in and can omit everything else
  -- (see https://www.yesodweb.com/book/settings-types).
  let
    config =
      InstanaSDK.defaultConfig
        { InstanaSDK.agentHost = Just "127.0.0.1"
        , InstanaSDK.agentPort = Just 42699
        , InstanaSDK.serviceName = Just "A Great Hakell Service"
        , InstanaSDK.forceTransmissionAfter = Just 1000
        , InstanaSDK.forceTransmissionStartingAt = Just 500
        , InstanaSDK.maxBufferedSpans = Just 1000
        }
  instana <- InstanaSDK.initConfiguredInstana config

Pour les paramètres de configuration qui sont omis lors de la création de l'enregistrement de configuration ou qui sont définis sur Nothing, le SDK se retrouvera dans les variables d'environnement (voir ci-dessous), puis dans les valeurs par défaut.

Il existe également des variantes de style crochet de la fonction d'initialisation, appelées withInstana et withConfiguredInstana:

import qualified Instana.SDK.SDK as InstanaSDK

main :: IO ()
main = do
  InstanaSDK.withInstana runApp

runApp :: InstanaContext -> IO ()
runApp instana = do
  -- do your thing here :-)

ou, avec un style de support et un enregistrement de configuration :

import qualified Instana.SDK.SDK as InstanaSDK

main :: IO ()
main = do
  let
    config =
      InstanaSDK.defaultConfig
        { InstanaSDK.agentHost = Just "127.0.0.1"
        , InstanaSDK.agentPort = Just 42699
        , InstanaSDK.serviceName = Just "A Great Hakell Service"
        , InstanaSDK.forceTransmissionAfter = Just 1000
        , InstanaSDK.forceTransmissionStartingAt = Just 500
        , InstanaSDK.maxBufferedSpans = Just 1000
        }

  InstanaSDK.withConfiguredInstana config runApp

runApp :: InstanaContext -> IO ()
runApp instana = do
  -- do your thing here :-)

Création d'étendues

Traçage des entrées HTTP automatiquement

Vous pouvez laisser le SDK créer automatiquement des portées d'entrée pour toutes les requêtes HTTP entrantes dans une application WAI en l'utilisant comme plug-in middleware WAI. Les en-têtes de traçage Instana ainsi que les en-têtes de contexte de traçage du W3C sont automatiquement pris en compte par le plug-in. Notez que les plages d'exit doivent encore être créées manuellement via les fonctions withHttpExit ou startHttpExit/completeExit (voir ci-dessous).

Le plug-in middleware ajoutera également un en-tête de réponse HTTP supplémentaire (Server-Timing) aux réponses HTTP. Cet en-tête active la corrélation d'arrière-plan de surveillance de site Web.

import qualified Instana.Wai.Middleware.Entry as InstanaWaiMiddleware

main = do
  Warp.run 3000 $ InstanaWaiMiddleware.traceHttpEntries instana $ app

Style de fonction bracket (API de haut niveau)

Toutes les fonctions commençant par with acceptent (entre autres paramètres) une action d'E-S. Le kit SDK démarre une étendue avant, puis exécute l'action d'E-S indiquée avant de terminer l'étendue. L'utilisation de ce style est recommandée par rapport à l'API de bas niveau qui nécessite le démarrer et terminer vous-même les étendues.

  • withRootEntry : crée une étendue d'entrée qui est la racine d'une trace (sans étendue parent).
  • withEntry : crée une étendue d'entrée avec une portée parent.
  • withHttpEntry : fonction de commodité qui examine une requête HTTP entrante pour les en-têtes de traçage Instana ou les en-têtes de contexte de traçage W3C et crée une portée d'entrée. Il ajoutera automatiquement les métadonnées correctes à l'étendue. Notez que vous n'avez pas besoin de traiter les demandes HTTP entrantes du tout lors de l'utilisation du plug-in de middleware Instana WAI (voir ci-dessus).
  • withHttpEntry_: une variante de withHttpEntry avec une signature de type plus générale, mais moins de fonctions. Elle poursuivra automatiquement la trace à partir des en-têtes entrants (en-têtes Instana ou contexte de trace W3C ), tout comme withHttpEntry le fait [...], mais elle ne capturera pas le code d'état de la réponse HTTP ni n'ajoutera l'en-tête de réponse nécessaire à la corrélation du backend de surveillance du site web (Server-Timing). Il est recommandé d'utiliser withHttpEntry au lieu de cette fonction, si possible. Vous pouvez également appeler postProcessHttpResponse dans le bloc withHttpEntry_ pour couvrir les deux fonctions manquantes mentionnées ci-dessus. Notez que vous n'avez pas besoin de traiter les demandes HTTP entrantes du tout lors de l'utilisation du plug-in de middleware Instana WAI.
  • withExit : crée une étendue de sortie. Ce style ne peut être appelé qu'au sein d'un appel withRootEntry ou withEntry, car une étendue de sortie nécessite une étendue d'entrée en tant que parent.
  • withHttpExit : crée une étendue de sortie pour une demande client HTTP donnée. Il ajoutera automatiquement les métadonnées correctes à l'étendue afin d'être préféré à withExit lors du traçage des demandes HTTP sortantes. Il ajoutera également les en-têtes HTTP de traçage Instana ainsi que les en-têtes HTTP du contexte de traçage du W3C HTTP à la demande de propagation du contexte de traçage en aval.
  • postProcessHttpResponse : traite la réponse d'une entrée HTTP. Cette fonction doit être appelée alors que l'étendue d'entrée HTTP est toujours active. Il peut être utilisé dans un bloc withHttpEntry_ ou entre startHttpEntry et completeEntry. Cette fonction réalise deux choses : elle capture le code d'état HTTP de la réponse et l'ajoute sous forme d'annotation à l'étendue active. Cela ajoute également un en-tête de réponse supplémentaire « HTTP » (Server-Timing) à la réponse HTTP fournie, ce qui permet la corrélation avec le système de surveillance du site web. Le code client devrait rarement avoir la nécessité de l'appeler directement. Au lieu de cela, capturer les demandes HTTP entrantes avec withHttpEntry, ce qui fait automatiquement ces deux choses.
  • addAnnotation: ajoute une balise à l'étendue en cours.

API de bas niveau/Démarrage et fin explicites

  • startRootEntry : démarre une étendue d'entrée qui correspond au début d'une trace (sans étendue parent). Il vous faudra appeler completeEntry à moment donné.
  • startEntry : démarre une étendue d'entrée. Il vous faudra appeler completeEntry à moment donné.
  • startHttpEntry : démarre une étendue d'entrée pour une demande HTTP entrante. Il ajoutera automatiquement les métadonnées correctes à l'étendue. Il n'est pas nécessaire de traiter les demandes HTTP entrantes du tout lors de l'utilisation du plug-in middleware WAI (voir ci-dessus). Il vous faudra appeler completeEntry à moment donné.
  • startExit : démarre une étendue de sortie. Il vous faudra appeler completeExit à moment donné.
  • startHttpExit : démarre une étendue de sortie pour une demande HTTP sortante. Il ajoutera automatiquement les métadonnées correctes à l'étendue afin d'être préféré à startExit lors du traçage des demandes HTTP sortantes. Il ajoutera également des en-têtes HTTP à la requête pour propager le contexte de traçage en aval. Vous devrez appeler completeExit à un moment donné.
  • completeEntry : finalise une étendue d'entrée. Place l'étendue dans la mémoire tampon du kit SDK pour la transmettre à l'agent Instana.
  • completeExit : finalise une étendue de sortie. Place l'étendue dans la mémoire tampon du kit SDK pour la transmettre à l'agent Instana.

Meilleures pratiques

Assurez-vous d'avoir lu la documentation d' Instana sur le traçage personnalisé. Cette documentation contient de nombreuses informations utiles pour intégrer le traçage d' Instana dans votre code; elle explique notamment quelles métadonnées peuvent être ajoutées aux segments (via InstanaSDK.addTag et InstanaSDK.addTagAt).

Instana fait la différence entre les portées enregistrées et celles de SDK. Les portées enregistrées sont généralement créées par le traçage automatique et il existe une manipulation spécialisée pour chaque enregistrement enregistré dans le pipeline de traitement d'Instana. Les portées SDK, en revanche, sont le type de portées créées à l'aide d'un SDK de traçage (comme le SDK de traçage Haskell ou d'autres SDK similaires pour les autres plateformes d'exécution). La portée SDK est traitée de manière plus générique par le pipeline de traitement d'Instana.

Notez que presque toutes les portées créées avec ce SDK doivent être des portées SDK. Il ne s'agit que de deux exceptions, pour lesquelles ce SDK crée des portées enregistrées :

  • L'entrée HTTP/WAI (serveur) s'étend et
  • L'exit HTTP (client) s'étend.

Le SDK propose des fonctions spécifiques pour créer ces intervalles enregistrés (withHttpEntry, withHttpExit ainsi que les fonctions de bas niveau startHttpEntry correspondantes et startHttpExit, voir « Style des crochets » et « API de bas niveau »).

Configuration via les variables d'environnement

Au lieu de configurer le SDK par programmation, comme indiqué dans les sections précédentes, il est également possible de le configurer à l'aide de variables d'environnement :

  • INSTANA_AGENT_HOST : adresse IP ou hôte de l'agent Instana auquel se connecter. Valeur par défaut : 127.0.0.1.
  • INSTANA_AGENT_PORT: port de l'agent Instana auquel se connecter. Valeur par défaut : 42699.
  • INSTANA_SERVICE_NAME: remplacez le nom de service par défaut dans Instana.
  • INSTANA_FORCE_TRANSMISSION_STARTING_AFTER : les espaces sont généralement mis en mémoire tampon avant d'être transmis à l'agent. Ce paramètre force la transmission de toutes les portées en mémoire tampon après le nombre de millisecondes indiqué. Par défaut : 1 000.
  • INSTANA_FORCE_TRANSMISSION_STARTING_AT : ce paramètre force la transmission de toutes les portées en mémoire tampon lorsque le nombre de travées indiqué a été mis en mémoire tampon.
  • INSTANA_MAX_BUFFERED_SPANS : limite le nombre de portées à la mémoire tampon. Lorsque la limite est atteinte, les portées seront supprimées. Ce paramètre est un gardien sûr contre les fuites de mémoire de la mise en tampon de quantités excessives des portées. Il doit être supérieur à INSTANA_FORCE_TRANSMISSION_STARTING_AT.
  • INSTANA_LOG_LEVEL: Voir la section « Configurer la journalisation de débogage ».
  • INSTANA_LOG_LEVEL_STDOUT: Voir la section « Configurer la journalisation de débogage ».
  • INSTANA_OVERRIDE_HSLOGGER_ROOT_HANDLER: Voir la section « Configurer la journalisation de débogage ».