Skip to main content

Periodic stack-trace sampler for Python performance profiling.

Project description

pysttl

[[TOC]]

pysttl (Python Sampling Thread Trace Logger) は、Python アプリケーションのパフォーマンスのボトルネックを特定するためのスタックトレース定期サンプラーです。SIGALRM を利用して指定間隔ごとに全スレッドのスタックトレースを取得し、JSON Lines 形式でログファイルに追記します。

得られたログを解析することで、どの関数・どの行で時間を費やしているかを統計的に把握できます (poor-man's profiler の発想)。

動作要件

  • Python 3.11 以上
  • POSIX 系 OS (Linux / macOS) — 内部で signal.SIGALRM を使用するため、Windows では動作しません。
  • start() はメインスレッドからのみ呼び出せます (signal.signal() の制約)。
  • signal.SIGALRM / signal.setitimer(ITIMER_REAL, ...) を内部で利用するため、同じシグナル/タイマーを使う他のコードとは併用できません。

インストール

pip install pysttl

使い方

1. コンテキストマネージャ (推奨)

import pysttl

with pysttl.trace():
    do_heavy_work()

ブロックを抜けると自動的に stop() が呼ばれ、SIGALRM ハンドラと setitimer の状態は呼び出し前に復元されます。trace()PYSTTL_ENABLE を見ません(明示的にプロファイルしたいブロック向け)。

2. 関数 API

環境変数 PYSTTL_ENABLE設定されていて、かつ空でない場合にだけ start() がサンプリングを開始します。未設定なら何もせず、例外も発生しません。アプリに pysttl.start() を常時置き、デバッグ実行時だけ PYSTTL_ENABLE=1 のように付与する使い方を想定しています。

ログファイルの親ディレクトリが無い場合は自動作成します。

サンプリング開始に成功した場合、プロセス終了時に atexitstop() が呼ばれるため、stop() は省略できます。

import pysttl

# 例: PYSTTL_ENABLE=1 python app.py
pysttl.start()
do_heavy_work()

パスや間隔を明示する例:

import pysttl

pysttl.start(log_file_path="/tmp/backtrace.log", interval=1.0)
try:
    do_heavy_work()
finally:
    pysttl.stop()

3. デフォルト値の上書き

log_file_pathinterval のデフォルト値はモジュール属性として公開されており、外部から上書き可能です。start() / trace() は呼び出し時にその時点の値を参照します。

import pysttl

pysttl.DEFAULT_LOG_FILE_PATH = "/var/log/myapp/backtrace.log"
pysttl.DEFAULT_INTERVAL = 0.5  # 500ms 間隔でサンプル

# PYSTTL_ENABLE を付与したデバッグ実行時のみ有効
pysttl.start()

引数を明示的に渡した場合はそちらが優先されます。

出力フォーマット

ログは JSON Lines で書き出されます。1 行 = 1 サンプル = その時点の全スレッドのスタックトレースです。

{
  "threads": [
    {
      "backtrace": [
        "<FrameSummary file '/path/to/main.py', line 14 in main>",
        "<FrameSummary file '/path/to/core.py', line 80 in busy_loop>"
      ],
      "datetime": "2026-05-08T21:00:00.123456",
      "thread_name": "MainThread",
      "thread_ident": 140123456789
    }
  ]
}

backtrace は呼び出し元 → 呼び出し先の順 (root -> leaf) に並んでいます。

解析 CLI

pysttl-parsepysttl が出力した JSON Lines ログを解析し、スタックツリーとステップランキングを出力します。

# ファイルを解析して結果を保存
pysttl-parse < /tmp/backtrace.log > log/tree.txt

# パイプ経由でも利用可能
cat /tmp/backtrace.log | pysttl-parse

出力には以下の2セクションが含まれます。

  • ### Stack trace log analysis tree
  • ### Step load ranking

壊れた JSON 行は警告を stderr に出力し、解析は継続します。

API リファレンス

シンボル 種別 説明
pysttl.start(log_file_path=None, interval=None) 関数 PYSTTL_ENABLE が有効なときのみサンプリング開始。それ以外は no-op(例外なし)。None の引数は対応する DEFAULT_* を参照。
pysttl.stop() 関数 サンプリング停止 + SIGALRM ハンドラ復元。未起動なら no-op。
pysttl.trace(log_file_path=None, interval=None) コンテキストマネージャ サンプリングの開始/停止。PYSTTL_ENABLE は不要。
pysttl.DEFAULT_LOG_FILE_PATH 定数 (str) 既定の出力先。初期値 "/tmp/backtrace.log"
pysttl.DEFAULT_INTERVAL 定数 (float) 既定のサンプリング間隔 [秒]。初期値 1.0
pysttl.PYSTTL_ENABLE_ENV 定数 (str) 参照する環境変数名。値は "PYSTTL_ENABLE"

制限事項

  • signal.SIGALRMpysttl が占有するため、signal.alarm()setitimer(ITIMER_REAL, ...) を別途使用するコードと併用できません。
  • シグナルハンドラ内でファイル I/O (JSON シリアライズ + 追記書き込み) を行うため、I/O が遅い環境では実際の処理スレッドを意図せずブロックする可能性があります。本番常用ではなく調査用途を想定しています。
  • start() が既に有効な状態で再度 start() した場合は no-op です。出力先や間隔を変えるときはいったん stop() してから再度 start() してください。

ライセンス

MIT License。全文は LICENSE を参照してください。

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pysttl-0.1.4.tar.gz (8.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pysttl-0.1.4-py3-none-any.whl (9.3 kB view details)

Uploaded Python 3

File details

Details for the file pysttl-0.1.4.tar.gz.

File metadata

  • Download URL: pysttl-0.1.4.tar.gz
  • Upload date:
  • Size: 8.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.13 {"installer":{"name":"uv","version":"0.9.13"},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for pysttl-0.1.4.tar.gz
Algorithm Hash digest
SHA256 f111066b0798778256ae952bdd704b60295841f9372adbae43ef9ef018617ec9
MD5 8db7fa00262afc574466813007535f17
BLAKE2b-256 e0ae9b1a44cd5398ee24fba5439cfd9148387a48ab43cba7511ccdd0ee741b16

See more details on using hashes here.

File details

Details for the file pysttl-0.1.4-py3-none-any.whl.

File metadata

  • Download URL: pysttl-0.1.4-py3-none-any.whl
  • Upload date:
  • Size: 9.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.13 {"installer":{"name":"uv","version":"0.9.13"},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for pysttl-0.1.4-py3-none-any.whl
Algorithm Hash digest
SHA256 83f0e3751f0ed9b841f7425d8df2671d057b8e4c2f7ba9a2708c87e6b5fd3cef
MD5 3cb4e18ef4a508ccd68ae0154a165e68
BLAKE2b-256 09cc06443981f744c7c393b8c47b3a3cfc5bee40cc028b3c0f14da434cac6c02

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page