Not a customer? Click the 'Start a free trial' link to begin a 30-day SaaS trial of our product and to join our community.
Existing Cisco AppDynamics customers should click the 'Sign In' button to authenticate to access the community
02-26-2020 03:08 PM
Hi,
I'm working on instrumenting Java Lambda. My environment contains 2 lambdas. the first one is triggering the second one through SNS.
Also, implemented the sns exit call from the first lambda.
Now, I'm trying to correlate the business transaction to be the same as started from the first lambda and passing to the second one.
I'm using Manual Instrumentation and followed AppDynamics documentation:
https://docs.appdynamics.com/display/PRO45/Manual+Tracer+Instrumentation
This is a snippet from my code on how I'm fetching the correlation header from an input:
public Context handleRequest(InputStream input, Context context) {
if (runAppDynamics) {
//Instantiate the tracer
Tracer tracer = AppDynamics.getTracer(context);
//Automatically Parse the correlation header
InputStream inputStream = InputStreamConverter.convertToMarkSupportedInputStream(input);
try {
String inputAsString = IOUtils.toString(inputStream, Charset.forName("UTF-8"));
com.appdynamics.serverless.tracers.dependencies.com.google.gson.JsonParser parser = new JsonParser();
JsonObject inputObject = parser.parse(inputAsString).getAsJsonObject();
if (inputObject.has(Tracer.APPDYNAMICS_TRANSACTION_CORRELATION_HEADER_KEY)) {
System.out.println("corrHeader in tracer");
correlationHeader = inputObject.get(Tracer.APPDYNAMICS_TRANSACTION_CORRELATION_HEADER_KEY).getAsString();
} else {
//Try reading from HTTP headers
if (inputObject.has("headers")) {
System.out.println("corrHeader in 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();
}
}
}
}
catch (IOException e){}
if(correlationHeader == null) {
correlationHeader = "corrheadertest";
}
//Create Transaction
transaction = tracer.createTransaction(correlationHeader);
//Start the transaction monitoring.
transaction.start();
This is the Lambda Test input:
{
"key": "Content-Type",
"singularityheader": "com.appdynamics.serverless.tracers.aws.correlation.CorrelationHeader"
}
Every time I test my Lambda it didn't correlate and cloud watch logs return:
Solved! Go to Solution.
02-27-2020 05:36 AM
Catherine,
It appears that the value of the correlation header you are trying to consume on input is "com.appdynamics.serverless.tracers.aws.correlation.CorrelationHeader"
That is definitely not a valid header, where did you obtain it from?
To give you an idea of what you should be expecting to see, an example of a valid header is:
appId=4113*ctrlguid=1539290818*acctguid=e2c8a068-be66-46a4-a0d3-aeff5f18ecc9*btid=532007*guid=efbe5515-1e93-496c-9f53-47c1640069e73*ts=34869499416608*cidfrom=7500*unresolvedexitid=139411*exitguid=40*cidto={[UNRESOLVED][139411]}*etypeorder=HTTP
You should get a string of that form returned to you when you call getCorrelationHeader() on the ExitCall object you created in the upstream lambda.
Warm regards,
Peter
02-27-2020 02:28 PM
Thanks Peter for your reply.
Actually, I don't know how the correlation header should look like. I tried many entries, but in every time it returns malformed header and generate a new one like:
[AppDynamics Tracer] [DEBUG]: Correlation Header generated => com.appdynamics.serverless.tracers.aws.correlation.CorrelationHeader@3fee9989
This is why I used it same as the generated value com.appdynamics.serverless.tracers.aws.correlation.CorrelationHeader without the sequence number at the end.
Yes, I get a header chain generated after that and looks like that:
HeaderChain{root='appId=300*ctrlguid=1570069847*acctguid=a678f643-40d2-4d5d-8a32-636b904e6186*ts=1582757985080*btid=145515*guid=98faae3f-ddfb-4904-bc01-19078418956d', fromCompChain='174213', toCompChain='', exitTypeCallChain='', exitSubtypeCallChain='', snapshotEnabledSet=false, fromCompIds=[174213], threadCallChainForOutOfProcess='null'}
But, the generated correlation header is not fetched by the second Lambda. Second Lambda code:
public String handleRequest(SNSEvent event, Context context) {
String snsMsg = "Hello From Lambda To SNS";
String messasge = event.getRecords().get(0).getSNS().getMessage();
String correlationHeader="";
//Instantiate the tracer
Tracer tracer = AppDynamics.getTracer(context);
com.appdynamics.serverless.tracers.dependencies.com.google.gson.JsonParser parser = new JsonParser();
JsonObject inputObject = parser.parse(messasge).getAsJsonObject();
if (inputObject.has(Tracer.APPDYNAMICS_TRANSACTION_CORRELATION_HEADER_KEY)) {
System.out.println("corrHeader in tracer");
correlationHeader = inputObject.get(Tracer.APPDYNAMICS_TRANSACTION_CORRELATION_HEADER_KEY).getAsString();
System.out.println(correlationHeader);
} else {
//Try reading from HTTP headers
if (inputObject.has("headers")) {
System.out.println("corrHeader in 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();
System.out.println(correlationHeader);
}
}
}
//Create Transaction
Transaction transaction = tracer.createTransaction(correlationHeader);
//Start the transaction monitoring.
transaction.start();
//Lambda code
try{
context.getLogger().log("SNS Message: " + snsMsg);
context.getLogger().log(event.getRecords().get(0).getSNS().getMessage());
return null;
}
finally {
transaction.stop();
AppDynamics.cleanup();
}
}
}
Cloud watch logs that showing receiving message to this Lambda:
{
"singularityheader": "com.appdynamics.serverless.tracers.aws.correlation.CorrelationHeader",
"msg": "Hello from InitSample to SNS"
}
I'm still missing something on how to pass the generated header from the first lambda to the second one?
Thanks
03-02-2020 02:08 PM
Hi Peter,
I passed a correct formate header to the first lambda and it's succeeded to pass it to the second lambda and correlate the transaction created from the first lambda, but I found that, the first Lambda is correlating to itself.
I want the first Lambda to start the Transaction and generate the correlation header, then fetch this header and send it to the second Lambda.
Any idea how I can fetch the generated header from first Lambda? what Package in AppD I can call it to get the generated header?
Thanks
03-03-2020 04:40 AM
Catherine,
You should create an exit call object and obtain the outgoing correlation header from that, as shown in the code sample in the documentation here: https://docs.appdynamics.com/display/PRO45/.Manual+Tracer+Instrumentation+v4.5.x#id-.ManualTracerIns...
I pasted the relevant section below:
03-04-2020 09:58 PM
Great Peter, exitcall.getCorrelationHeader(), this what I was looking for.
Noe the first Lambda generates the correlation header then fetch the outgoing header and send it to each Lambda through it's exit call.
Thanks a lot for your help, I'll mark this case as solved.
Please let me know if I need to do anything else, like put ranks for you or anything else should be done when I'm closing a post. This is my first post on AppD community.
Thanks
03-05-2020 03:10 AM
Catherine,
I'm delighted that got you going.
If you have any suggestions as to how we could make this easier to find in the documentation, please let me know. From the inside, it's easy to take too much for granted. What search terms did you try to use to find this? Where would you expect to see it?
Warm, regards,
Peter
Thank you! Your submission has been received!
Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form