• ログイン今すぐ開始

本書は、お客様のご参考のために原文の英語版を機械翻訳したものです。

英語版と齟齬がある場合、英語版の定めが優先するものとします。より詳しい情報については、本リンクをご参照ください。

問題を作成する

Pythonのヒントとコツ

Webアプリケーションの監視にPythonエージェントを最大限に活用するために、いくつかのヒントをご紹介します。

デコレーターと内観

トランザクションや関数のトレースノードに名前を付けるとき、Pythonエージェントは呼び出される関数の名前を調べる必要があります。関数が生の関数やクラスメソッドである場合、これはすべてうまくいきます。しかし、関数やクラスメソッドにデコレーターが適用されている場合、もしデコレーターがラップされた関数のイントロスペクト機能を維持するように実装されていなければ、エージェントはラップされた関数の代わりにデコレーターのラッパー関数の名前を使用します。

デコレーターの典型的な実装方法は、パターンを使用することです。

def decorator(f):
def _decorator():
f()
return _decorator
@decorator
def foo():
pass

この実装の問題は、 foo.__name__の値を見ると、それがfoo _decoratorになることです。デコレータが別のモジュールに含まれている場合、 foo.__module__を見ると、デコレータが宣言されているモジュールの名前になり、ラップされた関数が含まれているモジュールの名前にはなりません。

モジュールと関数に正しい名前を付けるには、標準ライブラリfunctoolsモジュールのwraps()デコレータを使用して内部デコレータ関数をラップします。

import functools
def decorator(f):
@functools.wraps(f)
def _decorator():
f()
return _decorator
@decorator
def foo():
pass

詳細については、Python Web サイトでwraps()関数のドキュメントを参照してください。

トランザクションの識別

Python エージェントがトランザクションのエラーの詳細を記録したり、スローなトランザクションのトレースをキャプチャしたりするとき、そのトランザクションに対して個別に記録した他のデータと関連付けるために使用できる固有の識別子がありません。これは、例えば、UIからの情報と自分のウェブアプリケーションのログを一致させることを困難にしています。

このようなクロスマッチングを行いたい場合、または単にトランザクションに対して、このような状況で役立つ可能性のある追加の詳細をキャプチャしたい場合、エージェントAPIを使用して、トランザクションに対してカスタムパラメータを記録することができます。エラーが発生したり、遅いトランザクションのトレースが記録され、それがUIに表示された場合、あなたが提供したこれらの追加パラメータは、エラーまたはトレースの詳細の Custom parameters セクションの下に表示されます。

このような追加の詳細を追加するには、 newrelic.agentモジュールでadd_custom_attribute()関数を使用できます。

重要

トランザクション名の末尾に括弧[suffix]を使用しないでください。エージェントは名前から括弧を自動的に削除します。代わりに、必要に応じて括弧(suffix)またはその他の記号を使用してください。

例えば、Django web framework チュートリアルの polls アプリケーションのコードを見てみましょう。

from django.shortcuts import render_to_response, get_object_or_404
def detail(request, poll_id):
p = get_object_or_404(Poll, pk=poll_id)
return render_to_response('polls/detail.html', {'poll': p})

もし、問題が発生したときに利用できるように、トランザクションに対してポールIDを記録したい場合は、次のようにします。

import newrelic.agent
def detail(request, poll_id):
newrelic.agent.add_custom_attribute('poll_id', poll_id)
p = get_object_or_404(Poll, pk=poll_id)
return render_to_response('polls/detail.html', {'poll': p})

カスタムパラメーターに使用する値は、 json モジュールが提供する JSON エンコーダーでシリアライズできるものであれば、どのようなものでも使用できます。これにはタプル、リスト、ディクショナリーが含まれます。

推奨: 値を整数、浮動小数点、文字列に制限します。より複雑なデータ構造を使用する場合は、あまり大きなデータ構造を関連付けないようにしてください。収穫されるまでキャッシュし、パッケージ化してコアアプリケーションに送信する必要があるからです。

また、値がJSONにシリアライズできない場合、エラーの詳細や遅いトランザクションが捨てられてしまう可能性があるため、シンプルな値が望ましいです。

カスタムメトリクスの記録

我々は、我々が知っている公的に利用可能なPythonのサードパーティモジュールのみをインスツルメンテーションすることができます。あなた自身のコードのためにインストルメンテーションを拡張するには、 adding Python instrumentation で説明されているテクニックを使用してください。これにより、ウェブトランザクションのパフォーマンスブレークダウンデータや低速トランザクションのトレースをカバーすることができます。

APIコールを介して任意のパフォーマンスデータを記録することができます(例えば、タイミングやコンピュータリソースのデータなど)。その後、 データエクスプローラー を使用して、そのメトリックをグラフ化し、追跡することができます。カスタムメトリクスを使用して、モニタリングを統一することができます。

カスタム メトリクスを記録するには、 newrelic.agentモジュールでrecord_custom_metric()関数を使用します。メトリックの名前と値の 2 つの引数を取ります。値は整数または浮動小数点値である必要があります。

import newrelic.agent
def create_account(request, ...):
...
newrelic.agent.record_custom_metric('Custom/Signups', 1)
...
return render_to_response('...', ...)

メトリック名Custom/のパスを開始して、既存のエージェント メトリック ( Custom/MyMetricなど) との名前空間の競合を回避します。

カスタム メトリックは、収集サイクルごとに集計され、コレクターに送信されます。この場合、各1が加算されて、収穫サイクルのサインアップ数が記録されます。

関数トレース機能は、関数呼び出しやコードブロック内の時間を追跡するために使用されますが、個別のカスタムチャートを作成することはできません。カスタムメトリクスを使用して、何かにかかった時間を記録し、チャートにすることはできます。

これを容易にするために、メトリックのタイミングと記録のためのコンテキスト・マネージャー・クラスを事前に定義することができます。

class CustomMetricTimedNode(object):
def __init__(self, name):
self.name = name
self.start_time = None
self.end_time = None
def __enter__(self):
self.start_time = time.time()
return self
def __exit__(self, exc, value, tb):
if not self.start_time:
return
self.end_time = time.time()
duration = self.end_time - self.start_time
newrelic.agent.record_custom_metric(self.name, duration)

これは、コード ブロックを囲むwithステートメントと組み合わせて使用できます。

def function():
with CustomMetricTimedNode('Custom/TimedNode1'):
time.sleep(0.01)

このコンテキストマネージャーを関数に適用するには、関数デコレーターを作成します。

def custom_metric_timed_node(name):
def _decorator(f):
@functools.wraps(f)
def _wrapper(*args, **kwargs):
with CustomMetricTimedNode(name):
return f(*args, **kwargs)
return _wrapper
return _decorator

として使用されていると。

@custom_metric_timed_node('Custom/TimedNode2')
def function():
time.sleep(0.01)

関数トレースのためにインスツルメンテーションを追加する場合と同様に、メトリック名は有限のセット内で、比較的小さな長さのものを選ぶことをお勧めします。値に制限のない名前は避けるべきです。そうしないと、大量の名前を意味のある形で表示することが難しくなります。また、ユニークな名前が多いと、メモリが過剰に使用され、エージェントが名前を強制的に正規化して、ユニークな名前の数を制限することになります。

注意

あまりにも多くのメトリクスを収集すると、アプリケーションとエージェントの両方のパフォーマンスに影響を与える可能性があります。潜在的なデータの問題を回避するために、カスタムインスツルメンテーションによって導入されるユニークなメトリクスの総数を2000以下に抑えるようにしてください。

Copyright © 2022 New Relic Inc.

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.