Java アプリケーション向け New Relic APM 設定ガイド

Java アプリケーションでの New Relic APM 導入は、エンタープライズ環境での実績ある監視ソリューションを提供します。Java エージェントは、様々なフレームワークとの統合、詳細なJVM監視、包括的なパフォーマンス分析を実現します。

Java エージェントの特徴

New Relic Java エージェントは、JVM レベルでの深い統合により、アプリケーションの動作を詳細に監視します。バイトコードの動的計測技術を活用し、既存のアプリケーションコードを変更することなく包括的な監視を実現します。

主要なJavaフレームワークとの自動統合により、Spring、Spring Boot、Hibernate、MyBatis、Struts などの一般的な技術スタックを即座に監視対象とできます。また、JVM のガベージコレクション、メモリ使用量、スレッド状況なども詳細に追跡します。

導入前の準備

システム要件の確認

Java エージェントは以下のバージョンに対応しており、包括的なJVM環境をサポートします:

対応JDK:

  • Oracle JDK: 8, 11, 17, 21 (LTS版すべて対応)
  • OpenJDK: 8以降(最新版まで対応)
  • Amazon Corretto: 8, 11, 17, 21
  • Eclipse Temurin: 8以降
  • GraalVM: Native Image含む

パフォーマンス影響: 追加メモリ使用量は通常64-128MB、CPU オーバーヘッドは1-3%程度です。

New Relic アカウントの準備

New Relic アカウントの作成とライセンスキーの取得が必要です。アカウント設定では、データの保存リージョンとセキュリティポリシーを適切に構成します。

エージェントのダウンロードと配置

エージェントファイルの取得

New Relic Java エージェント(newrelic.jar)をダウンロードし、アプリケーションサーバーの適切なディレクトリに配置します。一般的には /opt/newrelic/ または /usr/local/newrelic/ ディレクトリを使用します。

bash
# エージェントディレクトリの作成
mkdir -p /opt/newrelic
cd /opt/newrelic

# エージェントのダウンロード(バージョンは最新のものを使用)
curl -O https://download.newrelic.com/newrelic/java-agent/newrelic-agent/current/newrelic-java.zip
unzip newrelic-java.zip

設定ファイルの準備

newrelic.yml 設定ファイルを編集し、ライセンスキーとアプリケーション名を設定します。

yaml
common: &default_settings
  license_key: 'YOUR_LICENSE_KEY_HERE'
  agent_enabled: true
  app_name: 'My Java Application'
  enable_auto_app_naming: false
  enable_auto_transaction_naming: true
  log_level: info

production:
  <<: *default_settings
  
development:
  <<: *default_settings
  log_level: debug

JVMパラメータの設定

基本的なJVMオプション

Java アプリケーション起動時に、New Relic エージェントを有効化するJVMパラメータを追加します。

bash
java -javaagent:/opt/newrelic/newrelic.jar \
     -Dnewrelic.config.file=/opt/newrelic/newrelic.yml \
     -jar your-application.jar

アプリケーションサーバー別設定

Tomcat での設定

catalina.sh または setenv.sh ファイルにJVMオプションを追加します。

bash
JAVA_OPTS="$JAVA_OPTS -javaagent:/opt/newrelic/newrelic.jar"
JAVA_OPTS="$JAVA_OPTS -Dnewrelic.config.file=/opt/newrelic/newrelic.yml"

Spring Boot での設定

Spring Boot アプリケーションでは、起動コマンドまたは環境変数でエージェントを指定します。

bash
# 起動コマンドでの指定
java -javaagent:/opt/newrelic/newrelic.jar -jar myapp.jar

# 環境変数での指定
export JAVA_TOOL_OPTIONS="-javaagent:/opt/newrelic/newrelic.jar"

フレームワーク固有の設定

Spring Framework 統合

Spring Framework を使用するアプリケーションでは、自動的にコントローラーメソッド、サービスクラス、リポジトリレイヤーが監視対象となります。@Transactional アノテーションが付与されたメソッドも自動的に追跡されます。

データベース監視の詳細設定

JPA/Hibernateクエリ、JDBC接続、トランザクション境界を詳細に監視するための設定を追加できます。

yaml
common: &default_settings
  database_name_reporting:
    enabled: true
  transaction_tracer:
    enabled: true
    explain_enabled: true
    explain_threshold: 500
    record_sql: obfuscated

