Auto Trigger Notification to Discord/Teams/Slack
7458

1.1 Mục Tiêu

Tính năng này giúp:

  • Thu thập log từ ứng dụng backend qua AWS CloudWatch.
  • Phân loại lỗi thành hai kênh:
    • Tất cả lỗi (channel 1) → gửi đến Discord Webhook 1.
    • Lỗi nghiêm trọng (5xx, 4xx, Out-of-memory, etc.) (channel 2) → gửi đến Discord Webhook 2 kèm giải thích.
  • Tránh spam thông báo lặp lại (cùng một lỗi xuất hiện nhiều lần trong thời gian ngắn).

1.2 Kiến Trúc

Hệ thống hoạt động như sau:

  1. Ứng dụng Backend chạy bằng PM2, ghi log vào file.
  2. PM2-CloudWatch đẩy log từ backend lên AWS CloudWatch Logs.
  3. CloudWatch LogsSubscription Filter để gửi log đến AWS Lambda.
  4. AWS Lambda thực hiện:
    • Lọc chỉ những log có lỗi (errors - ...).
    • Phân tích xem lỗi có nghiêm trọng không.
    • Chuẩn hóa lỗi để tránh spam (nếu cùng lỗi xuất hiện trong vòng 5 phút, không gửi lại).
    • Gửi lỗi đến Discord Webhook.
  5. AWS S3 lưu cache lỗi để tránh thông báo lặp lại.

1.3 Cách Cài Đặt

Bước 1: Cấu hình Webhook Discord

Trên Discord:

  1. Vào Server SettingsIntegrationsWebhooks.
  2. Tạo 2 webhook:
    • DISCORD_WEBHOOK_ALL → gửi tất cả lỗi.
    • DISCORD_WEBHOOK_CRITICAL → gửi lỗi nghiêm trọng.
  3. Lưu lại 2 URL webhook để sử dụng trong AWS Lambda.

Bước 2: Cấu hình AWS S3 để lưu cache lỗi

  • Tạo một S3 bucket để lưu danh sách lỗi đã gửi nhằm tránh spam:
    aws s3 mb s3://my-error-cache-bucket

Bước 3: Viết AWS Lambda để xử lý log

  1. Tạo Lambda Function

    • Chọn Runtime: Node.js 18.x.
    • Gán các biến môi trường:
      DISCORD_WEBHOOK_ALL=<URL_webhook_all>
      DISCORD_WEBHOOK_CRITICAL=<URL_webhook_critical>
      S3_BUCKET=my-error-cache-bucket
      S3_KEY=errors.json
      
  2. Code Lambda xử lý log (Node.js)

    const AWS = require("aws-sdk");
    const https = require("https");
    
    const s3 = new AWS.S3();
    const bucketName = process.env.S3_BUCKET;
    const s3Key = process.env.S3_KEY;
    const webhookAll = process.env.DISCORD_WEBHOOK_ALL;
    const webhookCritical = process.env.DISCORD_WEBHOOK_CRITICAL;
    
    async function getErrorCache() {
        try {
            const data = await s3.getObject({ Bucket: bucketName, Key: s3Key }).promise();
            return JSON.parse(data.Body.toString());
        } catch (error) {
            return {};
        }
    }
    
    async function updateErrorCache(cache) {
        await s3.putObject({
            Bucket: bucketName,
            Key: s3Key,
            Body: JSON.stringify(cache),
            ContentType: "application/json"
        }).promise();
    }
    
    function sendToDiscord(webhook, message) {
        const data = JSON.stringify({ content: message });
    
        const options = {
            hostname: "discord.com",
            path: webhook.replace("https://discord.com", ""),
            method: "POST",
            headers: {
                "Content-Type": "application/json",
                "Content-Length": data.length
            }
        };
    
        const req = https.request(options, res => {
            console.log(`Status: ${res.statusCode}`);
        });
    
        req.on("error", error => console.error(error));
        req.write(data);
        req.end();
    }
    
    exports.handler = async (event) => {
        const logs = event.awslogs.data;
        const decodedLogs = Buffer.from(logs, "base64").toString("utf-8");
        
        if (!decodedLogs.includes("errors -")) return;
        
        const errorCache = await getErrorCache();
        const now = Date.now();
    
        if (errorCache[decodedLogs] && now - errorCache[decodedLogs] < 300000) {
            return; // Lỗi đã gửi trong 5 phút, bỏ qua.
        }
    
        errorCache[decodedLogs] = now;
        await updateErrorCache(errorCache);
    
        sendToDiscord(webhookAll, `📌 **Lỗi mới:**\n${decodedLogs}`);
    
        if (decodedLogs.includes("5xx") || decodedLogs.includes("Out-of-memory")) {
            sendToDiscord(webhookCritical, `🚨 **Lỗi nghiêm trọng:**\n${decodedLogs}`);
        }
    };
    

     


