Surveillance et journalisation - AWS AppSync

Surveillance et journalisation

Vous pouvez utiliser Amazon CloudWatch pour surveiller et déboguer les demandes dans AWS AppSync. À l'aide d'AWS AppSync, vous pouvez utiliser GraphQL pour demander des données du cloud. Vous avez souvent besoin d'obtenir plus d'informations sur l'exécution de votre API. Pour vous aider à déboguer les problèmes liés à l'exécution de demandes de votre API GraphQL, vous pouvez activer Amazon CloudWatch Logs afin de surveiller les appels d'API. Une fois que vous avez activé CloudWatch, AWS AppSync consigne les appels d'API dans CloudWatch.

Installation et configuration

Vous pouvez activer la journalisation sur une API GraphQL automatiquement via la console AWS AppSync.

  1. Connectez-vous à la console AWS AppSync.

  2. Choisissez Paramètres dans le volet de navigation.

  3. Sous Journalisation, cliquez sur le bouton bascule pour Activer les journaux.

  4. Lorsque la console vous y invite, fournissez ou créez un rôle ARN CloudWatch.

  5. (Facultatif) Choisissez de configurer le niveau de journalisation du champ de résolveur dans la liste.

  6. Choisissez Enregistrer. La journalisation est configurée automatiquement pour votre API.

Configuration de rôle manuelle

Pour activer CloudWatch Logs, vous devez accorder à AWS AppSync des autorisations appropriées pour l'écriture des journaux dans CloudWatch pour votre compte. Pour cela, vous devez fournir un nom ARN de rôle de service afin qu'AWS AppSync puisse assumer ce rôle lors de l'écriture des journaux.

Commencez par accéder à la console IAM. Ensuite, créez une nouvelle stratégie avec le nom AWSAppSyncPushToCloudWatchLogsPolicy ayant la définition suivante :

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents" ], "Resource": "*" } ] }

Puis créez un nouveau rôle avec le nom AWSAppSyncPushToCloudWatchLogsRole et attachez la stratégie ci-dessus à ce rôle. Modifiez la relation d'approbation de ce rôle afin d'obtenir ce qui suit :

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "appsync.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }

Copiez l'ARN du rôle et enregistrez ceci avec AWS AppSync afin de permettre l'écriture dans CloudWatch.

Indicateurs CloudWatch

Vous pouvez utiliser les métriques CloudWatch pour surveiller et fournir des alertes sur des événements spécifiques susceptibles d'être déclenchés par des codes de statut HTTP ou par latence, par exemple la latence générale des demandes et des réponses GraphQL. Les métriques suivantes sont émises.

  • 4XX

    Nombre d'erreurs capturées à la suite de demandes non valides en raison d'une configuration incorrecte du client. En général, ces erreurs peuvent se produire n'importe où en dehors de l'exécution GraphQL. Par exemple, cette erreur peut se produire lorsque la requête inclut une charge utile JSON incorrecte ou une requête incorrecte, lorsque le service rencontre un goulet d'étranglement ou lorsque les paramètres d'authentification sont mal configurés.

    Unité : nombre. Utilisez la statistique Somme pour obtenir le total des occurrences de ces erreurs.

  • 5XX

    Erreurs rencontrées lors de l'exécution d'une requête GraphQL. Par exemple, cela peut se produire lorsqu'une demande de requête est lancée pour un schéma vide ou incorrect. Cela peut également se produire lorsque l'ID de pool d'utilisateurs Amazon Cognito ou la région AWS n'est pas valide. Sinon, cela peut également se produire si AWS AppSync rencontre un problème lors de l'exécution d'une demande.

    Unité : nombre. Utilisez la statistique Somme pour obtenir le total des occurrences de ces erreurs.

  • Latence

    Délai entre le moment où AWS AppSync reçoit une demande d'un client et le moment où il renvoie une réponse au client. Cela n'inclut pas la latence du réseau rencontrée pour une réponse afin d'atteindre les appareils finaux.

    Unité : milliseconde. Utilisez la statistique Moyenne pour évaluer les latences attendues.

