0
1

More than 3 years have passed since last update.

[AWS] CloudWatch Logsを監視し、Slackに通知するLambda関数の例

Posted at

概要

Lambdaを使用してCloudWatch Logsを監視し、Slack通知を作ったときのLambda関数のソースの共有です。

以下の解説は省略します。

  • CloudWatch Logsへログの出力
  • Lambda関数の登録方法
  • Slack Incoming Webhookの設定

Lambda関数(Python3)

LaravelのログをJSON形式にしたものを処理しています。
ご自身の環境に合わせて修正してください。

# -*- coding: utf-8 -*-
import base64
import json
import urllib.request
import zlib

def lambda_handler(event, context):
    # print("Received event: " + json.dumps(event, indent=2))
    data = zlib.decompress(base64.b64decode(event['awslogs']['data']), 16+zlib.MAX_WBITS)
    data_json = json.loads(data)

    try:
        for item in data_json['logEvents']:
            # ↓↓↓ JSONの処理。適宜修正してください。 ↓↓↓
            # JSONフォーマット以外は処理しない
            try:
                log_json = json.loads(item['message'])
                # print(log_json)
            except json.JSONDecodeError as e:
                continue

            # JSONフォーマットが合わないものは無視
            if not 'level' in log_json.keys():
                continue
            # ログレベルが300(WARNING)以下はSlack通知しない
            if log_json['level'] <= 300:
                continue

            # Slack通知内容の整形
            log_text = '[ロググループ] ' + data_json['logGroup'] + '\n'
            log_text += '[ログストリーム] ' + data_json['logStream'] + '\n'
            log_text += '[ログレベル] ' + log_json['level_name'] + '\n'
            log_text += '[発生日時] ' + log_json['datetime'] + '\n'
            log_text += '[エラー内容]\n' + json.dumps(log_json['context'], ensure_ascii=False, indent=4, sort_keys=False, separators=(',', ': ')) + '\n'
            # print(log_text)
            # ↑↑↑ JSONの処理。適宜修正してください。 ↑↑↑

            send_data = {
                "username": "Lambda bot",
                "text": log_text,
            }
            send_text = "payload=" + json.dumps(send_data)

            request = urllib.request.Request(
                'https://hooks.slack.com/services/xxx',
                data=send_text.encode("utf-8"),
                method="POST"
            )
            with urllib.request.urlopen(request) as response:
                response_body = response.read().decode("utf-8")

    except Exception as e:
        print(e)

JSONログの例

以下はCloudWatch Logsで収集しているログのサンプルです。

{
    "message": "SQLSTATE[42S22]: Column not found: 1054 Unknown column 'xxx' in 'where clause' (SQL: xxx)",
    "context": {
        "exception": {
            "class": "Illuminate\\Database\\QueryException",
            "message": "SQLSTATE[42S22]: Column not found: 1054 Unknown column 'xxx' in 'where clause' (SQL: xxx)",
            "code": 42,
            "file": "/var/www/vendor/laravel/framework/src/Illuminate/Database/Connection.php:671",
            "trace": [
                "/var/www/vendor/laravel/framework/src/Illuminate/Database/Connection.php:631",
                〜略〜
            ],
            "previous": {
                "class": "Doctrine\\DBAL\\Driver\\PDO\\Exception",
                "message": "SQLSTATE[42S22]: Column not found: 1054 Unknown column 'xxx' in 'where clause'",
                "code": 42,
                "file": "/var/www/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDO/Exception.php:18",
                "trace": [
                    "/var/www/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOConnection.php:83",
                    〜略〜
                ],
                "previous": {
                    "class": "PDOException",
                    "message": "SQLSTATE[42S22]: Column not found: 1054 Unknown column 'xxx' in 'where clause'",
                    "code": 42,
                    "file": "/var/www/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOConnection.php:78",
                    "trace": [
                        "/var/www/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOConnection.php:78",
                        〜略〜
                    ]
                }
            }
        }
    },
    "level": 400,
    "level_name": "ERROR",
    "channel": "local",
    "datetime": "2021-02-15T10:38:44.466256+09:00",
    "extra": {}
}
0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1