私は正確にそれを行うものを認識していませんが、関連する関数にデコレータを追加するだけでそれを行うプロジェクトのために、しばらく前に何かを書きました。
関数の実行時間計測やDBアクセス関数の時間計測などを行うためのデコレータ一式を作成しました。
このようなデコレータの例は次のとおりです。
def func_runtime(method):
@functools.wraps(method)
def wrapper(self, *args, **kwargs):
start_time = datetime.datetime.utcnow()
try:
class_name = type(self).__name__
method_name = method.__name__
return method(self, *args, **kwargs)
finally:
end_time = datetime.datetime.utcnow() - start_time
time_taken_ms = end_time.microseconds / 1000
if _statsd:
# Send the data to statsD, but you can do that for CopperEgg or anything else
self.stats.timing("func.runtime.%s.%s" % (class_name, method_name), time_taken_ms)
後で次のように使用します。
@func_runtime
def myfunc(a, b, c):
pass
また、DB から読み取る関数と DB に書き込む関数のデコレータを追加したので、コードがデータの読み取りまたは書き込みの待機に費やした時間と、「読み取り」を呼び出した回数に関するグラフを取得できます。操作と「書き込み」操作。
したがって、全体として、次のデコレータがありました。 - @func_runtime - 関数の実行時間を測定する - @func_dbread - 読み取りを実行する関数に配置します。database.reads カウンターをインクリメントし、タイミング データを read_timing に送信します - @func_dbwrite - @func_dbread と同じですが、書き込み用です - @func dbruntime - DB 固有の関数の実行時間、および呼び出しの数と合計タイミングを測定するために使用されますすべての DB 関数の
デコレーターを組み合わせると、関数に最も近い順序で実行されます。次に例を示します。
@func_dbruntime
@func_dbread
def some_db_read_function(a, b, c,d):
pass
したがって、@func_dbread は @func_dbruntime の前に実行されます。
全体として、簡単にカスタマイズでき、非常に強力であり、サードパーティのサービスをサポートするように拡張したり、必要に応じてこれらのカウンターを動的にオンまたはオフにするコードを追加したりできます。私が知る限り、パフォーマンスの低下はせいぜい最小限でした。
CopperEgg やその他のサービスなどの場所にデータを送信することについての注意点として、StatsD は UDP を使用します。その統計により、一部のデータが失われる可能性がありますが、それでも意味のある洞察が得られ、何もブロックされません。CopperEgg のようなサード パーティのサイトにデータを送信する場合は、データをローカル キューに送信し、別のプロセスで CopperEgg にプッシュして、サード パーティのサービスの問題を自分の問題から切り離すことを検討します。
個人的には、そのようなデータの場合、StatsD は優れており、グラファイトは 90 パーセンタイル、平均、最大、グラフ作成機能など、必要なすべてのものを提供し、基本的に必要なカウンター タイプのほとんどを備えています。