1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Python】自作モジュールでも使える特殊なloggerを簡潔に書きたい時【logging】

Posted at

特殊なloggerとは?

loggingと言えばlogging.iniとかloggingConfigDictとかいろいろあるけど、
例えば、googleのCloud LoggingとかにAI Platformのログを貯めたい時にこんな書き方をします。

loggingの書き方}
import logging
import google.cloud.logging_v2
from google.cloud.logging_v2.handlers import CloudLoggingHandler
from google.cloud.logging_v2.resource import Resource

client = google.cloud.logging_v2.Client(project=os.environ["PROJECT_ID"])
handler = CloudLoggingHandler(client, resource=Resource(
    "ml_job",
    {
        "task_name": "hoge",
        "project_id": os.environ["PROJECT_ID"],
        "job_id": os.environ["CLOUD_ML_JOB_ID"]
    }
)
)
LOGGER = logging.getLogger(__name__)
LOGGER.setLevel(logging.INFO)
LOGGER.addHandler(handler)

ちょっとこれはlogging.iniに書けんなーと思って、
だけどちゃんとモジュールを呼んだらLoggingして欲しい訳です。結構苦しみましたが、うまく動作した例を紹介します。

成功例

以下のようにファイルを整理

main.py}
from logger import get_logger, set_logger
from module import module
set_logger()
LOGGER = get_logger()


def another():
  LOGGER.info("another")

def main():
  LOGGER.info("start")
  another()
  module()
  LOGGER.info("end")

if __name__ == "__main__":
  main()
module.py}
from logger import get_logger
# 呼び出したいモジュール

def module():
  global LOGGER
  LOGGER = get_logger()
  LOGGER.info("test")
  module2()

def module2():
  LOGGER.info("test2")
logger.py}
import logging

def set_logger():
  global LOGGER
  LOGGER = logging.getLogger(__name__)
  LOGGER.setLevel(logging.INFO)
  ch = logging.StreamHandler()
  ch.setLevel(logging.DEBUG)
  formatter = logging.Formatter("%(levelname)s - %(message)s")
  ch.setFormatter(formatter)
  LOGGER.addHandler(ch)
#今回は簡単な例としてStreamHandlerを使用。
  
def get_logger():
  return LOGGER

まず説明すると、Entrypointとなるmain.pyには必ずset_logger()を付け加えます。
するとlogger側でLOGGERの設定ができる事になります。
そして、get_logger()からLOGGERを取り出し、使用することができます。
ここまでは、単純なloggingと変わりません。

問題は別モジュールを呼び出した時、Entrypointで設定したLOGGERはどうやっても読めませんし、
かと言ってもう一度宣言をすると、二重でログを吐くことが分かっています。
なので、モジュールにおいては、get_logger()だけを使用し、そのLOGGERをGrobal設定することで、
モジュールファイル内のLOGGER全てで設定したLOGGERを使用することができます。

別の方法

別の方法があれば教えてください...もっと...もっと簡潔に書きたい...

参考文献

(あまり参考にできなかったですが、以下の方法もあるみたいです)

1
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
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?