AppDynamics switched from Semantic Versioning to Calendar Versioning starting in February 2020 for some agents and March 2020 for the entire product suite.


    Skip to end of metadata
    Go to start of metadata

    Manual tracer instrumentation consists of the following steps:

    1. Instantiate the Tracer
    2. Create a Transaction
    3. Start and Stop a Transaction
    4. Create External Exit Calls

    Instantiate the Java Serverless Tracer

    To instantiate the tracer, call the AppDynamics.getTracer(context) method. Place the method at the beginning of your function's entry point method.

    The code snippet demonstrates how to instantiate the tracer: 

    @Override
        public void handleRequest(InputStream input, OutputStream output, Context context) throws IOException {
     
    		//Instantiate the tracer.
      		Tracer tracer = AppDynamics.getTracer(context);
     
    		//Your AWS Lambda function code begins here.
    		int letter = 0;
            while((letter = input.read()) >= 0) {
                output.write(Character.toUpperCase(letter));
    		}
        }

    Create a Transaction

    Next, you need to create transactions. A transaction is a monitored segment in a larger business transaction. Creating a transaction involves locating the correlation header, which the tracer uses to pass contextual information downstream.  

    Transactions either:

    • Start a new business transaction, or
    • Continue an existing business transaction 

    Start a New Business Transaction 

    A transaction that originates in the current function does not have an inbound correlation header. To create a business transaction, use the createTransaction() method and provide an empty correlation header. 

    Continue an Existing Business Transaction

    To continue an existing business transaction, you need to locate an inbound correlation header. You can locate a correlation header automatically or manually. 

    If the tracer cannot find the correlation header, the tracer creates a new business transaction.

    Continue a Business Transaction by Locating the Correlation Header Automatically

    Use the createTransaction(inputStream, context) method to create a transaction that locates the correlation header automatically. This method searches your code's object schema for a key called singularityheader in the inputStream object. The correlation header finds the singularityheader key, then continues the business transaction.

    The tracer reads the inputStream object, which is configured to be read once. If your application needs to read the inputStream object, you must use a converter method to allow both the tracer and your application to read the stream. 

    The code snippet shows an example of how to create a transaction and automatically locate the correlation header:

    public class <LambdaChops> implements RequestStreamHandler {
        @Override
        public void handleRequest(InputStream input, OutputStream output, Context context) throws IOException {
      	Tracer tracer = AppDynamics.getTracer(context);
    	
    	//Use a converter method if you need to read your inputStream more than once. The tracer reads your inputStream once.
      	inputStream = InputStreamConverter.convertToMarkSupportedInputStream(input);
     
    	//Create a transaction. 
    	Transaction transaction = tracer.createTransaction(input, context);
    
    	//Your AWS Lambda function code begins here. 
            int letter = 0;
            while((letter = input.read()) >= 0) {
                output.write(Character.toUpperCase(letter));
            }
        }
    }
    Create a Transaction by Locating the Correlation Header Manually

    To create a transaction that locates the correlation header using custom logic, you need to manually parse a correlationHeader string. Next, call the createTransaction()method and provide the correlationHeader object. This process gives you full control over the parsing of your function's input payload. 

    The code snippet shows an example of how to obtain the correlation header string and create a transaction:

    public class <LambdaChops> implements RequestHandler {
        @Override
    	public O handleRequest(InputStream input, OutputStream output, Context context) {
    	Tracer tracer = AppDynamics.getTracer(context);
         
    	//Manually parse the correlation string.
         String inputAsString = IOUtils.toString(inputStream, Charset.forName("UTF-8"));
         JsonParser parser = new JsonParser();
         JsonObject inputObject = parser.parse(inputAsString).getAsJsonObject();
     
    	String correlationHeader = "";
    	if (inputObject.has(Tracer.APPDYNAMICS_TRANSACTION_CORRELATION_HEADER_KEY)) {
        	correlationHeader = inputObject.get(Tracer.APPDYNAMICS_TRANSACTION_CORRELATION_HEADER_KEY).getAsString();
    	} else {
        	// Try reading from HTTP headers
        	if (inputObject.has("headers")) {
            	JsonObject httpHeaders = inputObject.getAsJsonObject("headers");
            	if (httpHeaders.has(Tracer.APPDYNAMICS_TRANSACTION_CORRELATION_HEADER_KEY)) {
                	correlationHeader = httpHeaders.get(Tracer.APPDYNAMICS_TRANSACTION_CORRELATION_HEADER_KEY).getAsString();
            }	
        }
    }
     
    	// Create transaction object using the correlation header. If the correlationHeader string is empty, the transaction you create uses the default transaction name.
    	Transaction transaction = tracer.createTransaction(correlationHeader);
     
    	//Your AWS Lambda function code starts here
    	...
     
    }

    Start and Stop a Transaction

    After creating a transaction, you need to set transaction boundaries. Use the transaction.start() and transaction.stop() methods to place boundaries around any section of code that you want the tracer to monitor.

    As a best practice, you can report all events, even if your function crashes, by running your entire function within a try block, and then stopping the transaction within a finally block.  

    This code sample demonstrates how to start and stop a transaction that monitors an entire function:

    @Override
     public void handleRequest(InputStream input, OutputStream output, Context context) throws IOException {
      Tracer tracer = AppDynamics.getTracer(context);
      Transaction transaction = tracer.createTransaction(input, context);
     
    	//Start the transaction monitoring.
      	transaction.start();
      	try { 
       		int letter = 0;
            while((letter = input.read()) >= 0) {
                output.write(Character.toUpperCase(letter));
    		}
     
    	//Stop the transaction monitoring. Place in a finally block to monitor all events. 
    	} finally {
       		transaction.stop();
    		AppDynamics.cleanup();
      	}  
     }

    Create External Exit Calls

    The createExitCall method is used to obtain an exitCall object. Exit call objects record the time spent in external exit calls and allow for correlation of downstream activity. 

    Exit Call Types and Identifying Properties

    In the Controller, each exit call has a distinct type, determined by a set of identifying properties. 

    The exitCall types and identifying properties are listed below: 

    exitCall Type
    Identifying Properties
    HTTP

    HOST

    PORT

    URL

    QUERY STRING

    JDBC

    URL

    HOST

    PORT

    DATABASE

    VERSION

    VENDOR

    WEB SERVICE

    SERVICE

    URL

    OPERATION

    SOAP ACTION

    VENDOR

    CUSTOMAny user-defined set of properties


    Create an External Exit Call 

    Call createExitCall() on your transaction object. 

    The following code sample demonstrates how you might perform an external exit call:

    public void makeExitCall(URL url){
     
    HttpURLConnection conn = (HttpURLConnection)url.openConnection();
     
    String outgoingHeader = null;
    String callType = null;
    Map<String, String> identifyingProperties = new HashMap<>();
        
    //Below properties are appropriate for an inter-AWS Lambda call
    identifyingProperties.put("DESTINATION", functionName);
    identifyingProperties.put("DESTINATION_TYPE", "LAMBDA");
    callType="CUSTOM";
        
    //Below properties are appropriate for an external HTTP call
    identifyingProperties.put("HOST", url.getHost());     
    identifyingProperties.put("PORT", String.valueOf(url.getPort()));
    callType="HTTP";
     
    //Define the createExitCall method to obtain an exitCall object.     
    ExitCall exitCall = transaction.createExitCall(callType, identifyingProperties);
    outgoingHeader =  exitCall.getCorrelationHeader();
    exitCall.start();
        
    try {
    // Tracer.APPDYNAMICS_TRANSACTION_CORRELATION_HEADER_KEY is the name of the header that should be set
       
        if (outgoingHeader != null) {
            conn.setRequestProperty(Tracer.APPDYNAMICS_TRANSACTION_CORRELATION_HEADER_KEY, outgoingHeader); // set the correlation header on an HttpURLConnection
        }
      
    // Make the exit call here
      
    } finally {
            exitCall.stop();
        }
    }

    Create Multiple External Exit Calls

    If one AWS Lambda function makes multiple exit calls, each function should be identified by a unique exitCall object. To make multiple exit calls, create new exitCall objects for each distinct exit call. The exitCall objects are not reusable. 


    Amazon Web Services, the AWS logo, AWS, and any other AWS Marks used in these materials are trademarks of Amazon.com, Inc. or its affiliates in the United States and/or other countries.

    • No labels