Pythonの`print`と`logging`の違い　実例を交えて徹底解説


# Pythonの`print`と`logging`の違い、実例を交えて徹底解説

Pythonを学び始めると、最初は`print`を使ってプログラムの動作を確認することが多いと思います。実際、私もその方法で多くのデバッグを行っていました。しかし、コードが複雑になり、運用を考えた時に、`print`では限界を感じる瞬間が来ました。

その時に出会ったのがPythonの`logging`です。この記事では、`print`と`logging`の違いについて、初学者の方にも分かりやすいように実例を交えながら説明していきます。`logging`を使うことで、コードの管理やデバッグがどれだけ効率的になるかを一緒に学んでいきましょう。

## `print`だけでは不十分？デバッグの限界

初学者の方であれば、`print`を使って変数の値やプログラムの動作確認を行うことが多いでしょう。私も最初は`print`を使ってコードの至るところにメッセージを表示していました。例えば、こんな感じです。

```python
print("プログラム開始")
x = 10
print(f"xの値は: {x}")
```

このように、簡単なコードであれば`print`でも十分です。しかし、プログラムが大きくなると、`print`での出力は雑多になりがちです。どこでエラーが発生しているのか、どの部分が重要なメッセージなのか、瞬時に判断するのが難しくなります。

これを改善するために必要なのが、ログ管理ツールである`logging`です。

## `logging`を使うメリット

`logging`を使うと、プログラムの動作やエラーを**ログとして記録**することができ、後で問題が起きた場所や原因を追跡するのが容易になります。さらに、ログには重要度（ログレベル）を設定できるので、プログラムのどの部分が重大な問題を引き起こしているかを効率よく把握できます。

以下に、`logging`の簡単な例を示します。

```python
import logging

logging.basicConfig(level=logging.INFO)

logging.info("プログラム開始")
x = 10
logging.debug(f"xの値は: {x}")
```

この例では、`logging.basicConfig(level=logging.INFO)`により、`INFO`以上のレベルのメッセージだけが表示されます。つまり、`DEBUG`メッセージは出力されません。これにより、重要なメッセージだけに絞って出力できるため、プログラムが複雑でも確認が容易です。

## `print`と`logging`の違いを詳しく解説

では、`print`と`logging`の具体的な違いをもう少し掘り下げてみましょう。

| **項目**             | **`print`**                                                                                       | **`logging`**                                                                                     |
|----------------------|---------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------|
| **用途**             | コンソールにメッセージを表示。デバッグ用に使われることが多い。                                     | ログメッセージを記録し、後から分析や運用に役立てる。                                               |
| **出力先の柔軟性**   | 基本的に標準出力（コンソール）のみ。                                                               | コンソール以外にもファイルやネットワークに出力できる。                                             |
| **ログレベル**       | メッセージの重要度を設定できない。                                                                 | `DEBUG`, `INFO`, `WARNING`, `ERROR`, `CRITICAL`といったログレベルを設定できる。                    |
| **パフォーマンス**   | プログラムが大きくなるとパフォーマンスに影響が出る可能性あり。                                     | ログレベルでメッセージをフィルタリングし、必要な情報だけを記録。                                   |
| **フォーマット**     | メッセージの形式を手動で管理。                                                                     | タイムスタンプやログレベルなど、フォーマットを自由に設定できる。                                   |
| **運用時の使用**     | 本番運用には向いていない。                                                                         | 運用時にも適しており、エラートラッキングやパフォーマンスの管理に役立つ。                           |

このように、`logging`は単なるデバッグツールではなく、**開発から運用までサポートする強力なツール**です。

## `logging`の使用例

次に、具体的な`logging`の使用例をいくつか紹介します。

### 1. ファイルにログを保存する

`logging`では、ログをコンソールだけでなくファイルにも出力することが可能です。これにより、プログラムの動作やエラーログを後から確認でき、問題発生時の原因追跡が容易になります。

```python
import logging

# ログをファイルに保存する設定
logging.basicConfig(filename='app.log', level=logging.WARNING)

# ログメッセージを記録
logging.warning("これは警告メッセージです")
logging.error("これはエラーメッセージです")
logging.critical("これは重大なエラーメッセージです")
```

このコードでは、`app.log`というファイルに`WARNING`以上のログが記録されます。`DEBUG`や`INFO`メッセージは記録されません。

### 2. ログのフォーマットをカスタマイズする

ログには、日時やログレベルといった詳細情報を追加できます。以下の例では、タイムスタンプを含めたログ出力を行います。

```python
import logging

logging.basicConfig(
    filename='app.log',
    level=logging.DEBUG,
    format='%(asctime)s - %(levelname)s - %(message)s'
)

logging.info("アプリケーションが開始しました")
logging.error("データベース接続に失敗しました")
```

この例では、ログファイルにタイムスタンプ付きでメッセージが記録されます。

### 3. ログレベルによるフィルタリング

開発環境と本番環境では、出力するログの内容を変えたい場合があります。`logging`では、ログレベルを使ってメッセージをフィルタリングすることが可能です。

例えば、開発中には詳細なログを出力し、本番環境では重要なエラーのみを記録したい場合、以下のように設定を変更できます。

#### 開発環境用設定
```python
logging.basicConfig(level=logging.DEBUG)
```

#### 本番環境用設定
```python
logging.basicConfig(level=logging.ERROR)
```

これにより、開発環境ではすべてのログメッセージが出力され、本番環境では`ERROR`以上のログだけが記録されるようになります。

### 4. ファイル操作における`logging`の活用

少し複雑な例として、ファイルの読み込み時に発生するエラーを`logging`で管理する方法を紹介します。

```python
import logging

logging.basicConfig(
    filename='app.log',
    level=logging.DEBUG,
    format='%(asctime)s - %(levelname)s - %(message)s'
)

def read_file(file_path):
    logging.info(f"ファイル読み込み開始: {file_path}")
    
    try:
        with open(file_path, 'r') as file:
            data = file.read()
            logging.info("ファイル読み込み成功")
            return data
    except FileNotFoundError:
        logging.error(f"ファイルが見つかりません: {file_path}")
    except Exception as e:
        logging.critical(f"予期しないエラーが発生しました: {e}")

read_file('example.txt')
```

このコードでは、ファイルの読み込みに成功すれば`INFO`メッセージが記録され、ファイルが見つからなければ`ERROR`メッセージ、予期しないエラーが発生した場合は`CRITICAL`メッセージがログファイルに記録されます。

## まとめ

`logging`を使うことで、開発中のデバッグから運用中のエラートラッキングまで、プログラムの動作を効率的に管理できます。`print`は手軽ですが、プロジェクトが大きくなるにつれて管理が難しくなります。そんな時、`logging`を使えば、ログの出力先やログレベルを簡単に設定できるため、プログラムの状態を適切に記録できます。

ぜひ、次回のプロジェクトからは`logging`を活用して、開発や運用をスムーズに進めてください。