Atelier de programmation sur la journalisation et le traçage Cloud Functions

Cet atelier de programmation vous explique comment exploiter les outils de journalisation et de surveillance proposés à tous les développeurs de la fonction Cloud. Ces outils sont fournis avec toutes les fonctions Cloud que vous déployez dans tous les langages compatibles et vous permettent d'être plus productif lors de l'écriture et de l'exploitation de votre code sans serveur.

Nous utiliserons ici une fonction déclenchée par HTTP, mais tout ce que nous aborderons s'applique également à d'autres langues et aux fonctions déclenchées par d'autres événements (bucket de stockage, pub/sub, etc.).

Configuration de l'environnement au rythme de chacun

Si vous n'avez pas encore de compte Google (Gmail ou Google Apps), vous devez en créer un. Connectez-vous à la console Google Cloud Platform (console.cloud.google.com) et créez un projet:

Capture d'écran du 10/02/2016 12:45:26.png

Mémorisez l'ID du projet. Il s'agit d'un nom unique permettant de différencier chaque projet Google Cloud (le nom ci-dessus est déjà pris ; vous devez en trouver un autre). Il sera désigné par le nom PROJECT_ID tout au long de cet atelier de programmation.

Vous devez ensuite activer la facturation dans Cloud Console afin d'utiliser les ressources Google Cloud.

Suivre cet atelier de programmation ne devrait pas vous coûter plus d'un euro. Cependant, cela peut s'avérer plus coûteux si vous décidez d'utiliser davantage de ressources ou si vous n'interrompez pas les ressources (voir la section "Effectuer un nettoyage" à la fin du présent document).

Les nouveaux utilisateurs de Google Cloud Platform peuvent bénéficier d'un essai offert de 300$.

Google Cloud Shell

Vous pouvez utiliser Google Cloud Functions et ses fonctionnalités de journalisation et de surveillance à distance depuis votre ordinateur portable. Dans cet atelier de programmation, nous allons utiliser Google Cloud Shell, un environnement de ligne de commande fonctionnant dans le cloud.

Cette machine virtuelle basée sur Debian contient tous les outils de développement dont vous aurez besoin. Elle intègre un répertoire d'accueil persistant de 5 Go et s'exécute sur Google Cloud, ce qui améliore nettement les performances du réseau et l'authentification. Cela signifie que tout ce dont vous avez besoin pour cet atelier de programmation est un navigateur (oui, tout fonctionne sur un Chromebook).

Pour activer Google Cloud Shell, cliquez sur le bouton en haut à droite de la Console pour les développeurs, qui ne devrait pas prendre quelques instants pour provisionner l'environnement et s'y connecter :

activateCloudShell.png

Cliquez sur le bouton "Démarrer Cloud Shell" :

Capture d'écran du 2017-06-14 à 10.13.43 PM.png

En principe, une fois que vous êtes connecté à Cloud Shell, vous êtes authentifié, et le projet est défini sur votre PROJECT_ID :

gcloud auth list

Résultat de la commande

Credentialed accounts:
 - <myaccount>@<mydomain>.com (active)
gcloud config list project

Résultat de la commande

[core]
project = <PROJECT_ID>

Cloud Shell définit également certaines variables d'environnement par défaut qui peuvent être utiles lorsque vous exécutez de futures commandes.

echo $GOOGLE_CLOUD_PROJECT

Résultat de la commande

<PROJECT_ID>

Si, pour une raison quelconque, le projet n'est pas défini, exécutez simplement la commande suivante :

gcloud config set project <PROJECT_ID>

Vous recherchez votre PROJECT_ID ? Consultez l'ID utilisé pour la configuration ou recherchez-le dans le tableau de bord de la console:

ID_projet.png

IMPORTANT: Enfin, définissez la zone et la configuration du projet par défaut:

gcloud config set compute/zone us-central1-f

Vous pouvez choisir parmi différentes zones. Pour en savoir plus, consultez la documentation sur les régions et les zones.