Abonnements en temps réel

Toutes les métriques sont émises dans une dimension : GraphQLAPIID. Cela signifie que toutes les métriques sont couplées avec des ID d'API GraphQL. Les métriques suivantes sont liées aux abonnements GrapQL sur WebSockets purs :

  • ConnectSuccess

    Nombre de connexions WebSocket réussies à AWS AppSync. Il est possible d'avoir des connexions sans abonnements.

    Unité : nombre. Utilisez la statistique Sum (Somme) pour obtenir le total des occurrences de connexions réussies.

  • ConnectClientError

    Nombre de connexions WebSocket rejetées par AWS AppSync en raison d'erreurs côté client. Cela peut impliquer que le service rencontre un goulet d'étranglement ou que les paramètres d'autorisation sont mal configurés.

    Unité : nombre. Utilisez la statistique Sum (Somme) pour obtenir le total des occurrences des erreurs de connexion côté client.

  • ConnectServerError

    Nombre d'erreurs retournées par AWS AppSync lors du traitement des connexions. Cela se produit généralement lorsqu'un problème inattendu prend place côté serveur.

    Unité : nombre. Utilisez la statistique Sum (Somme) pour obtenir le total des occurrences d'erreurs de connexion côté serveur.

  • DisconnectSuccess

    Nombre de déconnexions WebSocket réussies depuis AWS AppSync.

    Unité : nombre. Utilisez la statistique Sum (Somme) pour obtenir le total d'occurrences de déconnexions réussies.

  • DisconnectError

    Nombre d'erreurs retournées par AWS AppSync lors de la déconnexion de connexions WebSocket.

    Unité : nombre. Utilisez la statistique Sum (Somme) pour obtenir le total des occurrences d'erreurs de connexion.

  • SubscribeSuccess

    Nombre d'abonnements qui ont été enregistrés avec succès sur AWS AppSync via WebSocket. Il est possible d'avoir des connexions sans abonnements, mais il n'est pas possible d'avoir des abonnements sans connexions.

    Unité : nombre. Utilisez la statistique Sum (Somme) pour obtenir le nombre total des occurrences d'abonnements réussis.

  • SubscribeClientError

    Nombre d'abonnements qui ont été rejetés par AWS AppSync en raison d'erreurs côté client. Cela peut se produire lorsqu'une charge utile JSON est incorrecte, que le service rencontre un goulet d'étranglement ou que les paramètres d'autorisation sont mal configurés.

    Unité : nombre. Utilisez la statistique Sum (Somme) pour obtenir le total des occurrences d'erreurs d'abonnement côté client.

  • SubscribeServerError

    Nombre d'erreurs retournées par AWS AppSync lors du traitement des abonnements. Cela se produit généralement lorsqu'un problème inattendu prend place côté serveur.

    Unité : nombre. Utilisez la statistique Sum (Somme) pour obtenir le nombre total d'occurrences des erreurs d'abonnement côté serveur.

  • UnsubscribeSuccess

    Nombre de désabonnements traités avec succès depuis AWS AppSync.

    Unité : nombre. Utilisez la statistique Sum (Somme) pour obtenir le total des occurrences de désabonnements réussis.

  • UnsubscribeClientError

    Nombre de désabonnements qui ont été rejetés par AWS AppSync en raison d'erreurs côté client.

    Unité : nombre. Utilisez la statistique Sum (Somme) pour obtenir le total des occurrences d'erreurs de désabonnement côté client.

  • UnsubscribeServerError

    Nombre d'erreurs retournées par AWS AppSync lors du traitement des désabonnements. Cela se produit généralement lorsqu'un problème inattendu prend place côté serveur.

    Unité : nombre. Utilisez la statistique Sum (Somme) pour obtenir le total des occurrences d'erreurs de désabonnement côté serveur.

  • PublishDataMessageSuccess

    Nombre de messages d'événement d'abonnement qui ont été publiés avec succès.

    Unité : nombre. Utilisez la statistique Sum (Somme) pour obtenir le total des messages d'événement d'abonnement qui ont été publiés avec succès.

  • PublishDataMessageClientError

    Nombre de messages d'événement d'abonnement qui n'ont pas pu être publiés en raison d'erreurs côté client.

    Unité : nombre. Utilisez la statistique Sum (Somme) pour obtenir le total des occurrences d'erreurs d'événement d'abonnement de publication côté client.

  • PublishDataMessageServerError

    Nombre d'erreurs retournées par AWS AppSync lors de la publication des messages d'événement d'abonnement. Cela se produit généralement lorsqu'un problème inattendu prend place côté serveur.

    Unité : nombre. Utilisez la statistique Sum (Somme) pour obtenir le total des occurrences d'erreurs d'événement d'abonnement de publication côté serveur.

  • PublishDataMessageSize

    Taille des messages d'événement d'abonnement publiés.

    Unité : octets.

  • ActiveConnection

    Nombre de connexions WebSocket simultanées entre les clients et AWS AppSync en 1 minute.

    Unité : nombre. Utilisez la statistique Sum (Somme) pour obtenir le nombre total de connexions ouvertes.

  • ActiveSubscription

    Nombre d'abonnements simultanés provenant de clients en 1 minute.

    Unité : nombre. Utilisez la statistique Sum (Somme) pour obtenir le total des abonnements actifs.

  • ConnectionDuration

    Durée pendant laquelle la connexion reste ouverte.

    Unité : millisecondes. Utilisez la statistique Average (Moyenne) pour évaluer la durée de connexion.