Bước 4: Thiết lập CloudWatch Logs Subscription Filter

  • Mở AWS CloudWatch LogsChọn Log Group của ứng dụng.
  • Chọn Subscription FilterTạo mới.
  • Chọn Gửi log đến AWS Lambda function vừa tạo.
  • Thiết lập filter pattern:
    { $.level = "error" }
    
    hoặc
    "errors -"
    
  • Lưu lại.

Bước 5: Kiểm tra hoạt động

  1. Tạo lỗi trong ứng dụng backend để sinh log.
  2. Kiểm tra trên Discord:
    • Nếu lỗi thông thường → xuất hiện trong kênh all-errors.
    • Nếu lỗi nghiêm trọng → xuất hiện trong cả all-errorscritical-errors.
  3. Gửi cùng lỗi nhiều lần trong 5 phút để kiểm tra cơ chế chống spam.

1.4 Mở Rộng

  • Điều chỉnh thời gian kiểm tra lỗi trùng bằng cách thay đổi 300000 (5 phút) trong errorCache.
  • Thêm nhiều pattern nhận diện lỗi khác như Connection Timeout, Database Error.
  • Gửi thông báo qua Slack, Teams, không chỉ Discord.

Tổng Kết

  • Tích hợp AWS CloudWatch Logs với AWS Lambda để xử lý log.
  • Phân loại lỗi và gửi thông báo đến Discord.
  • Tránh spam lỗi lặp trong khoảng thời gian ngắn.
  • Dễ dàng mở rộng với các hệ thống chat khác như Slack, Teams.

Danh mục


  1. Khác
  2. ThreeJS
  3. Ubuntu/Linux
  4. HTML/CSS
  5. Git
  6. Amazon Web Services
  7. Javascript
  8. Docker
  9. Laravel

Bài viết liên quan


AWS S3

AWS S3

27.09.2024
Author: ADMIN
AWS S3 là một dịch vụ lưu trữ đối tượng mạnh mẽ và linh hoạt. Bài viết này sẽ giúp bạn hiểu rõ về S3, từ các khái niệm cơ bản đến cách cấu hình chi tiết. Cùng với đó là hướng dẫn từng bước để tạo bucket, upload object, phân quyền và tạo bucket policy. Giú
AWS Region

AWS Region

27.09.2024
Author: ADMIN
Bài viết này giải thích chi tiết về AWS Region, bao gồm đặc điểm, lợi ích và cách chọn Region phù hợp. Tìm hiểu về Availability Zones, tuân thủ quy định, tối ưu hóa chi phí và giảm độ trễ. Nắm vững kiến thức để triển khai ứng dụng đám mây hiệu quả.
Maintenance Mode

Maintenance Mode

05.02.2025
Author: ADMIN
Tự động hóa Maintenance Mode Nginx với file flag, IP whitelist, script và tích hợp CI/CD (GitHub Actions). Hướng dẫn từng bước cấu hình Nginx, script và workflow để bảo trì hệ thống hiệu quả.
CI/CD Pipeline

CI/CD Pipeline

05.02.2025
Author: ADMIN
Hướng dẫn chi tiết thiết lập CI/CD Pipeline tự động hóa build, test, deploy qua Bastion Host, dùng GitHub Actions/CodePipeline. Cấu hình SSH Proxy, triển khai staging & production an toàn, hiệu quả.

Bài viết khác

Routing

Routing

01.08.2024
Author: ADMIN
Hướng dẫn chi tiết về Basic Routing trong Laravel, từ cách định nghĩa route, sử dụng middleware, route caching đến route naming giúp tối ưu hóa ứng dụng.
Blade Basics

Blade Basics

01.08.2024
Author: ADMIN
Khám phá Blade trong Laravel: từ if-else, loops, kế thừa layout đến include sub-views. Giúp code gọn gàng, dễ quản lý và bảo trì hơn!
9 Mẹo Hữu Ích Khi Sử Dụng Blade Trong Laravel

9 Mẹo Hữu Ích Khi Sử Dụng Blade Trong Laravel

01.08.2024
Author: ADMIN
Khám phá 9 mẹo Blade giúp bạn viết code Laravel sạch, tối ưu và chuyên nghiệp hơn. Từ @forelse, @auth, @guest, đến format ngày, tối ưu SEO – tất cả trong một bài viết súc tích, dễ áp dụng!
Hiển thị giá trị trong Blade

Hiển thị giá trị trong Blade

01.08.2024
Author: ADMIN
Hướng dẫn hiển thị biến trong Laravel Blade: escape HTML tự động, hiển thị dữ liệu thô, giá trị mặc định và cách truy xuất mảng, đối tượng. Giúp bạn tối ưu hiển thị dữ liệu một cách an toàn!