web-dev-qa-db-ja.com

python AWS Lambdaを使用したロギング

AWSドキュメントが示唆するように:

import logging
logger = logging.getLogger()
logger.setLevel(logging.INFO)
def my_logging_handler(event, context):
    logger.info('got event{}'.format(event))
    logger.error('something went wrong')

今私は作った:

import logging
logging.basicConfig(level = logging.INFO)
logging.info("Hello World!")

コードの最初のスニペットは、Cloud Watchコンソール、2番目のコンソールはありません。

2つのスニペットがルートロガーを使用しているため、違いは見られませんでした。

33
p.magalhaes

質問@StevenBohrerの回答リンクの一番上の回答から直接コピーしました(これは私のためのトリックを行い、最後の行を自分の設定に置き換えました):

root = logging.getLogger()
if root.handlers:
    for handler in root.handlers:
        root.removeHandler(handler)
logging.basicConfig(format='%(asctime)s %(message)s',level=logging.DEBUG)
33
Brett Beatty

同様の問題がありましたが、ラムダコードがインポートされる前に、ラムダコンテナがlogging.basicConfigを呼び出してハンドラを追加していると思われます。これは悪い形のようです...

回避策は、ルートロガーハンドラーが構成されているかどうかを確認し、構成されている場合はそれらを削除し、フォーマッターと目的のログレベルを(basicConfigを使用して)追加し、ハンドラーを復元します。

この記事を参照してください logging.basicConfigを実行する前のPythonロギング?

14
Steven Bohrer

ロギングが機能しないように見える理由は、AWS Lambda Python runtime 事前設定のロギングハンドラー 、選択したランタイムのバージョンに応じて、ログに記録されるメッセージの形式を変更し、利用可能な場合はレコードにメタデータを追加することもできます。not事前設定されているのはログレベルです。つまり、送信しようとするログメッセージの種類に関係なく、実際には印刷されません。

AWSドキュメント自体 のように、AWS Lambdaコンテキストでloggingライブラリを正しく使用するには、ルートロガーのログレベルを設定するだけです。

import logging
logging.getLogger().setLevel(logging.INFO)

PythonスクリプトをAWS Lambdaで実行可能にするだけでなく、ローカルPythonインタープリターも使用したい場合は、ハンドラーが構成されているかどうかを確認し、basicConfig(デフォルトのstderr-handlerを作成します)それ以外の場合:

if len(logging.getLogger().handlers) > 0:
    # The Lambda environment pre-configures a handler logging to stderr. If a handler is already configured,
    # `.basicConfig` does not execute. Thus we set the level directly.
    logging.getLogger().setLevel(logging.INFO)
else:
    logging.basicConfig(level=logging.INFO)
4
Pit

実際には、おそらく同じロガーを参照していないでしょう。最初のスニペットで、次の戻り値をログに記録します:logging.Logger.manager.loggerDict

すでに初期化されているロガーのdictを返します。

また、loggingドキュメントから、logging.basicConfigに関する重要な注意事項:

デフォルトのFormatterでStreamHandlerを作成し、それをルートロガーに追加することにより、ロギングシステムの基本設定を行います。ルートロガーにハンドラが定義されていない場合、関数debug()、info()、warning()、error()およびcritical()はbasicConfig()を自動的に呼び出します。

この機能は、ルートロガーにハンドラーがすでに設定されている場合は何もしません。

ソース: https://docs.python.org/2/library/logging.html#logging.basicConfig

3
HEADLESS_0NE

私はこの正確な問題に苦労しました。ローカルとAWS CloudWatchの両方で機能するソリューションは、次のようにログを設定することです。

import logging

# Initialize you log configuration using the base class
logging.basicConfig(level = logging.INFO)

# Retrieve the logger instance
logger = logging.getLogger()

# Log your output to the retrieved logger instance
logger.info("Python for the win!")

0
Kinman

基本的に、AWSログモンキーパッチは、非常に特定の方法で処理する必要があります。

  1. ログレベルは、スクリプトのトップレベルから設定されます(インポート時など)
  2. 関心のあるログステートメントは、ラムダ関数内から呼び出されます

一般的に、Pythonモジュールインポートで任意のコードを実行しない方が良いと考えられているため、通常、ラムダ関数の内部でのみ重荷が発生するようにコードを再構築できるはずです。

0
Edward Z. Yang