Thundra

Thundra: Serverless Observability for AWS Lambda

The black box nature of AWS Lambda and other serverless environments means that identifying and fixing performance issues is difficult and time-consuming. Built for straightforward debugging, monitoring, and observability, Thundra provides deep insight into your entire serverless environment. Thundra collects and correlates all your metrics, logs, and traces, allowing you to quickly identify problematic invocations and also analyzes external services associated with that function. With Thundra’s zero overhead and automated instrumentation capabilities, your developers are free to write code without worrying about bulking up their Lambdas or wasting time on chasing black box problems.

Get Started    Discussions

Trace Support

Traces provide end-to-end visibility throughout an entire chain of requests. Traces can be used for identifying which parts of the system have performance bottlenecks, detecting which components of the system lead to errors, and debugging the whole request flow for domain-level bugs.

Moreover, Trace support in the Node.js agent can be used by both Automated and Manual instrumentation, as mentioned in Instrumentation.

Using Trace with Manual Instrumentation

In your Lambda Handler code, add instrumentation to the operations to be tracked. You can do that primarily by placing "spans" around operations of interest and adding log statements to capture useful data relevant to those operations. Below is a simple hello-world example:

Distributed Tracing not Supported

Inject and extract methods are not implemented in the current version and will be available once fully distributed support is implemented in Thundra Agent.

Thundra Specific Methods

Apart from being Open Tracing compatible, Thundra's Node.js agent also provides specific methods at your disposal to allow easier configuration of Trace Support.

getActiveSpan/finishSpan

Thundra Tracer provides additional methods beyond what is found in the OpenTracing spec.

Obtain the active span via the getActiveSpan method and finish the active span
via finishSpan method.

const tracer = thundra.tracer();

const parent = tracer.startSpan('parent');
const child = tracer.startSpan('child', {childOf: parent});

const span = tracer.getActiveSpan(); //return child span as current active span

tracer.finishSpan(); // closes children and active span is parent
tracer.finishSpan(); // closes parent and active span is null

Callback Wrapper

The Thundra tracer provides a wrapper that will wrap your asynchronous callback. The wrapper returns a closure that saves the current active span at the time of callback creation and uses the saved active span as a parent span when the callback is called. In the example below, the Thundra tracer’s wrapper method wraps a callback function with a try/catch statement. It starts a span with the name callback at the beginning and closes the span before returning or in the case of an error.

const tracer = thundra.tracer();

const callback = function() {
  console.log('callback called');
};

const parentSpan = tracer.startSpan('parent');

// Callback is wrapped with span whose parent will be parentSpan which is the current active span 
const wrappedCallback = tracer.wrapper('callback', callback); 

const doStuff = function(stuff, callback) {
  const doStuffSpan = tracer.startSpan(‘doStuff’);
  console.log(`Starting doing my ${stuff}`);
  callback();
  doStuffSpan.finish();
}

doStuff('yoga', wrappedCallback);

parentSpan.finish(); 

// Span tree right now :
//         parentSpan
//            /  \
//      callback doStuff


// Span tree without wrapper would be:
//         parentSpan
//            /  
//      doStuff
//         /
//     callback

Using Trace with Automated Instrumentation

Automated instrumentation allows you to gain Trace Support without specifying each function to monitor as seen in Using Trace with Manual Instrumentation after configuring your Lambda functions with automated instrumentation as shown in the Instrumentation guides, there are various features that you can use, as below:

  • Trace Arguments
  • Trace Return Values
  • Trace Errors
  • Disable Request/Response Tracing of AWS Lambda
  • Integration with other libraries. Thundra NodeJS agent provides out-of-the-box instrumentation for many popular frameworks and libraries by using a integrations system. By default, all built-in integrations are enabled. Integrations can be disabled with simple configuration via declarative, programmatic API or environment variables. Here is the list of integration names and supported versions :

Declarative Configuration(JSON Notation)

For declarative configuration of the Thundra Node.js agent integrations, you need to define TraceConfig object in JSON notation by yourself. Below example enables http and pg integrations.

const config = {
	apiKey:<Your API Key>,
	traceConfig : {
		integrations:[{name:'http', opt: {enabled: false}},
      						{name:'pg', opt: {enabled: false}}],
	},
}

const thundra = require("@thundra/core");

exports.handler = thundra(config)((event, context, callback) => {
		// Your http and pg calls here
  
    callback(null, {msg : 'hello world'});    
});

Programmatic Configuration

For programmatic configuration of the Thundra’s Node.js agent integrations, just create a TraceConfig object and configure the desired aspects. Below example enables http and pg integrations.

const thundra = require('@thundra/core');
const ThundraConfig = thundra.config.ThundraConfig;
const TraceConfig = thundra.config.TraceConfig;

const config = new ThundraConfig();
const traceConfig = new TraceConfig();
traceConfig.integrations = [{name:'http', opt: {enabled: false}},
      										 {name:'pg', opt: {enabled: false}}];

config.traceConfig = traceConfig;

exports.handler = thundra(config)((event, context, callback) => {
  	// Your http and pg calls here
  	
    callback(null, {msg : 'hello world'});    
});

Environment Variable

You can disable your integrations via lambda environment variable. You just need to set thundra_agent_lambda_trace_instrument_integrations_disable with a list of integrations you want to disable. Below example shows, how to disable http and pg integrations.