カスタム計測の追加

アノテーションベースの計測

重要なビジネスロジックにカスタム計測を追加する場合、@NewRelic アノテーションを使用します。

java
import com.newrelic.api.agent.NewRelic;
import com.newrelic.api.agent.Trace;

@Service
public class OrderService {
    
    @Trace(dispatcher = true)
    public void processOrder(Order order) {
        // ビジネスロジック
        NewRelic.recordMetric("Custom/OrderProcessed", 1);
    }
}

プログラムによる計測

より詳細な制御が必要な場合、New Relic API を直接使用してメトリクスを記録できます。

java
import com.newrelic.api.agent.NewRelic;

public class PaymentProcessor {
    public void processPayment(Payment payment) {
        long startTime = System.currentTimeMillis();
        try {
            // 支払い処理
            NewRelic.recordMetric("Custom/PaymentSuccess", 1);
        } catch (Exception e) {
            NewRelic.noticeError(e);
            NewRelic.recordMetric("Custom/PaymentError", 1);
        } finally {
            long duration = System.currentTimeMillis() - startTime;
            NewRelic.recordResponseTimeMetric("Custom/PaymentDuration", duration);
        }
    }
}

パフォーマンス最適化

エージェント設定の調整

本番環境でのパフォーマンス影響を最小限に抑えるため、適切な設定調整を行います。

yaml
common: &default_settings
  transaction_tracer:
    transaction_threshold: 2.0
    top_n: 20
    stack_trace_threshold: 0.5
  error_collector:
    max_stack_trace_lines: 30
    ignore_errors: 'java.lang.IllegalArgumentException'

JVM ヒープサイズの考慮

New Relic エージェントによる追加メモリ使用量を考慮し、必要に応じてJVMヒープサイズを調整します。

bash
JAVA_OPTS="-Xms2g -Xmx4g -javaagent:/opt/newrelic/newrelic.jar"

監視データの確認

基本メトリクスの確認

エージェント導入後、New Relic UIでアプリケーションの基本的なパフォーマンスメトリクスを確認できます。応答時間、スループット、エラー率などの主要指標が自動的に収集されます。

JVM 監視

ガベージコレクションの頻度と実行時間、ヒープメモリ使用量、スレッド状況などのJVM固有のメトリクスも詳細に監視されます。

データベースパフォーマンス

実行されたSQLクエリ、実行時間、スロークエリの特定など、データベース関連のパフォーマンス情報も包括的に分析できます。

トラブルシューティング

一般的な問題と解決方法

エージェントが正常に起動しない場合、ログファイルを確認し、ライセンスキーの妥当性、ネットワーク接続、JVMバージョンの互換性を検証します。

ログ分析

New Relic エージェントのログは、デフォルトで logs/newrelic_agent.log に出力されます。問題の特定と解決に重要な情報を提供します。

yaml
common: &default_settings
  log_level: debug
  log_file_path: './logs/newrelic_agent.log'
  log_daily: true

セキュリティとベストプラクティス

機密情報の保護

データベースクエリや HTTP パラメータに含まれる機密情報を適切に難読化するための設定を行います。

yaml
common: &default_settings
  # OWASPセキュリティベストプラクティスに準拠
  transaction_tracer:
    record_sql: obfuscated
  capture_params: false
  ignored_params: 'credit_card,password,ssn,api_key,token'
  attributes:
    exclude:
      - request.parameters.password
      - request.parameters.credit_card
      - request.parameters.ssn
      - request.headers.authorization
      - request.headers.x-api-key
  # セキュリティヘッダーの監視
  browser_monitoring:
    auto_instrument: true
    loader: spa

高度なエラーハンドリング実装

包括的なエラー追跡と分析のための実装例:

java
@Component
public class AdvancedErrorHandler {
    private static final Logger logger = LoggerFactory.getLogger(AdvancedErrorHandler.class);
    
