Get in touch
or send us a question?
CONTACT

Cách nhận thông báo về các mẫu lỗi hàm Lambda cụ thể bằng CloudWatch

Bài đăng này trình bày cách tự động hóa thông báo cảnh báo cho các lỗi chức năng AWS Lambda cụ thể bằng cách sử dụng đăng ký nhật ký Amazon CloudWatch . Nhật ký CloudWatch cho phép bạn gọi một hàm Lambda khi mục nhập nhật ký khớp với một mẫu. Báo động Amazon CloudWatch được sử dụng để thông báo khi xảy ra lỗi với một hàm Lambda; thông báo này không cung cấp bất kỳ thông tin cụ thể nào về lỗi. Đối với các tình huống mà bạn cần thông tin cụ thể về lỗi trong thông báo, bạn có thể sử dụng đăng ký Nhật ký CloudWatch. Đăng ký Nhật ký CloudWatch cho phép bạn khớp các mục nhập với một mẫu lỗi cụ thể trong nhật ký của mình và được thông báo với các chi tiết lỗi đó. Điều này giúp bạn tiết kiệm một bước bổ sung để phân tích qua các nhật ký và thực hiện hành động cần thiết. Bạn cũng có thể sử dụng điều này như một bản thiết kế để xây dựng các biện pháp phản ứng tự động khi phát hiện mẫu lỗi đó trong hàm Lambda của mình.

Bài đăng này hướng dẫn bạn cách cấu hình đăng ký nhật ký CloudWatch kích hoạt hàm AWS Lambda để xử lý nhật ký. Hàm Lambda sử dụng Amazon SNS để gửi email có thông tin chi tiết về lỗi cụ thể và vị trí nhật ký.

Tổng quan về giải pháp

Kiến trúc cho giải pháp này khá đơn giản. Bạn có một loạt các hàm Lambda mà bạn muốn được thông báo về các lỗi nghiêm trọng cụ thể. CloudWatch Logs sẽ ghi lại các bản ghi từ các hàm Lambda này. Nó sẽ gọi hàm Lambda “xử lý lỗi” khi một mục nhật ký khớp với một mẫu bộ lọc, ví dụ: ERROR, CRITICAL hoặc lỗi tùy chỉnh. Hàm Lambda xử lý lỗi này sẽ lần lượt xuất bản một thông báo đến một chủ đề Amazon SNS, có thể đăng ký để nhận email khi lỗi xảy ra.

Đối với mục đích của bài đăng này, chúng tôi sẽ sử dụng hàm Lambda tạo lỗi mẫu sau:

import logging
import os

logging.basicConfig(level=logging.DEBUG)
logger=logging.getLogger(__name__)


def lambda_handler(event, context):
    logger.setLevel(logging.DEBUG)
    logger.debug("This is a sample DEBUG message.. !!")
    logger.error("This is a sample ERROR message.... !!")
    logger.info("This is a sample INFO message.. !!")
    logger.critical("This is a sample 5xx error message.. !!")

Hướng dẫn triển khai

Điều kiện tiên quyết

Để triển khai giải pháp này, bạn phải tạo:

  • Một chủ đề SNS
  • Vai trò IAM
  • Một hàm Lambda
  • Một trình kích hoạt nhật ký CloudWatch

Bước 1: Tạo chủ đề SNS

