いずみこんな悩みを解決できる記事を書きました!
僕は現役フリーランスエンジニア(歴10年)で、資格は13個保有しています。
「printデバッグから卒業して、Pythonできちんとしたログ出力を実装したい」とお考えではありませんか?
printを大量に書いたスクリプトは、リリース時に消して回る手間がかかります。
Python標準ライブラリのloggingを使えば、出力レベルの切り替えと出力先の分離をコード変更なしで管理できます。



標準ライブラリだけで完結するので、追加インストールは不要です。
ということで、本記事ではPythonのloggingでログ出力を実装する方法を解説します。



すぐ読み終わるので、ぜひ最後まで読んでくださいませ。
| 【当サイト】おすすめフリーランスエージェント3選 | |||
|---|---|---|---|
| エージェント | 評価 | ポイント | 公式サイト |
レバテックフリーランス | 5.0 | 業界最大級のエージェント。 高単価案件が豊富。 | 公式 |
Midworks | 4.8 | 満足度調査で 3年連続3冠を達成。 | 公式 |
ITプロパートナーズ | 4.6 | 週2〜3向けの案件が豊富。 | 公式 |
【Python】loggingでログ出力を実装する方法
早速ですが、Pythonのloggingでログ出力を実装する手順を見ていきます。
printではなくloggingを使うメリット
printは標準出力へ文字列を送るだけで、重要度の区別ができません。
loggingはメッセージに重要度(ログレベル)を付けられます。
開発中はDEBUGまで表示し、本番ではINFO以上だけ残す、といった切り替えを設定1箇所で行えます。
出力先も画面・ファイル・外部サービスへ自由に分けられます。
タイムスタンプ・モジュール名・行番号を自動で付与できる点も、原因調査を速くします。



printデバッグを消し忘れて本番に出てしまう事故も防げます。
loggingのログレベル
loggingには5段階のログレベルが用意されています。
- DEBUG(数値10): 変数の中身や分岐など、開発中に追いたい詳細情報
- INFO(数値20): 処理が想定どおり進んでいることを示す情報
- WARNING(数値30): 停止するほどではないが注意が必要な事象
- ERROR(数値40): 特定の処理が失敗したこと
- CRITICAL(数値50): プログラム全体が継続できない深刻な事態
ロガーやハンドラに設定したレベル以上のメッセージだけが出力されます。
何も設定しない場合の初期レベルはWARNINGで、DEBUGとINFOは表示されません。
basicConfigで手早くログを出力する
まずは最小構成として、basicConfigでログを出力します。
スクリプトの冒頭で1回だけ呼び出します。
import logging
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s %(levelname)s %(name)s %(message)s",
)
logging.info("処理を開始しました")
logging.warning("残り容量が少なくなっています")levelにINFOを渡したので、DEBUGは出ずINFO以上が表示されます。
formatにfilenameへのパスを追加すると、画面ではなくファイルへ書き出せます。
basicConfigはルートロガーへハンドラが未設定のときだけ効果を持ちます。
2回目以降の呼び出しは無視されるため、複数の出力先を細かく制御したい場合は次のハンドラ方式へ移行します。



小さなスクリプトならbasicConfigだけで十分なことも多いです。
getLoggerでモジュールごとにロガーを分ける
実務では、モジュールごとに名前付きロガーを作るのが基本形です。
import logging
logger = logging.getLogger(__name__)
def run():
logger.debug("デバッグ用の詳細情報")
logger.info("正常に処理が進んでいます")
try:
1 / 0
except ZeroDivisionError:
logger.exception("ゼロ除算が発生しました")getLoggerに__name__を渡すと、パッケージ階層に沿った名前のロガーが得られます。
ログにモジュール名が表示されるので、どのファイルの出力かがすぐ分かります。
logger.exceptionはexceptブロック内で使うと、スタックトレースを自動で付けてERRORレベルで記録します。



ライブラリ側のコードでは、ハンドラを足さず名前付きロガーへ出力するだけにしておくのが行儀の良い書き方です。
ハンドラとフォーマッタで出力先と書式を分ける
画面には要点だけ、ファイルには詳細まで、という分け方をハンドラで実現します。
ロガー自体はDEBUGまで通し、絞り込みは各ハンドラ側で行います。
import logging
from logging.handlers import RotatingFileHandler
logger = logging.getLogger("myapp")
logger.setLevel(logging.DEBUG)formatter = logging.Formatter(
"%(asctime)s [%(levelname)s] %(name)s:%(lineno)d %(message)s"
)
stream_handler = logging.StreamHandler()
stream_handler.setLevel(logging.INFO)
stream_handler.setFormatter(formatter)
file_handler = RotatingFileHandler(
"app.log", maxBytes=1_000_000, backupCount=3, encoding="utf-8"
)
file_handler.setLevel(logging.DEBUG)
file_handler.setFormatter(formatter)
logger.addHandler(stream_handler)
logger.addHandler(file_handler)StreamHandlerは画面へINFO以上、RotatingFileHandlerはファイルへDEBUGまで書き出します。
RotatingFileHandlerはmaxBytesを超えるとファイルを世代交代させ、backupCountの数だけ古いログを残します。