CloudWatch Logs

Vous pouvez configurer deux types de journalisation sur n'importe quelle API GraphQL nouvelle ou existante : au niveau de la demande et au niveau du champ.

Journaux au niveau de la demande

Lorsque cette option est activée, les informations suivantes sont consignées :

  • La demande et la réponse des en-têtes HTTP

  • La requête GraphQL en cours d'exécution dans la demande

  • Résumé global de l'exécution

  • Les abonnements à GraphQL nouveaux et anciens qui sont enregistrés

Journaux au niveau du champ

Lorsque cette option est activée, les informations suivantes sont consignées :

  • Mappage des demandes générées avec la source et les arguments de chaque champ

  • Mappage des réponses transformées pour chaque champ, ce qui inclut les données obtenues à la suite de la résolution de ce champ

  • Suivi des informations pour chaque champ

Si vous activez la journalisation, AWS AppSync gère CloudWatch Logs. Le processus comprend la création de groupes de journaux et de flux de journaux, et la génération de rapports dans les flux de journaux avec ces journaux.

Lorsque vous activez la journalisation sur une API GraphQL et que vous effectuez des demandes, AWS AppSync crée un groupe et des flux de journaux dans le groupe de journaux. Le groupe de journaux est nommé selon le format /aws/appsync/apis/{graphql_api_id}. Dans chaque groupe de journaux, les journaux sont également divisés en flux de journaux. Ces derniers sont classés selon l'heure du dernier événement lors de la consignation des données.

Chaque événement de journal est balisé avec l'ID x-amzn-RequestId de cette demande. Cela vous permet de filtrer les événements de journaux dans CloudWatch afin d'obtenir toutes les informations consignées concernant cette demande. Vous pouvez obtenir le RequestId à partir des en-têtes de réponse de chaque demande GraphQL AWS AppSync.

La journalisation au niveau du champ est configurée avec les niveaux de journaux suivants :

  • AUCUN – Aucun journal au niveau du champ n'est capturé.

  • ERREUR – Consigne les informations suivantes uniquement pour les champs comportant une erreur :
    • Section d'erreur dans la réponse du serveur

    • Erreurs au niveau du champ

    • Fonctions de demande/réponse générées qui ont été résolues pour les champs d'erreur

  • TOUS – Les informations suivantes sont consignées pour tous les champs de la requête :
    • Informations de suivi au niveau du champ

    • Fonctions de demande/réponse générées qui ont été résolues pour chaque champ

