web-dev-qa-db-fra.com

Comment déboguer les fonctions aws lambda écrites dans le noeud js

Nous développons des fonctions AWS Lambda dans Node JS depuis quelques mois. Pouvons-nous déboguer, c’est-à-dire parcourir le code Node JS comme nous le pouvons avec le code .Net C # dans Visual Studio?

6
Steve

Les outils de développement basés sur l'EDI ne sont pas disponibles par défaut pour de nombreuses fonctions Lambda. Il existe certains plugins, tels que le support Visual Studio introduit par AWS sur leur blog à l'adresse suivante: https://aws.Amazon.com/blogs/developer/aws-lambda-support-in-visual-studio/ , mais ceux-ci auront différents niveaux de fonctionnalités et de support.

Afin de tester Lambda à l'aide du débogage en étapes, vous devez vous concentrer sur deux domaines: le matériel sur lequel il s'exécute et la manière dont votre fonction Lambda est appelée. Le matériel est difficile à émuler, car AWS garde secrètes les informations relatives aux instances de machine qui exécutent vos fonctions lambda. En tant que tel, quand il s’agit d’émuler du matériel, vous devez simplement rester dans les limites de votre langue et de votre système d’exploitation - assurez-vous que la bonne durée d’exécution est installée (en tant que, n’installez pas NodeJS 4.X lorsque vous travaillez avec la version 6), assurez-vous de ne pas dépasser les exigences de stockage (les AMI pour Lambda obtiennent 500 Mo d’espace de stockage temporaire dans/tmp) et ne sauvegardez aucun état localement avant les exécutions de votre code.

Une fois que vous avez défini les exigences de votre machine (ou décidé de les transmettre car votre code ne fait aucun travail spécifique au matériel), vous devez alors écrire un test pour appeler votre fonction AWS Lambda. Ce faisceau de test sert de point d’entrée pour votre débogueur. Bien qu’il ne soit probablement pas précis à 100% sur la façon dont AWS appelle Lambda (par exemple, le paramètre context contient des informations sur votre invocation Lambda en cours, qui varient par nature exécutions), vous pouvez invoquer tous vos outils de support de codage standard.

Remarque: le test de harnais simple suivant est écrit pour Node.JS, mais vous pouvez adapter les concepts à l'exécution dans laquelle votre Lambda s'exécute.

Un harnais de test simple pour AWS Lambda (Node.js)

La première chose à faire est de créer un nouveau fichier - debug.js - et d’importer le prototype de la fonction de gestionnaire. En supposant que vous ayez défini votre gestionnaire dans handler.js et que vous l'appeliez handler, procédez comme suit:

var handler = require('./handler.js').handler;

Ensuite, nous devons invoquer la fonction de gestionnaire. Comme je l'ai mentionné plus haut, chacun des paramètres a un objectif différent. Le premier paramètre du gestionnaire -event - contient des détails sur l'événement à l'origine de l'appel. Remarque: cela inclut également les arguments de votre fonction . Le deuxième paramètre, comme nous l'avons vu, contient des informations sur le contexte dans lequel votre fonction s'exécute. Il existe également un troisième paramètre, callback, qui peut être utilisé pour invoquer un rappel à la fin de votre exécution Lambda. Consultez la documentation AWS ici: http://docs.aws.Amazon.com/lambda/latest/dg/nodejs-prog-model-handler.html

Donc, pour nos besoins, pour un harnais de test simple, nous devons simplement envoyer les paramètres via le paramètre event. Nous allons laisser les paramètres context et callback seuls pour le moment (avec une modification mineure, voir ci-dessous), mais si vous souhaitez fournir des données supplémentaires sur lesquelles votre fonction s'appuie, c'est très bien. Assurez-vous simplement qu'elle ne soit pas en conflit avec l'une des données automatisées mises là dans AWS. Nous définissons donc le paramètre hash et appelons la fonction à l'aide du code suivant dans debug.js:

var parameters = {
    "key1":"val1",
    "object" :{},
    // other keys as necessary
};

handler(parameters, {succeed:function(result){
    console.log("success: ", JSON.stringify(result, null, 2));
    process.exit(0);
}, fail:function(error){
    console.error("error: ", error);
    process.exit(1);
}});

