Billet ultra-geek aujourd’hui, sorry ;).
L’infra d’illuxiApp est entièrement chez AWS. Nous y sommes depuis quelques années déjà, mais grâce à la gang de chez Unicorne, nous avons complètement rebâti le tout, from scratch. De la bonne façon cette fois :). Et c’est frickin cool!
On utilise CloudWatch évidemment pour centraliser l’ensemble des logs. illuxiApp y envoie aussi ses propres logs. Nous avons des alarmes pour nous aviser de certains éléments, mais on voulait certains logs en temps réel. Par exemple, les erreurs ;).
En nous inspirant de ce post, nous avons mis en place une fonction Lambda qui envoie un message dans un canal Slack chaque fois qu’un événement de log correspond à certains critères.
Voici les étapes.
Création d’un webhook Slack
Dans Slack, dirigez-vous vers Outils et paramètres / Gérer les applications:

Recherchez « webhook » et cliquez sur Webhooks entrants:

Cliquez sur Ajoutez à Slack:

Sélectionnez le canal dans lequel vous souhaitez publier les messages et cliquez sur Ajouter l’intégration:

Personnalisez les paramètres au besoin et copiez l’URl du Webhook:

Création d’une fonction Lambda
Vous êtes maintenant prêt à créer la fonction Lambda qui enverra les logs vers votre nouveau webhook Slack.
Dans le service Lambda de la console AWS, créez une nouvelle Function:

Dans le fichier index.php de la fenêtre de code, coller le code disponible plus bas:

Voici le code en question:
const zlib = require("zlib");
const https = require("https");
const SLACK_ENDPOINT =
"/services/xxxxxxxxxxxxzzzz"; // À remplacer par l'URL de votre Webhook
const SLACK_BOT = "Cloudwatch"; // Le nom du bot qui sera affiché
function doRequest(content) {
const obj = JSON.parse(content.message);
// formatting the message according Slack API
const payload = {
username: SLACK_BOT,
blocks: [
{
"type": "rich_text",
"elements": [
{
"type": "rich_text_preformatted",
"elements": [
{
"type": "text",
"text": JSON.stringify(obj, null, 4)
},
],
"border": 0
}
]
}
],
};
const payloadStr = JSON.stringify(payload);
const options = {
hostname: "hooks.slack.com",
port: 443,
path: SLACK_ENDPOINT,
method: "POST",
headers: {
"Content-Type": "application/json",
"Content-Length": Buffer.byteLength(payloadStr),
},
};
const postReq = https.request(options, function (res) {
const chunks = [];
res.setEncoding("utf8");
res.on("data", function (chunk) {
return chunks.push(chunk);
});
res.on("end", function () {
if (res.statusCode < 400) {
console.log("sent!!!");
} else if (res.statusCode < 500) {
console.error(
"Error posting message to Slack API: " +
res.statusCode +
" - " +
res.statusMessage
);
} else {
console.error(
"Server error when processing message: " +
res.statusCode +
" - " +
res.statusMessage
);
}
});
return res;
});
postReq.write(payloadStr);
postReq.end();
}
function main(event, context) {
context.callbackWaitsForEmptyEventLoop = true;
// always returns the last event
const payload = Buffer.from(event.awslogs.data, "base64");
const log = JSON.parse(zlib.gunzipSync(payload).toString("utf8"));
// the log is an object that contains an array of events called `logEvents` and we need access it bypassing the index 0
doRequest(log.logEvents[0]);
const response = {
statusCode: 200,
body: JSON.stringify("Event sent to Slack!"),
};
return response;
}
exports.handler = main;
Évidemment, vous devrez modifie la valeur de la constante SLACK_ENDPOINT pour y placer l’URL de votre webhook.
Cliquez ensuite sur Deploy pour déployer la fonction.
Création du déclencheur (trigger)
Dans le haut de la page, cliquez sur + Add trigger.

Dans la source, sélectionnez Cloudwatch Logs:

Sélectionnez ensuite le Log Group qui contient les logs que vous voulez envoyer vers Slack, donnez un nom à votre déclencheur et ajoutez un Filter pattern si vous le souhaitez:

Le Filter pattern « ?Error ?error ?ERROR » fera en sorte que seulement les événements de logs qui contiennent Error, error ou ERROR déclencheront votre fonction Lambda.
Cliquez sur Add pour ajouter le déclencheur.
Test
Pour tester, rendez-vous dans le log group en question et sélectionnez le plus récent log stream:

Cliquez ensuite sur Actions / Create log event:

Ajoutez, par exemple, ce log:
{
"message": "Severity: Notice --> Trying to access array offset on value of type null /file... line...",
"context": {
"url": "https://your-url.com",
"ip": "11.1.11.111"
},
"level": 400,
"level_name": "ERROR",
"channel": "illuxi-logger-staging",
"datetime": "2024-09-07T19:40:48.383092+00:00",
"extra": {}
}
Et voilà!






