Github: https://github.com/jazzband/django-silk
シルク
Silkは現在Jazzbandの組織に移り、貢献者を募集しています。あなたが手伝ってくれると思ったら、お気軽にお問い合わせください!
Silkは、Djangoフレームワークのためのライブプロファイリングとインスペクションツールです。 SilkはHTTPリクエストとデータベースクエリをインターセプトしてユーザインタフェースに提示してからさらに検査します:
内容
要件
シルクは以下のテストを受けました:
- Django:1.11,2.0
- Python:2.7,3.4,3.5,3.6
インストール
virtualenvにpipを通して:
pip install django-silk
settings.py
に以下を追加してください:
MIDDLEWARE = [
...
'silk.middleware.SilkyMiddleware',
...
]
INSTALLED_APPS = (
...
'silk'
)
注:ミドルウェアの配置は機密です。 ミドルウェアがsilk.middleware.SilkyMiddleware
前にprocess_request
から戻ってきたら、 SilkyMiddleware
は決して実行する機会を得られません。 したがって、前に配置されたミドルウェアがprocess_request
から何も返さないようにする必要があります。 詳細については、 djangoのドキュメントを参照してください。
注意: django.middleware.gzip.GZipMiddleware
を使用している場合は、 django.middleware.gzip.GZipMiddleware
前に silk.middleware.SilkyMiddleware
ます。そうしないと、エンコーディングエラーが発生します。
ユーザーインターフェイスへのアクセスを有効にするには、 urls.py
次の行を追加します。
urlpatterns += [url(r'^silk/', include('silk.urls', namespace='silk'))]
移行を実行する前に:
python manage.py makemigrations
python manage.py migrate
python manage.py collectstatic
Silkは自動的にリクエストの傍受を開始し、必要に応じてプロファイリングを追加することができます。 UIは、 /silk/
代替インストール
githubタグ経由:
pip install https://github.com/jazzband/silk/archive/<version>.tar.gz
以下を使用してmasterからインストールできますが、masterのバージョンが要件で指定されているすべてのバージョンで動作していない可能性があることに注意してください
pip install -e git+https://github.com/jazzband/django-silk.git#egg=silk
特徴
シルクは主に次のもので構成されます。
- リクエスト/レスポンスをインターセプトするためのミドルウェア
- データベースクエリのプロファイリングのためのSQL実行に関するラッパー
- コードや関数のブロックを手動または動的にプロファイリングするためのコンテキストマネージャ/デコレータ。
- 上記の検査と視覚化のためのユーザーインターフェース。
検査依頼
Silkミドルウェアは、構成されたデータベース内の要求と応答を傍受して格納します。 これらのリクエストは、リクエストの概要を通してSilkのUIを使用してフィルタリングして検査することができます。
それは次のようなものを記録します:
- 撮影時間
- Num。 クエリ
- クエリに費やされた時間
- リクエスト/レスポンスヘッダ
- リクエスト/レスポンス団体
等々。
関連するリクエストをクリックすると、各リクエストの詳細が表示されます。
SQL検査
Silkはまた、各要求によって生成されるSQLクエリをインターセプトします。 関係するテーブル、ジョイン数、実行時間などの要約を得ることができます(テーブルは列ヘッダをクリックすることでソートできます):
このリクエストがどこから来たのかを知るためにスタックトレースに入る前に:
プロファイリング
Pythonの組み込みcProfileプロファイラを使用するには、SILKY_PYTHON_PROFILER設定をオンにします。 各リクエストは個別にプロファイリングされ、プロファイラの出力はSilk UIのリクエストのプロファイリングページで利用可能になります。
SILKY_PYTHON_PROFILER = True
バイナリ.prof
ファイルも生成したい場合は、次のように設定します。
SILKY_PYTHON_PROFILER_BINARY = True
有効にすると、 gprof2dotおよびviz.jsを使用して生成されたグラフの視覚化がプロファイルの詳細ページに表示されます。
保存された生成されたバイナリ.prof
ファイルにカスタムストレージクラスを使用できます。
SILKY_STORAGE_CLASS = 'path.to.StorageClass'
デフォルトのストレージクラスはsilk.storage.ProfilerResultStorage
です。これを使用する場合は、選択したパスを指定できます。 指定されたディレクトリが存在することを確認する必要があります。
# If this is not set, MEDIA_ROOT will be used.
SILKY_PYTHON_PROFILER_RESULT_PATH = '/path/to/profiles/'
ダウンロードボタンは、リクエストごとにバイナリの.prof
ファイルで利用できるようになります。 このファイルは、 snakevizやその他のcProfileツールを使用してさらに解析するために使用できます
Silkは、コード/関数の特定のブロックのプロファイリングにも使用できます。 これは、この目的のためにデコレータとコンテキストマネージャを提供します。
例えば:
from silk.profiling.profiler import silk_profile
@silk_profile(name='View Blog Post')
def post(request, post_id):
p = Post.objects.get(pk=post_id)
return render_to_response('post.html', {
'post': p
})
ブログ投稿が表示されるたびに、Silk UI内にエントリが表示されます。
シルクプロファイリングは、実行時間を提供するだけでなく、要求と同じ方法でブロック内で実行されるSQLクエリを収集します。
デコレータ
シルクデコレータは、関数とメソッドの両方に適用できます
from silk.profiling.profiler import silk_profile
# Profile a view function
@silk_profile(name='View Blog Post')
def post(request, post_id):
p = Post.objects.get(pk=post_id)
return render_to_response('post.html', {
'post': p
})
# Profile a method in a view class
class MyView(View):
@silk_profile(name='View Blog Post')
def get(self, request):
p = Post.objects.get(pk=post_id)
return render_to_response('post.html', {
'post': p
})
コンテキストマネージャ
コンテキストマネージャを使用すると、名前にコンテキストを追加することができます。これにより、特定のデータベースレコードの処理速度を絞り込むのに役立ちます。
def post(request, post_id):
with silk_profile(name='View Blog Post #%d' % self.pk):
p = Post.objects.get(pk=post_id)
return render_to_response('post.html', {
'post': p
})
動的プロファイリング
Silkの興味深い機能の1つに、動的プロファイリングがあります。 たとえば、読み取り専用アクセスしか持たない依存関係の関数(例えば、システム所有のpythonライブラリがrootによって所有されている)をプロファイリングしたい場合、実行時にデコレータを適用するためにsettings.py
に以下を追加することができます:
SILKY_DYNAMIC_PROFILING = [{
'module': 'path.to.module',
'function': 'MyClass.bar'
}]
これは、
class MyClass(object):
@silk_profile()
def bar(self):
pass
以下にその可能性を要約します。
"""
Dynamic function decorator
"""
SILKY_DYNAMIC_PROFILING = [{
'module': 'path.to.module',
'function': 'foo'
}]
# ... is roughly equivalent to
@silk_profile()
def foo():
pass
"""
Dynamic method decorator
"""
SILKY_DYNAMIC_PROFILING = [{
'module': 'path.to.module',
'function': 'MyClass.bar'
}]
# ... is roughly equivalent to
class MyClass(object):
@silk_profile()
def bar(self):
pass
"""
Dynamic code block profiling
"""
SILKY_DYNAMIC_PROFILING = [{
'module': 'path.to.module',
'function': 'foo',
# Line numbers are relative to the function as opposed to the file in which it resides
'start_line': 1,
'end_line': 2,
'name': 'Slow Foo'
}]
# ... is roughly equivalent to
def foo():
with silk_profile(name='Slow Foo'):
print (1)
print (2)
print(3)
print(4)
動的プロファイリングは、関数をインプレースで変更する点で、Pythonモックフレームワークと同様に動作することに注意してください。
""" my.module """
from another.module import foo
# ...do some stuff
foo()
# ...do some other stuff
my.module.foo
とは対照的に、 my.module.foo
を動的にmy.module.foo
することによってfoo
をプロファイルします。
SILKY_DYNAMIC_PROFILING = [{
'module': 'my.module',
'function': 'foo'
}]
すでにインポートされた後に、関数ソースモジュールanother.module.foo
に動的プロファイルを適用すると、プロファイリングはトリガーされません。
コード生成
Silkは現在、要求ごとに2ビットのコードを生成しています。
どちらも要求の再生に使用することを意図しています。 curlコマンドはコマンドライン経由で再生することができ、PythonコードはDjangoユニットテスト内で使用することも、単なるスタンドアロンスクリプトとして使用することもできます。
構成
認証/承認
デフォルトでは、誰でもSilkのユーザーインターフェイスにアクセスするには、 /silk/
ます。 Djangoの認証バックエンドを有効にするには、 settings.py
次のように記述しsettings.py
:
SILKY_AUTHENTICATION = True # User must login
SILKY_AUTHORISATION = True # User must have permissions
SILKY_AUTHORISATION
がTrue
場合、デフォルトでSilkはis_staff
属性がTrue
設定されているユーザーのみを認証します。
これをカスタマイズするには、 settings.py
次のようにしsettings.py
。
def my_custom_perms(user):
return user.is_allowed_to_use_silk
SILKY_PERMISSIONS = my_custom_perms
lambda
使用することもできます。
SILKY_PERMISSIONS = lambda user: user.is_superuser
リクエスト/レスポンス団体
デフォルトでは、Silkは要求の度にリクエストとレスポンスのボディを保存します。 Silkが大きなボディで大量生産されている場合、これはスペース/時間パフォーマンスに大きな影響を与えます。 この動作は、次のオプションを使用して構成できます。
SILKY_MAX_REQUEST_BODY_SIZE = -1 # Silk takes anything <0 as no limit
SILKY_MAX_RESPONSE_BODY_SIZE = 1024 # If response body>1024kb, ignore
メタプロファイリング
Silkが要求/応答時間にどのような影響を与えているかを見ることができると便利なことがあります。 これを行うには、 settings.py
次の行を追加しsettings.py
:
SILKY_META = True
Silkは次に、各要求の最後にすべてをデータベースに保存するまでの時間を記録します。
上記のスクリーンショットでは、リクエストが29ms(Djangoから22ms、Silkから7ms)かかることに注意してください。
要求の一部を記録する
高負荷のサイトでは、作成された要求のほんの一部を記録するのが役に立ちます。これを行うには、 settings.py
次の行を追加しsettings.py
。
注:この設定はSILKY_INTERCEPT_FUNCと相互排他的です。
SILKY_INTERCEPT_PERCENT = 50 # log only 50% of requests
要求を記録するためのカスタムロジック
高負荷のサイトでは、リクエストを傍受するための独自のロジックを記述することも役立ちます。これを行うには、 settings.py
次の行を追加しsettings.py
。
注:この設定はSILKY_INTERCEPT_PERCENTと相互排他的です。
def my_custom_logic(request):
return 'record_requests' in request.session
SILKY_INTERCEPT_FUNC = my_custom_logic # log only session has recording enabled.
lambda
使用することもできます。
# log only session has recording enabled.
SILKY_INTERCEPT_FUNC = lambda request: 'record_requests' in request.session
要求/応答データの制限
シルキーなゴミが古いリクエスト/レスポンスデータを収集するためには、config varを設定して、それが格納するリクエスト/レスポンスの行数を制限することができます。
SILKY_MAX_RECORDED_REQUESTS = 10**4
ガベージコレクションは、オーバーヘッドを削減する要求の割合に対してのみ実行されます。 この設定で調整することができます:
SILKY_MAX_RECORDED_REQUESTS_CHECK_PERCENT = 10
ログデータの消去
管理コマンドは、ログに記録されたすべてのデータを消去します。
python manage.py silk_clear_request_log
貢献する
これはジャズバンドプロジェクトです。 貢献することにより、あなたはコントリビュータ行動規範を遵守し、 ガイドラインに従うことに同意します。
開発環境
Silkには、 silk
開発に使用できるプロジェクトという名前のproject
があります。 シンクコードがシンボリックリンクされているので、サンプルproject
とsilk
パッケージで同時に作業できます。
ローカル開発をセットアップするには、最初にテストproject
すべての依存関係をインストールする必要があります。 project
ディレクトリのルートから:
pip install -r test-requirements.txt
また、 silk
の依存関係をインストールする必要があります。 gitリポジトリのルートから:
pip install -r requirements.txt
この時点で、仮想環境には、サンプルproject
とsilk
両方を正常に実行するために必要なものすべてが必要です。
実行する前に、 DB
およびDB_NAME
環境変数を設定する必要があります。
export DB=sqlite3
export DB_NAME=db.sqlite3
他の組み合わせについては、 .travis.yml
チェックして.travis.yml
。
サンプルproject
ディレクトリのルートから、djangoサーバを起動します。
python manage.py runserver
テストの実行
cd project
./tests/test_migrations.sh
python manage.py test --noinput
ハッピープロファイリング!