Pour avoir un appareil à surveiller, nous allons créer une fonction Cloud Hello World. Dans le menu de gauche de la console, cliquez sur Cloud Functions, puis :Create function&quot:

Attribuez un nom à la nouvelle fonction :hello-monitor&quot:

... et conserver les valeurs par défaut pour le code source (vous pouvez toutefois choisir une autre langue ou un autre environnement d'exécution si vous le souhaitez) :

Pour terminer, créez la fonction à l'aide du bouton "Create".

Après quelques instants, votre fonction doit s'afficher comme étant prête à être appelée (comme illustré par la coche verte) :

Maintenant que vous avez déployé la fonction Cloud, vous allez la tester à partir de la ligne de commande.

Commencez par utiliser la commande suivante à l'aide de Cloud Shell :

$ gcloud functions describe hello-monitor

Cela doit renvoyer une description de la fonction, y compris une URL pour httpsTrigger qui est le point de terminaison HTTP(S) pour appeler la fonction. Elle doit respecter le format suivant : https://<region>-<project-id>.cloudfunctions.net/hello-monitor

Le déclenchement de la fonction devrait maintenant être aussi simple que curl et renvoyer cette URL :

$ curl https://<region>-<project-id>.cloudfunctions.net/hello-monitor
Hello World!

Nous allons à présent utiliser Vegeta, un outil de test de charge HTTP simple. Pour l'installer, saisissez la commande suivante dans Cloud Shell :

$ go get -u github.com/tsenart/vegeta

Pour envoyer du trafic vers votre fonction Cloud (5 requêtes par seconde pendant quelques minutes), exécutez la commande suivante :

$ echo "GET https://<region>-<project-id>.cloudfunctions.net/hello-monitor" \
   | vegeta attack -rate=5 -duration=120s \
   > results.bin

Dans la vue des détails de la fonction, cliquez sur le menu de droite pour afficher les journaux :

Vous êtes redirigé vers la section Stackdriver Logging de votre projet. Elle présente uniquement les journaux de votre fonction Cloud :

Nous espérons que toutes les requêtes adressées à votre fonction renvoient un code d'état 200.

Avec cette visionneuse de journaux, vous pouvez :

  • filtrer par niveau de journalisation (dans notre cas, tous les journaux sont de niveau Debug)
  • Sélectionnez une période spécifique (relative ou absolue)
  • activer la diffusion des journaux (bouton "Lecture" en haut de l'écran) ;
  • Copier un lien vers l'entrée de journal (à partager avec les membres de l'équipe)
  • afficher une entrée de journal dans le contexte de la ressource
  • Épingler une entrée de journal (signal visuel)
  • d'exporter des journaux vers BigQuery, Cloud Storage ou Cloud Pub/Sub (ou de les télécharger au format JSON ou CSV) ;

Notez également que le sélecteur en haut à gauche vous permet de filtrer les journaux par fonction. Vous pouvez également rechercher des libellés ou du texte dans la barre de recherche en haut de la fenêtre. Dans le cas présent, les étiquettes sont hello-monitor (le nom de la fonction) ainsi qu'un identifiant d'exécution pour chaque requête.

Vous pouvez également copier les filtres pour les partager (consultez le menu déroulant dans le champ de recherche) :

Depuis la console, accédez à la page "Détails de la fonction" et affichez le pic que nous avons créé avec notre testeur de charge, à la fois en termes d'appels par seconde et de temps d'exécution :

La fonctionnalité Stackdriver Trace est un autre outil plus détaillé pour observer la latence et les appels RPC. Toutefois, avant de l'utiliser, nous devons apporter quelques modifications à nos fonctions, à savoir:

  1. Ajoutez le package node-emoji qui sauve la vie en tant que dépendance
  2. Mettre à jour le code de la fonction pour utiliser le module node-emoji et introduire une latence
  3. Ajouter une variable d'environnement pour activer Stackdriver Trace pour Cloud Functions

Sur la page "Détails de la fonction", cliquez sur "Modifier" pour modifier la fonction :

Modifiez le fichier package.json afin d'ajouter une dépendance au package node-emoji :

{
  "name": "sample-http",
  "version": "0.0.1",
  "dependencies": {
    "node-emoji": "^1.8.1"
  }
}

Modifiez la fonction réelle en remplaçant le contenu du fichier index.js par le code suivant :

const emoji = require('node-emoji');

exports.helloWorld = (req, res) => {
  let message = req.query.message || req.body.message || 'Hello World!';

  // add some latency, functions are too quick!
  setTimeout(function() {
     message += emoji.random().emoji;  
     res.status(200).send(message);
  }, (3 * 100));  // 300ms
  
};

Un emoji aléatoire est alors ajouté au message renvoyé par la fonction après une pause de 300 millisecondes.

Enfin, ajoutez une variable d'environnement Cloud Function appelée GOOGLE_CLOUD_TRACE_ENABLED et définissez-la comme suit : true :

N'oubliez pas de cliquer sur "Enregistrer"

Revenez maintenant à Cloud Shell et souvenez-vous de la commande permettant de générer une charge sur la fonction nouvellement déployée :

$ echo "GET https://<region>-<project-id>.cloudfunctions.net/hello-monitor" \
   | vegeta attack -rate=5 -duration=120s \
   > results.bin

Nous sommes maintenant prêts à observer la liste des traces produites, sans autres exigences de configuration et aucune bibliothèque de traçage spécifique dans votre code.

Dans le menu de gauche, accédez à la liste des traces (sous Stackdriver Trace) :

Le résultat devrait ressembler à ceci :

Il est évident que la latence introduite par la fonction est effectivement mesurée à 300 ms.

Chaque point de ce graphique est une requête pour laquelle vous pouvez afficher des informations détaillées, telles que l'horodatage, la méthode et l'état HTTP, ses libellés, un lien vers l'entrée de journal correspondante et tout appel RPC ultérieur effectué par la fonction :

Pour faire un zoom avant, cliquez sur le graphique et faites-le glisser.Sélectionner une période personnalisée dans le graphique des traces

Pour faire un zoom arrière, cliquez sur le bouton "Annuler le zoom" en haut de la page.

Étant donné que nous avons déployé une seule fonction, le graphique n'affiche que les requêtes GET pour l'URI hello-monitor, mais vous pouvez filtrer les traces par méthode HTTP (GET, POST, DELETE, ...), par état HTTP (2XX, 3XX, etc.) ou à l'aide du filtre de requête.

Accédez à la section Traces & Overview (Présentation) du menu de gauche.

Sur cette page, vous pouvez trouver les traces récentes et d'autres insights.

... et créer des rapports personnalisés basés sur une combinaison de filtres de requêtes d'URI, de méthode HTTP, d'état HTTP et de période. Vous pouvez même comparer les valeurs générées à une référence temporelle :

Si vous configurez la bonne plage de dates et que vous disposez de suffisamment de données, vous pouvez générer un rapport indiquant le important décalage entre la fonction initiale et la nouvelle :

Un tel rapport personnalisé peut servir à détecter quand un problème de performances a été introduit, et à suivre les indicateurs de niveau de service (SLI) comme la latence des requêtes de l'utilisateur final.

C'est la fin de notre atelier de programmation sur le déploiement d'une nouvelle fonction Cloud, la navigation dans les journaux et l'observation de ses traces de requête.

Bien que les outils Cloud Functions et Stackdriver soient des plates-formes sans serveur qui n'engendreront pas de coûts lorsqu'ils ne seront pas utilisés, nous vous conseillons de supprimer notre fonction afin d'être un bon citoyen cloud.

Il suffit de sélectionner la fonction hello-monitor sur la page de présentation de Cloud Functions et de cliquer sur"supprimer".

Nous avons terminé cet atelier de programmation de démarrage simple avec les journaux et les traces Cloud Functions.

Voici quelques informations de suivi :

/