

Windows 10  
Python 3.6

directory example

[code]

    |-- main.py
    |-- modules/
    |   |-- __init__.py
    |   `-- funcs.py
    `-- log/
        `-- root.log
    
[/code]

* * *

複数モジュールからロギングする(main.pyからもfuncs.pyからもログを出したい)場合，  
<https://docs.python.jp/3/howto/logging.html#logging-from-multiple-modules>  
の通りに行えば，問題なくログ出力ができます．

しかしローテートの方法をカスタマイズする場合，main.pyに  
<https://docs.python.jp/3/howto/logging-cookbook.html#using-a-rotator-and-
namer-to-customize-log-rotation-processing>  
のように記述し，ロガーにハンドラを与えたところ，main.pyからのログに対してはローテートのカスタマイズが適用されました．  
このときfuncs.pyからのログに対しても同様のカスタマイズを適用したい場合，funcs.pyにはどのように記述すべきでしょうか(同じログファイル`/log/root.log`に出力したい)．  
main.pyと全く同じように記述すると，`PermissionError: [WinError 32]`となります．

＋α  
できれば`logging.config.fileConfig(...)`で設定を読み込めると，もっとプログラムがスッキリすると思うのですが，ローテートのカスタマイズを適用したい場合はやりようがないですかね？

* * *

main.py

[code]

    import logging
    import modules.funcs
    
    logger = logging.getLogger()
    logger.setLevel(logging.DEBUG)
    trh = logging.handlers.TimedRotatingFileHandler(...)
    trh.rotator = rotator   # rotatorは別途作成
    logger.addHandler(trh)
    
    logger.debug('rotate test')
    
[/code]

funcs.py

[code]

    import logging
    
    logger = logging.getLogger()
    # ここで何らかの設定/記述をする?
    
    logger.debug('rotate test @funcs.py')
    
[/code]


CC BY-SA 4.0
2018-11-07T03:10:57.697
50037
2023-11-11T07:07:30.997
30876
question
python logging
Pythonのロギング／ローテート設定を複数モジュールで使いたい


`funcs.py`の方は何もしなくてもいいはずです。`funcs.py`で何かの設定をすると別のロガー・オブジェクトになるので、同じログファイルに出力しようとすると`PermissionError:
[WinError 32]`になります。

・公式ドキュメント logging --- Python 用ロギング機能
[ロガーオブジェクト](https://docs.python.org/ja/3.7/library/logging.html#logger-
objects)

> ロガーを直接インスタンス化することはできず、常にモジュール関数 logging.getLogger(name)
> を介してインスタンス化することに注意してください。同じ name で getLogger()
> を複数回呼び出すと、常に同じロガー・オブジェクトへの参照が返されます。
>
> name は foo.bar.baz のようにピリオドで分割された (ただし単なるプレーンな foo もありえます)
> 潜在的に階層的な値です。階層リスト中でより下位のロガーは、上位のロガーの子です。例えば、foo という名前を持つロガーがあるとき、foo.bar,
> foo.bar.baz, foo.bam という名前を持つロガーはすべて foo の子孫です。ロガー名の階層は Python
> パッケージ階層と類似していて、推奨される構築方法 `logging.getLogger(__name__)`
> を使用してロガーをモジュール単位で構成すれば、Python パッケージ階層と同一になります。これは、モジュールの中では `__name__` が
> Python パッケージ名前空間におけるモジュール名だからです。


CC BY-SA 4.0
2018-11-07T14:19:13.350
50067
2018-11-07T14:19:13.350
15171
50037
answer


PermissionErrorがでてるということは, 複数のプロセスを実行しているのですね？

その場合は, 「[複数のプロセスからの単一ファイルへのログ記録](https://docs.python.org/ja/3/howto/logging-
cookbook.html#logging-to-a-single-file-from-multiple-
processes)」で以下の手法が紹介されています

  * [ネットワーク越しの logging イベントの送受信](https://docs.python.org/ja/3/howto/logging-cookbook.html#network-logging)
  * 別の方法として、 Queue と QueueHandler を使う方法

* * *

### logging.config に関して

`logging.config` の `fileConfig`は, 設定ファイルを用意しておけば簡単に設定できるが

  * JSON / YAML などで記述し(`load`して) `dictConfig`したほうが, 記述が分かりやすく便利に思える
  * 標準の [ロギングハンドラー](https://docs.python.org/ja/3/library/logging.handlers.html) (`RotatingFileHandler` や `TimedRotatingFileHandler` 程度)までなら簡単に利用できるが, カスタマイズしたハンドラーを扱い出すと面倒になりがち

という感じですね

* * *

でもまずは, カスタムロギングハンドラーをモジュール化して  
各プログラム(各プロセス) で `import` し動作させることから始めたらいいのではないでしょうか？


CC BY-SA 4.0
2021-04-11T14:50:46.520
75212
2021-04-11T14:50:46.520
43025
50037
answer