Để tạo chủ đề SNS, hãy hoàn thành các bước sau:

  1. Mở bảng điều khiển Amazon SNS .
  2. Trong ngăn điều hướng bên trái, chọn Chủ đề .
  3. Chọn Tạo chủ đề . Đối với Tên chủ đề , hãy nhập tên và chọn Tạo chủ đề . Bây giờ bạn có thể thấy trang MySNSTopic . Phần Chi tiết hiển thị Tên chủ đề , ARN , Tên hiển thị (tùy chọn) và ID tài khoản AWS của chủ sở hữu Chủ đề .
  4. Trong phần Chi tiết, hãy sao chép ARN chủ đề vào bảng tạm, ví dụ:arn:aws:sns:us-east-1:123456789012:MySNSTopic
  5. Trong ngăn điều hướng bên trái, chọn Đăng ký và Tạo đăng ký .
  6. Trên trang Tạo đăng ký , hãy thực hiện như sau:
    1. Nhập ARN chủ đề của chủ đề bạn đã tạo trước đó:arn:aws:sns:us-east-1:123456789012:MySNSTopic
    2. Đối với Giao thức , hãy chọn Email .
    3. Đối với Điểm cuối , hãy nhập địa chỉ email có thể nhận thông báo.
    4. Chọn Tạo đăng ký .
  7. Lưu ý rằng đối với đăng ký qua email, bạn phải xác nhận đăng ký bằng cách nhấp vào liên kết xác nhận đăng ký mà bạn sẽ nhận được qua email. Sau khi đăng ký được xác nhận, bạn đã sẵn sàng nhận thông báo qua email.

Bước 2: Tạo vai trò IAM

Để tạo vai trò IAM, hãy hoàn tất các bước sau. Để biết thêm thông tin, hãy xem Tạo vai trò IAM .

  1. Trong bảng điều khiển IAM , chọn Chính sách từ ngăn điều hướng bên trái và chọn Tạo chính sách .
  2. Chọn tab JSON và nhập chính sách IAM sau, thay thế ARN chủ đề bằng ARN chủ đề SNS mà bạn đã tạo ở bước trước:
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "sns:Publish",
            "Resource": "arn:<partition>:sns:<region>:<AWS account number>:<name of the SNS topic from previous step>"
        },
        {
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ],
            "Resource": "arn:<partition>:logs:<region>:<AWS account number>:log-group:/aws/lambda/<name of the lambda function you are going to create in next step>:*"
        }
    ]

3. Chọn Chính sách đánh giá .

4. Nhập tên ( MyCloudWatchRole ) cho chính sách này và chọn Tạo chính sách . Ghi chú tên của chính sách này cho các bước sau.

5. Trong ngăn điều hướng bên trái, chọn Vai trò và chọn Tạo vai trò .

6. Trên trang Chọn loại vai trò , hãy chọn dịch vụ AWS làm thực thể đáng tin cậy của bạn và chọn Lambda trong các trường hợp sử dụng phổ biến.

7. Chọn Tiếp theo: Quyền.

8. Lọc chính sách theo tên chính sách bạn vừa tạo và chọn hộp kiểm.

9. Chọn Tiếp theo: Thẻ và đặt thẻ thích hợp.

10. Chọn Tiếp theo: Xem lại . Đặt tên phù hợp cho vai trò IAM này và ghi chú lại để sử dụng sau này.

11. Chọn Tạo vai trò .

Bước 3: Tạo hàm Lambda

Để tạo hàm Lambda, hãy hoàn tất các bước sau. Để biết thêm thông tin, hãy xem Tạo hàm Lambda bằng bảng điều khiển .

  1. Trong bảng điều khiển Lambda , chọn Tác giả từ đầu .
  2. Đối với Tên hàm , hãy nhập tên hàm của bạn.
  3. Đối với Runtime , hãy chọn Python 3.7 .
  4. Đối với vai trò Thực thi , hãy chọn Sử dụng vai trò hiện có , sau đó chọn vai trò IAM đã tạo ở bước trước.
  5. Chọn Create Function , xóa hàm mặc định và sao chép đoạn mã sau vào cửa sổ Function Code:
# Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
# Licensed under the Apache License, Version 2.0 (the "License").
# You may not use this file except in compliance with the License.
# A copy of the License is located at## http://aws.amazon.com/apache2.0/
# or in the "license" file accompanying this file.
# This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
# either express or implied. See the License for the specific language governing permissions
# and limitations under the License.
# Description: This Lambda function sends an email notification to a given AWS SNS topic when a particular
#              pattern is matched in the logs of a selected Lambda function. The email subject is
#              Execution error for Lambda-<insert Lambda function name>.
#              The JSON message body of the SNS notification contains the full event details.

# Author: Sudhanshu Malhotra

import base64
import boto3
import gzip
import json
import logging
import os

from botocore.exceptions import ClientError

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)


