Python アプリケーション向け New Relic APM 設定ガイド
Python アプリケーションでの New Relic APM 導入は、動的な言語特性を活かした柔軟な監視ソリューションを提供します。Python エージェントは、主要なフレームワークとの深い統合、WSGI/ASGI アプリケーションの包括的な監視、豊富なカスタマイズオプションを実現します。
Python エージェントの特徴
New Relic Python エージェントは、インタープリター レベルでの動的計測により、アプリケーションの実行時動作を詳細に追跡します。デコレータベースの計測システムとコンテキスト管理により、Pythonic な監視実装を可能にします。
Django、Flask、FastAPI、Tornado などの主要フレームワークとの自動統合により、フレームワーク固有の処理パターンを効率的に監視できます。また、非同期処理(asyncio)、バックグラウンドタスク(Celery)、データ処理パイプラインなど、Python エコシステムの多様な実行パターンに対応しています。
導入前の準備
環境要件の確認
Python エージェントは以下の環境での動作をサポートしています:
対応 Python バージョン:
- CPython: 3.7, 3.8, 3.9, 3.10, 3.11, 3.12
- PyPy3: 3.7以降の互換バージョン
- Jython: 限定サポート(一部機能のみ)
パフォーマンス影響: メモリオーバーヘッドは通常30-80MB、CPU オーバーヘッドは2-4%程度です。パッケージ管理には pip、conda、Poetry などの標準ツールを使用できます。
仮想環境の設定
本番環境での安定した運用のため、仮想環境での環境分離を推奨します。
# venv を使用した仮想環境の作成
python -m venv newrelic-env
source newrelic-env/bin/activate # Linux/macOS
# newrelic-env\Scripts\activate # Windows
# Poetry を使用した場合
poetry init
poetry add newrelic
エージェントのインストール
pip を使用したインストール
pip install newrelic
requirements.txt への追加
newrelic>=9.2.0 # 最新版推奨(Python 3.12 対応)
Poetry プロジェクトでの追加
poetry add newrelic
基本設定の構成
設定ファイルの生成
New Relic エージェントの設定ファイルを生成します。
newrelic-admin generate-config YOUR_LICENSE_KEY newrelic.ini
設定ファイルの編集
生成された newrelic.ini
ファイルを編集し、アプリケーション固有の設定を行います。
[newrelic]
license_key = YOUR_LICENSE_KEY
app_name = My Python Application
# ログ設定
log_file = /tmp/newrelic-python-agent.log
log_level = info
# トランザクション設定
transaction_tracer.enabled = true
transaction_tracer.transaction_threshold = 2.0
transaction_tracer.record_sql = obfuscated
transaction_tracer.stack_trace_threshold = 0.5
# エラー収集設定
error_collector.enabled = true
error_collector.ignore_errors = requests.exceptions.ConnectionError
# ブラウザ監視設定
browser_monitoring.auto_instrument = true
フレームワーク別設定
Django アプリケーション
Django プロジェクトでは、WSGI ファイルまたは manage.py での初期化を行います。
settings.py での設定
# settings.py
import newrelic.agent
# New Relic エージェントの初期化
newrelic.agent.initialize('/path/to/newrelic.ini')
# Django設定
INSTALLED_APPS = [
'newrelic', # オプション:Django固有の統合
# その他のアプリ
]
# ミドルウェア設定
MIDDLEWARE = [
'newrelic.agent.django_middleware',
# その他のミドルウェア
]
wsgi.py での設定
# wsgi.py
import os
import newrelic.agent
# New Relic設定の初期化
newrelic.agent.initialize()
from django.core.wsgi import get_wsgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myproject.settings')
application = get_wsgi_application()
# WSGIアプリケーションのラップ
application = newrelic.agent.wsgi_application()(application)
Flask アプリケーション
Flask アプリケーションでは、アプリケーション初期化時にエージェントを設定します。
# app.py
import newrelic.agent
newrelic.agent.initialize()
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello():
return 'Hello, World!'
if __name__ == '__main__':
app.run()
FastAPI アプリケーション
FastAPI では ASGI アプリケーションとしてエージェントを統合します。
# main.py
import newrelic.agent
newrelic.agent.initialize()
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
async def read_root():
return {"Hello": "World"}
# ASGI アプリケーションのラップ
app = newrelic.agent.asgi_application()(app)
起動方法の設定
環境変数による設定
export NEW_RELIC_CONFIG_FILE=/path/to/newrelic.ini
export NEW_RELIC_ENVIRONMENT=production
python app.py
newrelic-admin コマンドによる起動
newrelic-admin run-program python app.py
Gunicorn での起動
newrelic-admin run-program gunicorn --bind 0.0.0.0:8000 myapp:app
uWSGI での起動
newrelic-admin run-program uwsgi --http :8000 --module myapp:app
カスタム計測の実装
デコレータベースの計測
重要な関数やメソッドにカスタム計測を追加できます。
import newrelic.agent
@newrelic.agent.function_trace()
def important_business_logic():
# ビジネスロジック
pass
@newrelic.agent.background_task()
def background_process():
# バックグラウンド処理
pass
class PaymentService:
@newrelic.agent.function_trace('PaymentService/process_payment')
def process_payment(self, amount):
# 支払い処理
newrelic.agent.record_custom_metric('Custom/PaymentAmount', amount)
コンテキストマネージャーによる計測
import newrelic.agent
def complex_operation():
with newrelic.agent.FunctionTrace('ComplexOperation/database_query'):
# データベース処理
pass
with newrelic.agent.FunctionTrace('ComplexOperation/api_call'):
# API呼び出し
pass
非同期処理の計測
import asyncio
import newrelic.agent
@newrelic.agent.background_task()
async def async_background_task():
await asyncio.sleep(1)
newrelic.agent.record_custom_event('AsyncTaskCompleted', {
'duration': 1.0,
'task_type': 'background'
})
async def main():
await async_background_task()
Celery 統合
Celery タスクの監視
# tasks.py
import newrelic.agent
from celery import Celery
app = Celery('tasks')
@app.task
@newrelic.agent.background_task()
def add(x, y):
result = x + y
newrelic.agent.record_custom_metric('Custom/CeleryTask/Add', result)
return result
Celery ワーカーの起動
newrelic-admin run-program celery -A tasks worker --loglevel=info
データベース監視の詳細設定
SQLAlchemy 統合
from sqlalchemy import create_engine
import newrelic.agent
# データベースエンジンの作成
engine = create_engine('postgresql://user:password@localhost/dbname')
# 自動的にSQLクエリが監視される
Django ORM の詳細監視
[newrelic]
# Django ORM固有の設定
database_name_reporting.enabled = true
transaction_tracer.explain_enabled = true
transaction_tracer.explain_threshold = 500
パフォーマンス最適化
エージェント設定の調整
[newrelic]
# パフォーマンス影響を最小化する設定
transaction_tracer.top_n = 20
error_collector.max_stack_trace_lines = 50
agent_limits.transaction_traces_nodes = 2000
メモリ使用量の最適化
import newrelic.agent
# エージェント設定のプログラムによる調整
settings = newrelic.agent.global_settings()
settings.transaction_tracer.explain_threshold = 1.0
settings.slow_sql.enabled = True
監視データの確認とアラート設定
カスタムメトリクスの記録
import newrelic.agent
def business_metric_example():
# ビジネスメトリクスの記録
newrelic.agent.record_custom_metric('Business/Revenue', 1500.00)
newrelic.agent.record_custom_metric('Business/UserSignups', 5)
# カスタムイベントの記録
newrelic.agent.record_custom_event('UserAction', {
'user_id': 12345,
'action_type': 'purchase',
'amount': 99.99
})
セキュリティベストプラクティス
OWASP Top 10に準拠したセキュリティ設定:
[newrelic]
# 機密情報の自動難読化
capture_params = false
ignored_params = password,credit_card,ssn,api_key,token
# HTTPSアクセスの強制
ssl = true
# 属性から機密情報を除外
attributes.exclude = request.headers.authorization,
request.headers.x-api-key,
request.parameters.password,
request.parameters.credit_card
# セキュリティヘッダーの監視
browser_monitoring.auto_instrument = true
高度なエラーハンドリング
包括的なエラー追跡と分析の実装例:
import newrelic.agent
import logging
from functools import wraps
from enum import Enum
class ErrorSeverity(Enum):
LOW = "low"
MEDIUM = "medium"
HIGH = "high"
CRITICAL = "critical"
class AdvancedErrorHandler:
def __init__(self):
self.logger = logging.getLogger(__name__)
def handle_error(self, exception, severity=ErrorSeverity.MEDIUM, **extra_attributes):
"""包括的なエラーハンドリング"""
attributes = {
'error.severity': severity.value,
'error.class': type(exception).__name__,
'error.message': str(exception),
**extra_attributes
}
# エラーカテゴリ別の分類
if isinstance(exception, ValueError):
attributes['error.category'] = 'validation'
newrelic.agent.record_custom_metric('Errors/Validation', 1)
elif isinstance(exception, ConnectionError):
attributes['error.category'] = 'network'
newrelic.agent.record_custom_metric('Errors/Network', 1)
elif isinstance(exception, PermissionError):
attributes['error.category'] = 'security'
newrelic.agent.record_custom_metric('Errors/Security', 1)
else:
attributes['error.category'] = 'unexpected'
newrelic.agent.record_custom_metric('Errors/Unexpected', 1)
# New Relicへのエラー報告
newrelic.agent.notice_error(attributes=attributes)
# 重要度に応じたアラート
if severity == ErrorSeverity.CRITICAL:
newrelic.agent.record_custom_metric('Errors/Critical', 1)
self._trigger_critical_alert(exception, attributes)
self.logger.error(f"Error handled: {exception}", extra=attributes)
def _trigger_critical_alert(self, exception, attributes):
"""クリティカルエラー用のアラート送信"""
# アラート送信ロジック
self.logger.critical(f"Critical error detected: {exception}")
def error_tracking_decorator(severity=ErrorSeverity.MEDIUM, **extra_attrs):
"""エラートラッキング用デコレータ"""
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
try:
return func(*args, **kwargs)
except Exception as e:
error_handler = AdvancedErrorHandler()
error_handler.handle_error(
e,
severity=severity,
function_name=func.__name__,
**extra_attrs
)
raise
return wrapper
return decorator
# 使用例
@error_tracking_decorator(severity=ErrorSeverity.HIGH, module='payment')
@newrelic.agent.function_trace()
def process_payment(payment_data):
# 支払い処理ロジック
if not payment_data.get('amount'):
raise ValueError("Payment amount is required")
# 処理継続...
ビジネスメトリクス収集
アプリケーション固有のビジネス価値を測定するカスタムメトリクス:
import newrelic.agent
from datetime import datetime
from functools import wraps
class BusinessMetricsCollector:
"""ビジネスメトリクス収集クラス"""
@staticmethod
def track_user_action(action_type, user_id, **metadata):
"""ユーザーアクション追跡"""
attributes = {
'user_id': user_id,
'action_type': action_type,
'timestamp': datetime.now().isoformat(),
**metadata
}
# メトリクス記録
newrelic.agent.record_custom_metric(f'Business/UserActions/{action_type}', 1)
newrelic.agent.record_custom_event('UserAction', attributes)
@staticmethod
def track_revenue(amount, currency='USD', category=None, **metadata):
"""売上追跡"""
attributes = {
'amount': amount,
'currency': currency,
'category': category or 'general',
'timestamp': datetime.now().isoformat(),
**metadata
}
# 売上メトリクス
newrelic.agent.record_custom_metric('Business/Revenue/Total', amount)
if category:
newrelic.agent.record_custom_metric(f'Business/Revenue/Category/{category}', amount)
newrelic.agent.record_custom_event('RevenueGenerated', attributes)
@staticmethod
def track_conversion(conversion_type, funnel_stage, **metadata):
"""コンバージョン追跡"""
attributes = {
'conversion_type': conversion_type,
'funnel_stage': funnel_stage,
'timestamp': datetime.now().isoformat(),
**metadata
}
newrelic.agent.record_custom_metric(f'Business/Conversions/{conversion_type}', 1)
newrelic.agent.record_custom_event('ConversionEvent', attributes)
def business_metrics_decorator(metric_type, **default_attrs):
"""ビジネスメトリクス記録用デコレータ"""
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
start_time = datetime.now()
try:
result = func(*args, **kwargs)
# 成功メトリクス
duration = (datetime.now() - start_time).total_seconds()
attributes = {
'function_name': func.__name__,
'duration': duration,
'status': 'success',
**default_attrs
}
newrelic.agent.record_custom_metric(f'Business/{metric_type}/Success', 1)
newrelic.agent.record_custom_metric(f'Business/{metric_type}/Duration', duration)
newrelic.agent.record_custom_event(f'{metric_type}Completed', attributes)
return result
except Exception as e:
# 失敗メトリクス
duration = (datetime.now() - start_time).total_seconds()
attributes = {
'function_name': func.__name__,
'duration': duration,
'status': 'error',
'error_type': type(e).__name__,
**default_attrs
}
newrelic.agent.record_custom_metric(f'Business/{metric_type}/Error', 1)
newrelic.agent.record_custom_event(f'{metric_type}Failed', attributes)
raise
return wrapper
return decorator
# 使用例
@business_metrics_decorator('OrderProcessing', priority='high')
@newrelic.agent.function_trace()
def process_order(order_data):
"""注文処理"""
# 注文処理ロジック
order_total = calculate_order_total(order_data)
# ビジネスメトリクスの記録
BusinessMetricsCollector.track_revenue(
amount=order_total,
category=order_data.get('category', 'general'),
customer_segment=order_data.get('customer_type', 'regular')
)
BusinessMetricsCollector.track_conversion(
conversion_type='purchase',
funnel_stage='checkout_complete',
order_value=order_total
)
return order_total
# FastAPI/Flask での実装例
from flask import Flask, request
import newrelic.agent
app = Flask(__name__)
@app.route('/api/purchase', methods=['POST'])
@newrelic.agent.web_transaction()
def purchase_endpoint():
try:
order_data = request.get_json()
# ユーザーアクション追跡
BusinessMetricsCollector.track_user_action(
action_type='purchase_attempt',
user_id=order_data.get('user_id'),
product_category=order_data.get('category')
)
# 注文処理
result = process_order(order_data)
return {'status': 'success', 'order_total': result}
except Exception as e:
# エラー処理と追跡
error_handler = AdvancedErrorHandler()
error_handler.handle_error(
e,
severity=ErrorSeverity.HIGH,
endpoint='/api/purchase',
user_id=order_data.get('user_id', 'unknown')
)
return {'status': 'error', 'message': str(e)}, 500
本番環境でのデプロイメント
環境別設定の管理
[newrelic:production]
app_name = MyApp (Production)
monitor_mode = true
log_level = info
[newrelic:staging]
app_name = MyApp (Staging)
monitor_mode = true
log_level = debug
[newrelic:development]
app_name = MyApp (Development)
monitor_mode = false
log_level = debug
Docker コンテナでの設定
FROM python:3.11-slim
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY newrelic.ini .
COPY app.py .
# New Relic エージェントでアプリケーションを起動
CMD ["newrelic-admin", "run-program", "python", "app.py"]
Kubernetes での設定
apiVersion: apps/v1
kind: Deployment
metadata:
name: python-app
spec:
template:
spec:
containers:
- name: app
image: myapp:latest
env:
- name: NEW_RELIC_CONFIG_FILE
value: "/app/newrelic.ini"
- name: NEW_RELIC_ENVIRONMENT
value: "production"
トラブルシューティング
一般的な問題の診断
import newrelic.agent
# エージェント状態の確認
print(f"Agent version: {newrelic.agent.version}")
print(f"Config file: {newrelic.agent.config_file}")
# アプリケーション情報の確認
application = newrelic.agent.application()
print(f"Application name: {application.name}")
print(f"Application settings: {application.settings}")
ログ分析
[newrelic]
log_file = /var/log/newrelic/python-agent.log
log_level = debug
audit_log_file = /var/log/newrelic/python-audit.log
Python アプリケーションでの New Relic APM 導入により、動的な言語特性を活かした詳細なパフォーマンス監視を実現できます。適切な設定と統合により、Python エコシステムの多様な実行パターンに対応した包括的な監視システムを構築できます。
関連記事: Node.js APM設定関連記事: 分散トレーシング設定