質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.46%
Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

1213閲覧

pythonのloggingにて、想定した値が取得できない。

takuyatakkyu

総合スコア17

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2021/11/17 10:22

サンプルコード

python

1# これがmain.pyです 2import logging 3from logging import getLogger, StreamHandler, FileHandler, Formatter 4 5# -------------------------------------------------- 6# log関連の宣言 7# -------------------------------------------------- 8# loggerオブジェクトの宣言 9logger = logging.getLogger(__name__) 10# loggerのログレベル設定(ハンドラに渡すエラーメッセージのレベル) 11logger.setLevel(logging.INFO) 12# logのフォーマット 13handler_format = Formatter('%(asctime)s %(levelname)-8s [%(module)s#%(funcName)s %(lineno)d] %(message)s') 14 15# ---- 標準出力のhandler ---- 16# コンソール用のhandlerの生成 17stream_handler = StreamHandler() 18# handlerのログレベル設定(ハンドラが出力するエラーメッセージのレベル) 19stream_handler.setLevel(logging.INFO) 20# ログ出力フォーマット設定 21stream_handler.setFormatter(handler_format) 22 23# ---- ログファイル出力のhandler ---- 24# ログファイル用のhandlerの生成 25file_handler = FileHandler('error.log', encoding='utf-8') 26# handlerのログレベル設定(ハンドラが出力するエラーメッセージのレベル) 27file_handler.setLevel(logging.WARNING) 28# ログ出力フォーマット設定 29file_handler.setFormatter(handler_format) 30 31# ---loggerにhandlerをセット--- 32# 標準出力のhandlerをセット 33logger.addHandler(stream_handler) 34# ログファイル出力のhandlerをセット 35logger.addHandler(file_handler) 36 37# mainの開始ログをコンソールに表示 38logger.info("開始") 39logger.error("エラー")

python

1# こちらがtest.pyです 2import logging 3 4class Test(): 5 def __init__(self): 6 # ロガーを取得する 7 self.logger = logging.getLogger(__name__) 8 9 def log_write(): 10 # ログ出力 11 self.logger.debug('DEBUGレベルのメッセージです') 12 self.logger.info('INFOレベルのメッセージです') 13 self.logger.warning('WARNINGレベルのメッセージです') 14 self.logger.error('ERRORレベルのメッセージです') 15 self.logger.critical('CRITICALレベルのメッセージです')

terminal

12021-11-17 18:08:57,448 INFO [main#<module> 47] 開始 22021-11-17 18:08:57,448 ERROR [main#<module> 48] エラー 3WARNINGレベルのメッセージです 4ERRORレベルのメッセージです 5CRITICALレベルのメッセージです 62021-11-17 18:09:23,046 INFO [main#<module> 105] 終了

log

1(これがerror.logです) 22021-11-17 18:08:57,448 ERROR [main#<module> 48] エラー

実現したいこと

・test.pyで記入したlogがターミナルに表示されましたが、フォーマットが適用されません。

2021-11-17 18:08:57,448 INFO [main#<module> 47] 開始 2021-11-17 18:08:57,448 ERROR [main#<module> 48] エラー 2021-11-17 18:08:57,448 WARNING [test#<module> 47] WARNINGレベルのメッセージです 2021-11-17 18:08:57,448 ERROR [test#<module> 48] ERRORレベルのメッセージです 2021-11-17 18:08:57,448 CRITICAL [test#<module> 49] CRITICALレベルのメッセージです 2021-11-17 18:09:23,046 INFO [main#<module> 105] 終了

上記のようにターミナルに表示されることが理想です。

・error.logにもフォーマットが適用された状態でtest.pyでのlogを表示させたいです。

2021-11-17 18:08:57,448 ERROR [main#<module> 48] エラー 2021-11-17 18:08:57,448 WARNING [test#<module> 47] WARNINGレベルのメッセージです 2021-11-17 18:08:57,448 ERROR [test#<module> 48] ERRORレベルのメッセージです 2021-11-17 18:08:57,448 CRITICAL [test#<module> 49] CRITICALレベルのメッセージです

上記のようにerror.logに表示されることが理想です。

最後に

初歩的な質問で申し訳ありません。
しかし、自分なりに調べても出てこなかったため、お力を貸して頂けると幸いです。
何か不足している情報があれば遠慮なくお申し付けください。
よろしくお願い致します。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

quickquip

2021/11/17 11:13

Pythonは3.7以前のものですか?
takuyatakkyu

2021/11/17 11:23

バージョンは3.9を使用しております!!
guest

回答1

0

ベストアンサー

pythonのloggingモジュールでは、1つのプログラムの中で複数のロガーオブジェクトを持つことができます。親子関係にもできるし、別々のオブジェクトにすることもできます。
logging.getLogger("one") と logging.getLogger("two") は別のロガーオブジェクトです。
logging.getLogger("p") と logging.getLogger("p.c1") は親子関係のあるロガーオブジェクトです。

__name__ は、pythonの特殊変数で、モジュールのファイル名か、直接起動された時には、"main"という値を持ちます。

ということで、おわかりと思いますが、
質問の状況は、別のコードで「logging.getLogger(name)」と書いているので、それらは別のロガーオブジェクトになり、設定は片方にしか反映されません。
同じロガーにするには、__name__を使わず、何も設定しない(ルートロガーと呼ばれるロギーオブジェクトが取得できます)か、固定の文字列にするのが簡単でしょう。

ちゃんと親子関係にする方法もありますので、ドキュメントを参照してみてください。

投稿2021/11/17 12:00

TakaiY

総合スコア12832

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

takuyatakkyu

2021/11/17 13:59

回答ありがとうございます。 親子関係にするという記事も調べる中で見かけたのですが、例えば logger = getLogger("main").getChild("test")として親子関係にした場合、 モジュールの表示で 2021-11-06 20:30:30,681 - main.test - DEBUG - Hi! のように、ドットで階層のような表記になってしまうのではと思い採用を見送っておりました。 親子関係にしてもモジュール名だけをコンソールで表示させるといった方法はあるのでしょうか?
TakaiY

2021/11/17 14:45 編集

出力にモジュール名を表示したいのであれば、フォーマッタの文字列に モジュール名(${module}s)を入れればいいでしょう。 main.testと表示されるのは、 %{name}s のように、ロガーの名前をログに入れているからですが、表示しなければならないわけではないので、不要であれば入れなければOKです。 ちなみに、ロガーの名前にモジュール名を入れる必要はありません。(入れることが多いでしょうけど。) ご存知とは思いますが、フォーマッタに使える変数はここで確認できます。 https://docs.python.org/ja/3/library/logging.html#logrecord-attributes
takuyatakkyu

2021/11/18 00:16

ご回答ありがとうございます。 全て解決いたしました!!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.46%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問