Creación de una integración personalizada de CloudWatch Log para Slack con AWS Lambda
Existen integraciones de Slack para todo pero a veces necesitas algo más específico así que esta vez te voy a mostrar una forma de crear tu propia integración personalizable para recibir notificaciones cuando tu aplicación registre algo en CloudWatch.
Una integración a medida, ¿qué es?
Los webhooks son una forma sencilla de compartir información de fuentes externas con tu espacio de trabajo. Slack Help Center
La API para crear una integración es muy completa, por supuesto, depende de las cosas que quieras crear pero cubre lo suficiente para resolver todas las necesidades. Por otro lado, es una forma de tener control total de tu información y del formato utilizado para mostrarla en tu espacio de trabajo de Slack.
¿Qué es una función Lambda?
Básicamente es un fragmento de código que solo se ejecuta bajo demanda y el precio es más barato que otras integraciones de Slack que tienes que pagar aunque no se usen. Usando esta función puedes reducir un poco tus costes eliminando integraciones innecesarias ya que si solo necesitas enviar alertas de error, el uso de esta función debería ser muy poca porque claro, no queremos que nuestras aplicaciones en producción estén llenas de errores.
Creando la integración personalizada
Primero debes acceder a AWS Management Console
Crear un nuevo IAM role; se utilizará para acceder a los eventos de CloudWatchLogs.



Ahora necesitas crear 2 grupos de registro en CloudWatch,
/aws/lambda/Log2Slackyproduction-apio cualquier otro nombre que desees probar. Nota: La configuración de retención se utiliza para asignar una vida útil al registro.

Para crear la función lambda hay que ir a Lambda y hacer clic en el botón Crear, luego asigna un nombre, selecciona el lenguaje de ejecución (Node.js para este ejemplo) y asigna el rol creado previamente.


Añade un disparador para escuchar los eventos de CloudWatch.


Antes de añadir el código lambda es necesario crear una integración personalizada utilizando esta URL
https://{your-slack-workspace}.slack.com/apps/manage/custom-integrationsy, a continuación, hacer clic enIncoming WebhooksAhora haz clic en
Add to Slack.
- Seleccione un canal para publicar las alertas.
- Da clic en
Add Incoming Webhook integration. - Copia el valor de
Webhook URL.

Nota: En Ajustes de integración puedes asignar un nombre y un logotipo para darle un aspecto más agradable
Ha sido un largo camino hasta ahora, pero ahora estás muy cerca de completar la integración, da clic en el nombre de tu función para abrir el editor de código y, a continuación doble clic en el icono
index.jsy sustituye el contenido actual por el código siguiente.
const zlib = require('zlib') const https = require('https') const SLACK_ENDPOINT = '/services/T1N6FE97Y/B01NK2BR2CR/TrCYV2mkCIRaaxopcXYF3jyc' // don't use this endpoint, I removed it after publish this post const SLACK_BOT = 'Cloudwatch' function doRequest(content) { // formatting the message according Slack API const payload = { username: SLACK * BOT, blocks: [ { type: 'header', text: { type: 'plain_text', text: 'Whoops, looks like something went wrong 😞🤕', emoji: true } }, { type: 'section', fields: [ { type: 'mrkdwn', text: '<!here> the API is running into an issue' } ] }, { type: 'section', fields: [ { type: 'mrkdwn', text: '*Environment: * Production' } ] }, { type: 'section', fields: [ { type: 'mrkdwn', text: '*Message:\* *' + content.message + '\_' } ] }, { type: 'section', fields: [ { type: 'mrkdwn', text: '*Stacktrace:\*' } ] }, { type: 'section', text: { type: 'mrkdwn', text: '`' + JSON.stringify(content.original ? content.original : content) + '`' } }, { type: 'divider' } ] } 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 = mainDa clic en el botón
Deploypara completar la función.Probar, probar y probar. Hay dos maneras de probar la función:
- Creación de una
Log Streamdirectamente en elLog Groupa continuación, entrar en el flujo de registro y desencadenar un evento de registro manualmente.

Este es el resultado final tras el envío de un log de Cloudwatch a Slack 🎉

Recursos de Slack:
Reflexiones finales
Crear tu propia integración para registrar la información relevante sobre sus aplicaciones es muy fácil y si lo deseas puede personalizar cada tipo de nivel de registro para mostrar como success, info, warning o error proporcionando una manera fácil de solucionar los problemas sin perder tiempo comprobando los registros directamente en Cloudwatch.