この機械翻訳は、参考として提供されています。

英語版と翻訳版に矛盾がある場合は、英語版が優先されます。詳細については、このページを参照してください。

問題を作成する

メッセージキューに Amazon SQS を使用する

Javaエージェントは、 AWS SQS メッセージキューのインストゥルメンテーションをサポートしています。 SQS インストゥルメンテーションはメッセージ ブローカー トレースを生成しますが、SQS SDK の使用法に関する追加情報が必要になる場合があります。

サポートされているすべての SQS ライブラリを確認するには、 Java の互換性と要件のページを参照してください。

重要

Javaエージェント 8.18.0 のユーザーは、SQS インストゥルメンテーションを手動で有効にする必要があります。 このインストゥルメンテーションは、 newrelic.ymlファイルで有効にできます。

class_transformer:
aws-java-sdk-sqs:
enabled: true

あるいは、システム プロパティ-Dnewrelic.config.class_transformer.aws-java-sdk-sqs.enabled=trueまたは環境変数NEW_RELIC_CLASS_TRANSFORMER_AWS_JAVA_SDK_SQS_ENABLED=trueを設定することもできます。

インストゥルメンテーションは、 Javaエージェントの他のバージョンではデフォルトで有効になっています。

View SQS ディストリビューティッド(分散)トレーシング

AWS SQS SDK インストゥルメンテーションには、SQS メッセージのメッセージ属性としてディストリビューティッド(分散)トレーシング ヘッダーが自動的に含まれます。 この機能はバージョン 2.1.0 以降で利用できます。 ただし、メッセージ受信操作の場合、これらのヘッダーを処理する組み込みメソッドはありません。 ディストリビューティッド(分散)トレーシング ヘッダーを読み取るためにカスタムインストゥルメンテーションを実装することをお勧めします。

以下は、V2 SDK を使用して SQS メッセージからディストリビューティッド(分散)トレーシング ヘッダーを読み取る方法の例です。

// This method will call the SDK to receive messages and then process them
public void readMessages(SqsClient sqsClient, String queueUrl) {
List<Message> msgs = receiveMessages(queueUrl);
for (Message msg : msgs) {
handleMessage(msg);
}
}
// Since calling the SDK to recieve messages is a batch call, it is not recommended to accept distributed trace headers
// in the same transaction as the SDK call. Distributed traces can only have one parent span.
@Trace(dispatcher = true, metricName = "v2/receiveMessages")
public List<Message> receiveMessages(SqsClient sqsClient, String queueUrl) {
ReceiveMessageRequest request = ReceiveMessageRequest.builder()
.queueUrl(queueUrl)
.maxNumberOfMessages(10)
.build();
List<Message> messages = sqsClient.receiveMessage(request).messages();
if (messages.isEmpty()) {
logger.info("[v2 API] No messages received");
}
return messages;
}
// Here we accept distributed trace headers in a seperate transaction from the SDK call.
@Trace(dispatcher = true, metricName = "v2/handleMessage")
public void handleMessage(Message msg, SqsClient sqsClient, String queueUrl) {
// We use a wrapper class that helps extract the distributed trace headers
SQSReceivedMessageHeaders headers = new SQSReceivedMessageHeaders(msg);
// Here we accept the distributed trace headers
NewRelic.getAgent().getTransaction().acceptDistributedTraceHeaders(TransportType.Other, headers);
// Process your message here
DeleteMessageRequest deleteMessageRequest = DeleteMessageRequest.builder()
.queueUrl(queueUrl)
.receiptHandle(msg.receiptHandle())
.build();
sqsClient.deleteMessage(deleteMessageRequest);
}

以下は、SQS メッセージからディストリビューティッド(分散)トレーシング ヘッダーを抽出するラッパー クラスSQSReceivedMessageHeadersです。

import com.newrelic.api.agent.HeaderType;
import com.newrelic.api.agent.Headers;
import software.amazon.awssdk.services.sqs.model.Message;
import software.amazon.awssdk.services.sqs.model.MessageAttributeValue;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
public class SQSReceivedMessageHeaders implements Headers {
private Message message = null;
public SQSReceivedMessageHeaders(Message msg) {
message = msg;
}
@Override
public HeaderType getHeaderType() {
return HeaderType.MESSAGE;
}
@Override
public String getHeader(String name) {
String value = null;
Map<String, MessageAttributeValue> msgAttributes = message.messageAttributes();
MessageAttributeValue msgAttributeValue = msgAttributes.get(name);
if(msgAttributeValue != null) {
if(msgAttributeValue.dataType().equalsIgnoreCase("string")) {
value = msgAttributeValue.stringValue();
}
}
return value;
}
@Override
public Collection<String> getHeaders(String name) {
List<String> list = new ArrayList<String>();
String value = getHeader(name);
if(value != null && !value.isEmpty()) {
list.add(value);
}
return list;
}
@Override
public void setHeader(String name, String value) {
// Not supported
}
@Override
public void addHeader(String name, String value) {
// Not supported
}
@Override
public Collection<String> getHeaderNames() {
if(message != null) {
Map<String, MessageAttributeValue> attributes = message.messageAttributes();
if(attributes != null) return attributes.keySet();
}
return Collections.emptyList();
}
@Override
public boolean containsHeader(String name) {
return getHeaderNames().contains(name);
}
}