Avantages de l'activation de la surveillance

Vous pouvez utiliser la journalisation et les métriques pour identifier, dépanner et optimiser vos requêtes GraphQL. Par exemple, cela vous aidera à déboguer les problèmes de latence à l'aide des informations de suivi consignées pour chaque champ de la requête. Pour illustrer cela, supposons que vous utilisiez un ou plusieurs résolveurs imbriqués dans une requête GraphQL. Un exemple d'exécution de champ dans CloudWatch Logs peut ressembler à ce qui suit :

{ "path": [ "singlePost", "authors", 0, "name" ], "parentType": "Post", "returnType": "String!", "fieldName": "name", "startOffset": 416563350, "duration": 11247 }

Cela peut correspondre à un schéma GraphQL, comme illustré ci-dessous :

type Post { id: ID! name: String! authors: [Author] } type Author { id: ID! name: String! } type Query { singlePost(id:ID!): Post }

Dans les résultats du journal ci-dessus, le chemin indique un élément unique dans les données renvoyées de l'exécution d'une requête nommée singlePost(). Dans cet exemple, il représente le champ nom au premier index (0). startOffset donne un décalage par rapport au début de l'exécution des requêtes GraphQL. Durée correspond à la durée totale pour résoudre le champ. Ces valeurs peuvent être utiles afin de déterminer la raison pour laquelle les données d'une source de données spécifique sont exécutées plus lentement que prévu, ou si un champ spécifique ralentit l'ensemble de la requête. Par exemple, vous pouvez choisir d'augmenter le débit alloué pour une table Amazon DynamoDB, ou supprimer un champ spécifique à partir d'une requête qui nuit aux bonnes performances d'exécution globale.

Depuis le 8 mai 2019, AWS AppSync génère les événements de journaux dans un format JSON entièrement structuré. Cela vous permet d'utiliser des services d'analyse de journaux tels qu'Amazon CloudWatch Logs Insights et Amazon Elasticsearch Service pour comprendre les performances de vos demandes GraphQL et les caractéristiques d'utilisation de vos champs de schéma. Par exemple, vous pouvez identifier facilement les résolveurs rencontrant des latences importantes et qui pourraient être la cause profonde d'un problème de performances. Vous pouvez également identifier les champs utilisés le plus et le moins fréquemment dans votre schéma et évaluer l'impact des dépréciations des champs GraphQL.

Détection des conflits et enregistrement de synchronisation

Si une API AWS AppSync a activé CloudWatch Logs avec les paramètres de journalisation définis sur Journaux au niveau du champ enabled et au niveau du journal pour les Journaux au niveau du champ définis sur ALL, AWS AppSync émettra des informations de détection et de résolution des conflits pour le groupe de journaux. Cela fournira un aperçu granulaire des décisions que l'API AWS AppSync a prises lorsqu'un conflit a été détecté. Pour ce faire, les informations suivantes seront fournies dans les journaux :

conflictType

Détermine si un conflit s'est produit en raison d'une incompatibilité de version ou de la condition fournie par le client.

conflictHandlerConfigured

État le gestionnaire de conflits configuré sur le résolveur au moment de la demande.

message

Fournit des informations sur la façon dont le conflit a été détecté et résolu.

syncAttempt

Nombre d'essais du serveur pour synchroniser les données avant de rejeter la demande.

data

Si le gestionnaire de conflits configuré était Automerge, ce champ sera renseigné pour indiquer la décision prise par Automerge pour chaque champ. Les actions proposées peuvent être les suivantes :

  • REJETÉ Lorsque Automerge rejette la valeur du champ entrant en faveur de la valeur dans le serveur.

  • AJOUTÉ Lorsque Automerge ajoute sur le champ entrant en raison de l'absence de valeur préexistante dans le serveur.

  • AJOUTÉ Lorsque Automerge ajoute les valeurs entrantes aux valeurs de la liste qui existe dans le serveur.

  • FUSIONNÉ Lorsque Automerge fusionne les valeurs entrantes aux valeurs de l'ensemble qui existe dans le serveur.