Ce code fait quelques choses intéressantes:

  • Il surcharge l'objet de contexte avec un gestionnaire de succès et d'échec. Vous pouvez les envelopper dans une instruction "if" et les appeler dans votre code Lambda à l'aide de context.succeed(message) ou context.fail(error). Lambda ne les prend pas officiellement en charge, mais les utilise plutôt comme solution de contournement dans notre code pour accéder au comportement succès/échec
    • Les gestionnaires appellent process.exit () avec le code d'erreur approprié. Cela vous permet de chaîner votre exécution dans des outils de CI/CD ou dans tout autre outil de traitement par lots utilisant un code de sortie de processus comme flux de contrôle.

Une fois que vous avez écrit ce harnais de test simple et adapté votre code Lambda pour invoquer le gestionnaire succès/échec s’il est présent (quelque chose d'aussi simple que if(context.success){context.success(args);} devrait suffire), vous pouvez maintenant appeler la fonction lambda à l'aide de node debug.js et voir les résultats. dans la console.

J'ai également eu beaucoup de chance avec les tests unitaires dans mes fonctions Lambda. Comme vous avez maintenant un point d’entrée et un exemple d’appel de la fonction Lambda, vous devriez être capable d’écrire des tests d’unité et de fonction appropriés qui expriment l’ensemble de vos fonctionnalités.

Un petit mot sur les lacunes

Comme je l'ai mentionné, cette approche n'est pas parfaite. Voici quelques problèmes potentiels avec le harnais de test:

  • Nous n'avons pas effectué d'émulation d'objet de contexte. Vous pouvez voir les paramètres disponibles dans l’objet context à l’adresse http://docs.aws.Amazon.com/lambda/latest/dg/nodejs-prog-model-context.html - vous devrez faire quelques essais et erreurs pour savoir exactement quel format se retrouve dans ces paramètres
  • Nous n'avons pas effectué d'émulation de machine pour résoudre les problèmes matériels
  • Nous avons seulement couvert les fonctions de Node.js ici, d'autres langues peuvent avoir des difficultés à adapter l'approche de rappel
  • Nous avons surchargé le mécanisme de contexte pour fournir nos gestionnaires succès-échec. Si AWS ajoute des objets membres portant un nom similaire à l'objet context, cette approche peut rencontrer des problèmes

Cependant, malgré ce qui précède, vous devriez maintenant avoir la possibilité d’utiliser des outils de débogage locaux pour tester et déboguer vos fonctions Lambda. Nous utilisons un cadre similaire chez Backand - https://www.backand.com - pour notre outil de développement de fonctions Lambda, ce qui a considérablement accru notre vitesse de développement Lambda.

6
Matt Billock

Je voudrais partager ce que j'ai trouvé car j'avais eu du mal à le découvrir. La solution est basée sur ce que j'ai trouvé dans l'article "Débogage des fonctions AWS Lambda localement à l'aide de VS Code et de lambda-local" ( https://www.codeproject.com/Articles/1163890/Debugging-AWS-Lambda-functions-locally -using-VS-Co ) avec quelques modifications afin de fonctionner dans notre environnement Windows.

Voici le résumé:

1) Utiliser le code Visual Studio pour lancer une session de débogage. Voici un exemple de launch.json pour le débogage de 'llDebugDetail.js':

{
    "version": "0.2.0",
    "configurations": [
        {
            "type": "node",
            "request": "launch",
            "name": "Launch Program",
            "program": "${workspaceRoot}/test/llDebugDetail.js",
            "cwd": "${workspaceRoot}"
        }
    ]
}

2) Utiliser le framework lambda-local pour appeler (exécuter) la fonction lambda. Le framework lambda-local doit être installé localement, sinon le débogueur VSC ne le trouvera pas. Notre fonction lambda est appelée en appelant l'URL suivante: https://xxx.execute-api.ap-southeast-2.amazonaws.com/resourceName/ {id}/detail. Le {id} est un paramètre GUID permettant de sélectionner un produit et de renvoyer ses détails.

Voici le code 'llDebugDetail.js' pour appeler la fonction 'getDetail' afin de renvoyer les détails du produit avec le GUID comme identifiant dans l'URL. La fonction est dans le fichier 'getDetail.js'.

