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?
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.
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:
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 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.
Comme je l'ai mentionné, cette approche n'est pas parfaite. Voici quelques problèmes potentiels avec le harnais de test:
context
, cette approche peut rencontrer des problèmesCependant, 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.
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.
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.
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
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.
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
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"
}
L'option la plus simple que j'ai à ce jour avec VS Code est la suivante:
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()
Modifiez l'entrée de programme du fichier launcher.json
comme suit: "program": "${workspaceFolder}/<your app dir>/debug.js"
Vous pouvez maintenant simplement mettre un point d'arrêt sur cette ligne (app.handler()
) et cela fonctionne