Référence des types de journaux

RequestSummary

  • requestId : identifiant unique de la demande.

  • graphQLAPIId : ID de l'API GraphQL effectuant la demande.

  • statusCode : réponse de code d'état HTTP.

  • latency : latence de bout en bout de la demande, en nanosecondes, indiquée en tant que nombre entier.

{ "logType": "RequestSummary", "requestId": "dbe87af3-c114-4b32-ae79-8af11f3f96f1", "graphQLAPIId": "pmo28inf75eepg63qxq4ekoeg4", "statusCode": 200, "latency": 242000000 }

ExecutionSummary

  • requestId : identifiant unique de la demande.

  • graphQLAPIId : ID de l'API GraphQL effectuant la demande.

  • startTime : horodatage de début de l'exécution GraphQL de la demande, au format RFC 3339.

  • endTime : horodatage de fin de l'exécution GraphQL de la demande, au format RFC 3339.

  • duration : durée totale d'exécution GraphQL écoulée, en nanosecondes, indiquée en tant que nombre entier.

  • version : version de schéma du journal ExecutionSummary.

  • parsing :
    • startOffset : décalage de début de l'analyse, en nanosecondes, par rapport au début de l'exécution, indiqué en tant que nombre entier.

    • duration : temps consacré à l'analyse, en nanosecondes, indiqué en tant que nombre entier.

  • validation :
    • startOffset : décalage de début de la validation, en nanosecondes, par rapport au début de l'exécution, indiqué en tant que nombre entier.

    • duration : temps consacré à la validation, en nanosecondes, indiqué en tant que nombre entier.

{ "duration": 217406145, "logType": "ExecutionSummary", "requestId": "dbe87af3-c114-4b32-ae79-8af11f3f96f1", "startTime": "2019-01-01T06:06:18.956Z", "endTime": "2019-01-01T06:06:19.174Z", "parsing": { "startOffset": 49033, "duration": 34784 }, "version": 1, "validation": { "startOffset": 129048, "duration": 69126 }, "graphQLAPIId": "pmo28inf75eepg63qxq4ekoeg4" }

Tracing

  • requestId : identifiant unique de la demande.

  • graphQLAPIId : ID de l'API GraphQL effectuant la demande.

  • startOffset : décalage de début de la résolution du champ, en nanosecondes, par rapport au début de l'exécution, indiqué en tant que nombre entier.

  • duration : temps consacré à la résolution du champ, en nanosecondes, indiqué en tant que nombre entier.

  • fieldName : nom du champ en cours de résolution.

  • parentType : type de parent du champ en cours de résolution.

  • returnType : type de retour du champ en cours de résolution.

  • path : liste des segments de chemin, commençant à la racine de la réponse et se terminant par le champ en cours de résolution.

  • resolverArn : ARN du résolveur utilisé pour la résolution des champs. Peut ne pas être présent sur les champs imbriqués.

{ "duration": 216820346, "logType": "Tracing", "path": [ "putItem" ], "fieldName": "putItem", "startOffset": 178156, "resolverArn": "arn:aws:appsync:us-east-1:111111111111:apis/pmo28inf75eepg63qxq4ekoeg4/types/Mutation/fields/putItem", "requestId": "dbe87af3-c114-4b32-ae79-8af11f3f96f1", "parentType": "Mutation", "returnType": "Item", "graphQLAPIId": "pmo28inf75eepg63qxq4ekoeg4" }

Analyse de vos journaux avec Amazon CloudWatch Logs Insights

Voici des exemples de requêtes que vous pouvez exécuter pour obtenir des informations exploitables sur les performances et l'état de vos opérations GraphQL. Ces exemples sont disponibles sous forme d'exemples de requêtes dans la console CloudWatch Logs Insights. Dans la console Amazon CloudWatch, choisissez Logs Insights, sélectionnez le groupe de journaux AWS AppSync pour votre API GraphQL, puis choisissez AWS AppSync queries (Requêtes AWS AppSync) sous Sample queries (Exemples de requêtes).