const lambdaLocal = require('lambda-local');
var path = require("path");
const myPath = path.join(__dirname, '../getDetail.js');
const testEvent = {
    "resource": "resourceName/12da3f7d-7ce2-433f-8659-5d7cd0d74d9a/detail",
    "pathParameters": {"id": "12da3f7d-7ce2-433f-8659-5d7cd0d74d9a"}
}

var lambdaFunc = require(myPath);

lambdaLocal.execute({
    event: testEvent,
    lambdaFunc: lambdaFunc, 
    lambdaHandler: "getDetail"
}).then(function(done) {
    console.log(done);
}).catch(function(err) {
    console.log(err);
});

Avec ce qui précède, vous pouvez désormais définir des points d'arrêt n'importe où dans votre code, par exemple. Dans getDetail.js, lancez le programme et l’exploration du code à partir des points de rupture dans getDetail.js.

4
Steve

Vous ne pouvez pas déboguer le code lambda comme vous le faites dans VS, mais vous pouvez appeler des données de test et vérifier que tout va bien.

  1. Vous pouvez exécuter lambda localement sur votre ordinateur à l’aide de lambda-local et serverless-offline
  2. Alors invoquez votre lambda avec des événements et des données de test et vous pourrez vous connecter et voir ce qui se passe pour différentes entrées
3
Prasanth Jaya

Trek 10 a récemment publié un outil intéressant qui permet de parcourir le code de node.js en direct dans les fonctions AWS lambda! Comment, vous pouvez demander? "Magie et miroirs", selon eux :-)

Apparemment, il ne se connecte pas directement au processus hôte d'Amazon (ce qui est impossible), mais il introduit votre code dans un processus enfant s'exécutant en mode débogage et des connexions proxy à vos outils Chrome DevTools locaux. (Il y a en fait un peu plus dans la configuration, que vous pouvez lire sur le dépôt de github ci-dessous.)

Voici l'annonce: https://www.trek10.com/blog/aws-lambda-debugger/

et le dépôt github: https://github.com/trek10inc/aws-lambda-debugger

1
rob3c

Comme d'autres l'ont souligné, vous ne pouvez pas déboguer nativement un Lambda. Mais de nouveaux outils sont développés pour rendre cela possible. Rookout offre maintenant le débogage par étape de la production Node.js Lambdas sans forking ni arrêt du code, en utilisant une sorte de méthode de niveau bytecode.

1
Arieh Kovler

Le débogage par étapes n'est pas possible dans le cas de Lambda. C'est l'un des inconvénients de l'utilisation de Lambda. Vous devrez compter sur la journalisation (log4j ou autre) pour votre débogage

0
Arafat Nalkhande

Si vous utilisez un plug-in hors serveur sans serveur et sans serveur pour effectuer des tests en local. Vous pouvez vous référer ci-dessous:

Si vous utilisez Windows, mettez à jour les fichiers vscode launch.json et package.json comme suit:

// launch.json
{

    "version": "0.2.0",

   "configurations": [

       {

           "type": "node",

           "request": "launch",

           "name": "Debug Serverless",

           "cwd": "${workspaceFolder}",

           "runtimeExecutable": "npm",

           "runtimeArgs": [

               "run",

               "debug"

           ],

           "outFiles": [

               "${workspaceFolder}/handler.js"

           ],

           "port": 9229,

           "sourceMaps": true

       }

   ]

}
// package.json
....
"scripts": {
    "debug": "SET SLS_DEBUG=* && node --inspect %USERPROFILE%\\AppData\\Roaming\\npm\\node_modules\\serverless\\bin\\serverless offline -s dev"
  }

Si sur Linux, votre script de débogage sera:

// package.json
....
"scripts": {
    "debug": "export SLS_DEBUG=* && node --inspect /usr/local/bin/serverless offline -s dev"
  }
0
bhavesh vyas

L'option la plus simple que j'ai à ce jour avec VS Code est la suivante:

  1. Créez un nouveau fichier, appelons-le debug.js et appelez simplement votre fonction lambda à partir d'ici, quelque chose comme ceci: const app = require('./index') app.handler()

  2. Modifiez l'entrée de programme du fichier launcher.json comme suit: "program": "${workspaceFolder}/<your app dir>/debug.js"

  3. Vous pouvez maintenant simplement mettre un point d'arrêt sur cette ligne (app.handler()) et cela fonctionne

0
Mohammad Haque