ログファイルがディスクを圧迫し続ける問題を、ローテーションで避けられます。
dictConfigで設定を一括管理する
ハンドラを手続き的に組み立てる代わりに、辞書で宣言的に定義する方法がdictConfigです。
import logging.config
LOGGING_CONFIG = {
"version": 1,
"disable_existing_loggers": False,
"formatters": {
"standard": {
"format": "%(asctime)s [%(levelname)s] %(name)s: %(message)s",
},
},
"handlers": {
"console": {
"class": "logging.StreamHandler",
"level": "INFO",
"formatter": "standard",
},
"file": {
"class": "logging.handlers.RotatingFileHandler",
"level": "DEBUG",
"formatter": "standard",
"filename": "app.log",
"maxBytes": 1000000,
"backupCount": 3,
"encoding": "utf-8",
},
},
"root": {
"level": "DEBUG",
"handlers": ["console", "file"],
},
}
logging.config.dictConfig(LOGGING_CONFIG)
logger = logging.getLogger(__name__)
logger.info("dictConfigでの設定が完了しました")versionキーは常に1を指定します。
disable_existing_loggersをFalseにしておくと、定義前に作られたロガーが無効化されず安全です。
辞書はJSONやYAMLへ切り出せるので、開発と本番で設定ファイルだけ差し替える運用がしやすくなります。



アプリの規模が大きくなったらdictConfigへ寄せておくと、設定変更のたびにコードを触らずに済みます。
| 【当サイト】おすすめフリーランスエージェント3選 | |||
|---|---|---|---|
| エージェント | 評価 | ポイント | 公式サイト |
レバテックフリーランス | 5.0 | 業界最大級のエージェント。 高単価案件が豊富。 | 公式 |
Midworks | 4.8 | 満足度調査で 3年連続3冠を達成。 | 公式 |
ITプロパートナーズ | 4.6 | 週2〜3向けの案件が豊富。 | 公式 |
【厳選】フリーランスエンジニアにおすすめなエージェント3選


フリーランスエンジニアになるにはエージェントから案件をもらう必要があります。
僕が実際に利用しているおすすめエージェントを紹介しますね。



エージェントは必ず複数登録してください。
担当者によっては「全然案件紹介してくれない…」みたいなこともあるので…
僕は実際に5つのエージェントを使い回していますよ。
フリーランスを始めるなら「レバテックフリーランス


」
- 業界最大級の案件数。
- 業界トップクラスの高単価報酬、低マージン(平均年収862万円)。
- 案件参画中のフォローの充実。
※詳細は「【業界最大手】レバテックフリーランスとは?メリットや利用手順を解説!」を参照。
レバテックフリーランス
![]()
![]()
とにかく案件数が多いので、とりあえず登録しておけば間違いないエージェントです!



僕もはじめてフリーランスの案件を貰ったのはレバテックフリーランス
![]()
![]()
保有している案件数が多いので、業務経験がなくても何かしらの案件は紹介してもらえますよ(僕はJavaの経験3年でも案件を貰えました)。
手厚い保障を重視したいなら「Midworks


」
- 手厚い保障で正社員並みの安心感。
- 還元率60%超え&単価公開でクリアな契約。
- 給与保障制度(審査あり)。
Midworks
![]()
![]()
フリーランスを目指しているけど不安な方や保障を重視したい方におすすめです。



僕も何度か案件を紹介してもらいました。
自分のスキルに合った案件を紹介してもらえましたし、電話のやり取りも非常に丁寧でした。
週2〜3日の案件探しなら「ITプロパートナーズ


」
- IT案件に特化したフリーランスエージェント。
- 週2〜3日の案件が豊富。
- リモート案件が多く、直エンドなので単価も高い。
※詳細は「【週2・3案件】ITプロパートナーズとは?メリットや利用手順を解説!」を参照。
ITプロパートナーズ
![]()
![]()
週2〜3日から参画できる案件が豊富なので、起業したい人にもおすすめです。



週2〜3日の案件はある程度スキルがないと紹介してもらえない印象です。
とはいえ、週5の案件ももちろんありますし、僕が利用した時は迅速・丁寧に対応していただきました!
よくある質問
ルートロガーと名前付きロガーはどちらを使うべきですか?
アプリ側のコードではlogging.getLogger(__name__)で名前付きロガーを使うのが基本です。
ハンドラの登録はエントリーポイントでルートロガーへまとめて行い、各モジュールは出力するだけにすると管理が楽になります。
ログが二重に出力されてしまいます。
同じロガーへaddHandlerを複数回呼んでいるか、ルートロガーと子ロガーの両方にハンドラを付けているのが原因です。
ハンドラ登録を1箇所に集約し、必要なら子ロガーのpropagateをFalseにすると重複が止まります。
本番環境ではどのログレベルにすべきですか?
通常はINFOかWARNINGを基準にします。
ログレベルは環境変数や設定ファイルから読み込めるようにしておき、障害調査のときだけDEBUGへ下げられる構成にすると便利です。
まとめ
今回は、Pythonのloggingでログ出力を実装する方法について解説しました。
以下が本記事のまとめになります。
- おすすめ本
Pythonの勉強なら「独習Python



最後までお読みいただき、ありがとうございました!
| 【当サイト】おすすめフリーランスエージェント3選 | |||
|---|---|---|---|
| エージェント | 評価 | ポイント | 公式サイト |
レバテックフリーランス | 5.0 | 業界最大級のエージェント。 高単価案件が豊富。 | 公式 |
Midworks | 4.8 | 満足度調査で 3年連続3冠を達成。 | 公式 |
ITプロパートナーズ | 4.6 | 週2〜3向けの案件が豊富。 | 公式 |
- クソおすすめ本



海外のエンジニアがどういった思考で働いているかが理解できます。
海外に行く気はないけど海外エンジニアの動向が気になる雑魚エンジニアにおすすめです(本当におすすめな本しか紹介しないのでご安心を)。