La requête suivante renvoie les 10 principales demandes GraphQL rencontrant une latence maximale :

fields requestId, latency | filter logType = "RequestSummary" | limit 10 | sort latency desc

La requête suivante renvoie les 10 principaux résolveurs rencontrant une latence maximale :

fields resolverArn, duration | filter logType = "Tracing" | limit 10 | sort duration desc

La requête suivante renvoie les résolveurs les plus fréquemment appelés :

fields ispresent(resolverArn) as isRes | stats count() as invocationCount by resolverArn | filter isRes and logType = "Tracing" | limit 10 | sort invocationCount desc

La requête suivante renvoie les résolveurs rencontrant le plus grand nombre d'erreurs dans les modèles de mappage :

fields ispresent(resolverArn) as isRes | stats count() as errorCount by resolverArn, logType | filter isRes and (logType = "RequestMapping" or logType = "ResponseMapping") and fieldInError | limit 10 | sort errorCount desc

La requête suivante renvoie les statistiques de latence du résolveur :

fields ispresent(resolverArn) as isRes | stats min(duration), max(duration), avg(duration) as avg_dur by resolverArn | filter isRes and logType = "Tracing" | limit 10 | sort avg_dur desc

La requête suivante renvoie les statistiques de latence du champ :

stats min(duration), max(duration), avg(duration) as avg_dur by concat(parentType, '/', fieldName) as fieldKey | filter logType = "Tracing" | limit 10 | sort avg_dur desc

Les résultats des requêtes CloudWatch Logs Insights peuvent être exportés vers des tableaux de bord CloudWatch.

Analyse de vos journaux avec Amazon Elasticsearch Service

Vous pouvez rechercher, analyser et visualiser vos journaux AWS AppSync avec Amazon Elasticsearch Service pour identifier les goulots d'étranglement des performances et la cause profonde des problèmes opérationnels. Vous pouvez identifier les résolveurs rencontrant la latence maximale et le maximum d'erreurs. De plus, vous pouvez utiliser Kibana pour créer des tableaux de bord avec de puissantes visualisations. Kibana est un outil de visualisation et d'exploration de données open source disponible dans Amazon ES. Grâce aux tableaux de bord Kibana, vous pouvez surveiller en continu les performances et l'état de vos opérations GraphQL. Par exemple, vous pouvez créer des tableaux de bord qui vous permettent de visualiser la latence P90 de vos demandes GraphQL et d'explorer en détail les latences P90 de chaque résolveur.

Lorsque vous utilisez Amazon ES, utilisez « cwl* » comme modèle de filtre pour rechercher les index Elasticsearch. Elasticsearch indexe les journaux diffusés à partir de CloudWatch Logs avec le préfixe « cwl- ». Pour différencier les journaux d'API AWS AppSync des autres journaux CloudWatch envoyés à Elasticsearch, nous vous recommandons d'ajouter l'expression de filtre supplémentaire graphQLAPIID.keyword=<AWS AppSync's GraphQL API Id> à votre recherche.

Migration du format de journal

Les événements de journaux générés par AWS AppSync à partir du 8 mai 2019 sont au format JSON entièrement structuré. Si vous souhaitez analyser des demandes GraphQL antérieures au 8 mai 2019, vous pouvez migrer les anciens journaux vers un journal au format JSON entièrement structuré à l'aide d'un script disponible dans l'exemple GitHub. Si vous avez besoin d'utiliser le format de journal antérieur au 8 mai 2019, créez un ticket de support avec les paramètres suivants : définissez Type sur Account Management (Gestion de compte), puis définissez Category (Catégorie) sur General Account Question (Question d'ordre général sur le compte).

Vous pouvez également choisir d'activer les filtres de métriques dans CloudWatch. Vous pouvez ensuite utiliser ces filtres de métriques pour transformer les données des journaux en métriques numériques CloudWatch, afin de pouvoir les représenter graphiquement ou les utiliser pour définir une alarme.