    @EventListener
    @Trace
    public void handleApplicationError(ApplicationErrorEvent event) {
        Map<String, Object> attributes = new HashMap<>();
        attributes.put("error.severity", event.getSeverity().name());
        attributes.put("error.module", event.getModuleName());
        attributes.put("error.user_id", event.getUserId());
        attributes.put("error.request_id", event.getRequestId());
        
        // エラーカテゴリ別の分類
        if (event.getException() instanceof ValidationException) {
            attributes.put("error.category", "validation");
            NewRelic.recordMetric("Errors/Validation", 1);
        } else if (event.getException() instanceof DataAccessException) {
            attributes.put("error.category", "database");
            NewRelic.recordMetric("Errors/Database", 1);
        } else if (event.getException() instanceof ServiceUnavailableException) {
            attributes.put("error.category", "external_service");
            NewRelic.recordMetric("Errors/ExternalService", 1);
        }
        
        // New Relicへのエラー報告
        NewRelic.noticeError(event.getException(), attributes);
        
        // 重要度に応じたアラート
        if (event.getSeverity() == ErrorSeverity.CRITICAL) {
            NewRelic.recordMetric("Errors/Critical", 1);
            // 緊急アラートトリガー
            triggerCriticalAlert(event);
        }
    }
    
    @Trace
    private void triggerCriticalAlert(ApplicationErrorEvent event) {
        // アラート送信ロジック
        logger.error("Critical error detected: {}", event.getException().getMessage());
    }
}

ビジネスメトリクス収集

アプリケーション固有のビジネス価値を測定するカスタムメトリクス:

java
@Service
public class BusinessMetricsService {
    
    @EventListener
    @Trace
    public void onOrderCompleted(OrderCompletedEvent event) {
        Map<String, Object> attributes = new HashMap<>();
        attributes.put("order.value", event.getOrderValue());
        attributes.put("customer.segment", event.getCustomerSegment());
        attributes.put("product.category", event.getProductCategory());
        attributes.put("payment.method", event.getPaymentMethod());
        
        // 売上メトリクス
        NewRelic.recordMetric("Business/Revenue/Total", event.getOrderValue());
        NewRelic.recordMetric("Business/Orders/Completed", 1);
        
        // カテゴリ別売上
        String categoryMetric = "Business/Revenue/Category/" + event.getProductCategory();
        NewRelic.recordMetric(categoryMetric, event.getOrderValue());
        
        // カスタムイベントの送信
        NewRelic.recordCustomEvent("OrderCompleted", attributes);
    }
    
    @Scheduled(fixedRate = 60000) // 1分間隔
    @Trace
    public void collectActiveUsers() {
        int activeUsers = userSessionService.getActiveUserCount();
        NewRelic.recordMetric("Business/Users/Active", activeUsers);
        
        // ユーザーセグメント別の集計
        Map<String, Integer> segmentCounts = userSessionService.getActiveUsersBySegment();
        segmentCounts.forEach((segment, count) -> {
            String metricName = "Business/Users/Active/Segment/" + segment;
            NewRelic.recordMetric(metricName, count);
        });
    }
    
    @EventListener
    @Trace
    public void onUserRegistration(UserRegistrationEvent event) {
        Map<String, Object> attributes = new HashMap<>();
        attributes.put("user.source", event.getRegistrationSource());
        attributes.put("user.plan", event.getSubscriptionPlan());
        attributes.put("user.country", event.getCountry());
        
        NewRelic.recordMetric("Business/Users/Registered", 1);
        NewRelic.recordCustomEvent("UserRegistered", attributes);
        
        // 獲得チャネル別の追跡
        String sourceMetric = "Business/Users/Acquisition/" + event.getRegistrationSource();
        NewRelic.recordMetric(sourceMetric, 1);
    }
}

本番環境でのデプロイ

段階的なデプロイメント戦略により、New Relic エージェントの本番環境導入リスクを最小化します。カナリアデプロイやブルーグリーンデプロイメントと組み合わせることで、安全な監視システムの構築を実現します。

デプロイメント手順:

  1. ステージング環境での十分なテスト(最低1週間)
  2. カナリアリリース(全トラフィックの5-10%)
  3. 段階的な本番展開(25% → 50% → 100%)
  4. 24時間の監視期間とロールバック準備

Java アプリケーションでの New Relic APM 導入により、包括的なパフォーマンス監視と継続的な最適化を実現できます。適切な設定と運用により、高品質なアプリケーション体験を継続的に提供し、ビジネス価値の向上を支援します。


関連記事: APM概要・アーキテクチャ関連記事: APM設定完全リファレンス