LogXide — Rustベースで12.5倍高速なPythonロギングフレームワーク
(github.com/Indosaram)こんにちは。PythonのWebアプリケーションやデータパイプラインのような高負荷環境で、ファイルI/Oやロギングのボトルネックに悩んでいる方に向けて LogXide を紹介します。
1. なぜ作ったのか (The Problem)
Pythonの標準 logging モジュールは純粋なPythonで書かれています。一般的な環境では十分ですが、トラフィックが集中する局面や大規模なロギングパイプラインでは、I/O処理中にGIL (Global Interpreter Lock) を占有し、アプリケーション全体の性能低下を招く原因になります。
2. どう解決したか (Architecture)
LogXideはコアロジックとハンドラーをRustで実装し、PyO3でバインディングしました。
- Python-side Level Check:
FastLoggerWrapperを用意し、ログレベルが無効な場合(例: INFOレベル設定時のDEBUG呼び出し)は、PyObjectの生成やPyO3境界の通過を行わず、Python側で即座に破棄します。この最適化により、空呼び出し時の速度は2〜5倍向上しました。 - ノンブロッキングI/O: StreamHandler、HTTPHandler、OTLPHandlerは
crossbeamチャネルとバックグラウンドスレッドを使って非同期にログを処理します。メインアプリケーションスレッドをブロックしません。 - 同期ダイレクトwrite: FileHandlerでは
Mutex<BufWriter>を使って直接OS I/Oを実行し、必要な場合にのみflushを行うことで、I/Oオーバーヘッドを極限まで削減しました。
3. 主なベンチマーク (macOS ARM64, Python 3.12基準)
- FileHandler: 2.09M msgs/sec (stdlibの167K比で 12.5倍高速)
- StreamHandler: 2.14M msgs/sec (stdlibの11K比で 186倍高速)
- Cで書かれた
Picologgingより実際のファイルフォーマットI/Oで 25%高速、純粋なPython製のStructlogより 2.4倍高速 です。
4. 内蔵機能と使い方
from logxide import logging の1行を変えるだけで、既存の logging.getLogger() コードをそのまま使える構成です。最近のバックエンドアーキテクチャのトレンドに合わせて、次のハンドラーをRustネイティブ水準で内蔵しています:
- OTLPHandler: OpenTelemetryエージェントなしでProtobufベースの直接送信
- HTTPHandler: バッチでまとめて送信する機能
- SentryHandler: エラーロギングの統合をサポート (
pip install logxide[sentry]) - ColorFormatter: ANSI制御文字を活用したターミナルのカラー出力をサポート
5. 明確な制約 (Trade-offs)
導入を検討する際は、100%のDrop-in replacementではないことを理解しておく必要があります:
- Pythonで書かれたカスタム
logging.Handlerを継承して登録することはできません。(Rustで実装された内蔵ハンドラーのみを使う場合に最高性能が維持されます)。 LoggerやLogRecordオブジェクトをサブクラス化することはできません。- pytest環境では、ビルトインの
caplogの代わりにLogXideが提供するcaplog_logxidefixture を使う必要があります。
性能ボトルネックが理由でCベースのロガーや構造化ロギングライブラリを探していたなら、優れた代替案になるはずです。Django、FastAPI、Flaskにすぐ適用できる連携ガイドも公式ドキュメントに含まれているので、ぜひ一度ご覧いただき、フィードバックをいただければ幸いです。
- 公式ドキュメント: https://indosaram.github.io/logxide/
まだコメントはありません。