def logpayload(event):
    logger.setLevel(logging.DEBUG)
    logger.debug(event['awslogs']['data'])
    compressed_payload = base64.b64decode(event['awslogs']['data'])
    uncompressed_payload = gzip.decompress(compressed_payload)
    log_payload = json.loads(uncompressed_payload)
    return log_payload


def error_details(payload):
    error_msg = ""
    log_events = payload['logEvents']
    logger.debug(payload)
    loggroup = payload['logGroup']
    logstream = payload['logStream']
    lambda_func_name = loggroup.split('/')
    logger.debug(f'LogGroup: {loggroup}')
    logger.debug(f'Logstream: {logstream}')
    logger.debug(f'Function name: {lambda_func_name[3]}')
    logger.debug(log_events)
    for log_event in log_events:
        error_msg += log_event['message']
    logger.debug('Message: %s' % error_msg.split("\n"))
    return loggroup, logstream, error_msg, lambda_func_name


def publish_message(loggroup, logstream, error_msg, lambda_func_name):
    sns_arn = os.environ['snsARN']  # Getting the SNS Topic ARN passed in by the environment variables.
    snsclient = boto3.client('sns')
    try:
        message = ""
        message += "\nLambda error  summary" + "\n\n"
        message += "##########################################################\n"
        message += "# LogGroup Name:- " + str(loggroup) + "\n"
        message += "# LogStream:- " + str(logstream) + "\n"
        message += "# Log Message:- " + "\n"
        message += "# \t\t" + str(error_msg.split("\n")) + "\n"
        message += "##########################################################\n"

        # Sending the notification...
        snsclient.publish(
            TargetArn=sns_arn,
            Subject=f'Execution error for Lambda - {lambda_func_name[3]}',
            Message=message
        )
    except ClientError as e:
        logger.error("An error occured: %s" % e)


def lambda_handler(event, context):
    pload = logpayload(event)
    lgroup, lstream, errmessage, lambdaname = error_details(pload)
    publish_message(lgroup, lstream, errmessage, lambdaname)

6. Trong phần Biến môi trường , hãy nhập cặp khóa-giá trị sau:

  • Khóa = snsARN
  • Giá trị = ARN của MySNSTopic được tạo trước đó

7. Chọn Lưu .

Bước 4. Tạo trình kích hoạt nhật ký CloudWatch

  1. Để thêm kích hoạt, hãy chọn Thêm kích hoạt rồi chọn Nhật ký CloudWatch từ danh sách thả xuống.
  2. Trong Log group , hãy chọn tên nhóm nhật ký CloudWatch cho hàm Lambda mà bạn muốn nhận thông báo lỗi. Trong trường hợp của chúng tôi, đây sẽ là nhóm nhật ký cho hàm Lambda tạo lỗi mẫu đã thảo luận ở trên.
  3. Nhập giá trị phù hợp cho Tên bộ lọc và trong Mẫu bộ lọc , nhập giá trị bộ lọc cho nhật ký mà bạn muốn được thông báo. Ví dụ: “ ?ERROR ?WARN ?5xx ” sẽ lọc các thuật ngữ như ERROR, WARN hoặc 5xx trong nhật ký. Tài liệu cú pháp bộ lọc và mẫu nhật ký chứa nhiều ví dụ hơn cho các mẫu phức tạp khác.Ảnh chụp màn hình cấu hình kích hoạt hàm Lambda hiển thị với mẫu bộ lọc- ?ERROR ?WARN ?5xx
  4. Kích hoạt trình kích hoạt và Thêm .

Xác thực giải pháp

Để xác thực giải pháp của mình, tôi sẽ chạy hàm Lambda tạo lỗi mẫu và lọc theo mẫu “ ?ERROR ?WARN ?5xx ” để nhận thông báo qua email như sau:

ảnh chụp màn hình thông báo qua email hiển thị các thông báo lỗi cụ thể như [ERROR] và [CRITICAL]

Tương tự như vậy, tôi có thể tạo mẫu bộ lọc cho bất kỳ lỗi cụ thể nào, ví dụ lỗi 5xx như được hiển thị và nhận được thông báo sau về thông báo lỗi đó: