Define an Exit Call
For an inventoryServer.verifyQuantities(orders)
, which makes a request to
another process, you can monitor that request as an Exit Call. This helps to continue
monitoring the Business Transaction through the call to the downstream server and identify
the time spent in the remote service. You can do this by modifying the method as
follows:
public void verifyQuantities(List<ItemOrders> orders) {
ExitCall exitCall = null;
try {
exitCall = AppdynamicsAgent.getTransaction().startExitCall("Quantity Check", "Inventory Server", ExitTypes.HTTP, false);
/*******************
* Method Body
*******************/
} finally {
if (exitCall != null) {
exitCall.end();
}
}
}
Alternatively, if you want to use HTTP Backend detection rules, you can use the
startHttpExitCall
method:
public void verifyQuantities(List<ItemOrders> orders) {
ExitCall exitCall = null;
try {
Map<String, String> identifyingProps = new HashMap<String, String>();
URL url = new URL("https://www.appdynamics.com/solutions/microservices/");
exitCall = AppdynamicsAgent.getTransaction().startExitCall(identifyingProps, url, false);
/*******************
* Method Body
*******************/
} finally {
if (exitCall != null) {
exitCall.end();
}
}
}
The above code modifications define the Exit Call that manifests it as a remote service in the controller. To tag and follow the request into an instrumented downstream tier, add a correlation header:
public void verifyQuantities(List<ItemOrders> orders) {
ExitCall exitCall = null;
try {
exitCall = AppdynamicsAgent.getTransaction().startExitCall("Quantity Check", "Inventory Server", ExitTypes.HTTP, false);
// Generate the appdynamics correlation header
String correlationHeader = exitCall.getCorrelationHeader();
// ... Method code including request creation
// Modify the request/payload to include the correlation header
inventoryRequest.addHeader(AppdynamicsAgent.TRANSACTION_CORRELATION_HEADER, correlationHeader);
} finally {
if (exitCall != null) {
exitCall.end();
}
}
}
The following example shows how to instrument an asynchronous exit:
public class StartEndAsyncExitCall {
private void makeAsyncExitTransaction() throws Exception {
System.out.println("Starting transaction");
try (Transaction transaction = AppdynamicsAgent.startTransaction("StartEndAsyncExitCall", null, EntryTypes.POJO, true)) {
Thread.sleep(1000);
new TransactionEndingThread(transaction).start();
System.out.println("Starting exitcall");
ExitCall exitCall = null;
exitCall = transaction.startExitCall("Custom", "Custom", ExitTypes.CUSTOM, true);
new ExitCallEndingThread(exitCall).start();
}
}
public class TransactionEndingThread extends Thread {
Transaction transaction = null;
TransactionEndingThread(Transaction transaction) {
this.transaction = transaction;
}
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
transaction.end();
System.out.println("Ending transaction");
}
}
public class ExitCallEndingThread extends Thread {
ExitCall exitCall = null;
ExitCallEndingThread(ExitCall exitCall) {
this.exitCall = exitCall;
}
public void run() {
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
exitCall.end();
System.out.println("Ending exitcall");
}
}
}