はじめに
webサーバやアプリケーションサーバ等を構築する際に、ログをどう集め分析するかが課題になるが 単一のサーバでの分析であれば、CloudWatchLogsエージェントを使用すれば簡単なログの収集、分析、監視、可視化が可能になる。
本記事では詳細は紹介しないが、CloudWatchLogsではロググループごとに独自の検索(フィルタリング)が可能である。 aws公式ドキュメント
CloudWatchLogsはログをjsonで引き渡すとよいという話
ドキュメント見てもらうとわかると思うがいくつかのフィルタパターンを指定できる。そしてログがjson形式で出力されている場合、
{ $.Key = "Value" } { $.Key != "Value" } { $.Key[0] = "Value"}
などなどありがちなjson形式を指定でき便利である。
という事でpythonでjson形式のログを出力したい場合、次のようにformatter
をjson.dumps
してやればいい感じで出力される。
↓サンプルコード
import logging import sys import json def set_logger(logger_name,log_file_name): logger = logging.getLogger(logger_name) # ルートロガー設定 logger.setLevel(logging.DEBUG) # コンソール出力用のハンドラー to_stream = logging.StreamHandler(stream=sys.stdout) # ファイル出力用のハンドラー to_file = logging.handlers.FileHandler(filename=log_file_name) # ハンドラーごとの出力レベル定義 to_stream.setLevel(logging.DEBUG) to_file.setLevel(logging.INFO) # ハンドラーにセットするformatterを設定(時刻以外) jsonFormat = json.dumps(dict(level="%(levelname)s", time="%(asctime)s", function="%(funcName)s", message="%(message)s")) # 引数:fmtにformatterを渡す&時刻の書式を好みの形になるように引数:datefmtへ log_format = logging.Formatter(fmt=jsonFormat, datefmt="%Y-%m-%d %H:%M:%S") # それぞれのハンドラへformatterをセットしてやる to_stream.setFormatter(log_format) to_file.setFormatter(log_format) # ロガーへハンドラーを追加する logger.addHandler(to_stream) logger.addHandler(to_file) logger.INFO("Hello World") return logger
私は基本上記のようにモジュール化しておき、使い回す形にしている。
logger
を利用する場合でもルートのレベルはちゃんと設定し直すこと。(default:warningのためログが出ない!?みたいなことに陥る。ルートは個人的には最も低レベルなDEBUG
にしておき、ここのハンドラ、もしくは子loggerのレベルで調整してやるのが良い)
そしてこのコードだと以下の様、ログ出力が得られる。
{ "level": "INFO", "time": "2019-06-24 02:11:18", "function": "<module>", "message": "Hello World" }
具体的な値でフィルタリングをもう一度説明すると、例えばINFO
レベルのログだけを表示させたければ…
{ $.level = "INFO" }
でフィルタリングが可能になる。