Python Serverless Tracer

This page provides requirements and an overview of the instrumentation process for Python functions during development. The preferred method is to use the Splunk AppDynamics AWS1 Lambda Extension. See Use the Splunk AppDynamics AWS Lambda Extension to Instrument Serverless APM at Runtime.

Note: This document contains links to Amazon Web Services (AWS) documentation. Splunk AppDynamics makes no representation as to the accuracy of Amazon documentation because Amazon controls its own documentation.

Before You Begin

Ensure that your setup meets the following requirements:

  • Existing AWS Lambda functions implemented in .Python 3.9 to 3.13
  • Python Package Installer (the pip version must match the Python version of your AWS Lambda function)
  • Splunk AppDynamics SaaS Controller >= 4.5.16

Install the Python Serverless Tracer

Note: The Python Serverless Tracer is available for the Python Agent supported versions. The version of the tracer you obtain from PyPi needs to match the version of Python you use to run your function code in AWS.

The Python Serverless Tracer is available for download in PyPi repository. You can install the Python Serverless Tracer locally or package it with your AWS Lambda function code.

Install Locally

Run a pip install command to install the tracer in your local environment:

CODE
pip install appdynamics-lambda-tracer

If you install the tracer locally, you need to package the tracer with your AWS Lambda function at runtime.

Package with AWS Lambda Functions

Run the following command to include the tracer in your function's package:

CODE
pip install --target ./package/ appdynamics-lambda-tracer

See AWS documentation to learn more about packaging dependencies in your functions.

Instrument Your Function Code

To instrument your AWS Lambda function, add these lines of code:

PYTHON
import appdynamics # Add Splunk AppDynamics libraries. Must be the first line of code
@appdynamics.tracer # Must come before the handler function
def my_handler(event, context):
print("Hello world!")

Exit Call Instrumentation

By default, the Python Serverless Tracer automatically discovers HTTP, Amazon DynamoDB, and inter-AWS Lambda exit calls. Use the Python Tracer API to create an exit call if you want visibility into other types of external calls made by your function. See Python Serverless Tracer API.

Note: This document contains links to AWS documentation. Splunk AppDynamics makes no representation as to the accuracy of Amazon documentation because Amazon controls its own documentation.

Python Serverless Tracer API

This page describes how to use the Python Serverless Tracer API to modify the behavior of the tracer within your AWS Lambda function.

Custom Exit Calls

You can use the start_exit_call() and end_exit_call() methods to create a custom exit call from a specific business transaction to a backend that the Python Agent does not automatically detect.

The business transaction must be a custom business transaction.
Tip: If you want to make a custom exit call from a business transaction that is normally automatically detected, you can exclude that business transaction to prevent it from being automatically detected and then create it as a custom business transaction. This enables you to get the BtHandle that you need to create the custom exit call. See Configure Python Web Custom Match and Exclude Rules for information on excluding a business transaction.
Given the code:
CODE
try:
    db = custom_db.connect(host='financials-lb', port=3456)
    all_employees = db.query_path('/financials/employees')
    individual_contributors = all_employees.filter(lambda r: r.level < 3)
    salaries_by_dept = individual_contributors.sum(value='salary', group='dept', as='total')

    for dept, total in salaries_by_dept.extract('dept', 'total'):
        report_salary_data(dept, total)

You want to send the query via an exit call to a proprietary database.

You want the database to be labeled Financials Database in the Controller UI.

You want the backend properties that appear in the backend dashboard to appear as:

Host
financials-lb
Port
3456
Vendor
custom db

The following examples assume you are wrapping the exit call in a custom business transaction named department rollup, created in another part of your code.

Use start_exit_call() and end_exit_call()

This example uses start_exit_call() and end_exit_call().
PYTHON
from appdynamics.agent import api as appd
appd.init()

# Set the identifying properties
FINANCIALS_ID_PROPS = {'Host': 'financials-lb', 'Port': 3456, 'Vendor': 'custom db'}

with appd.bt('department rollup') as bt_handle:
    # Start the exit call
    exit_call = appd.start_exit_call(bt_handle, appd.EXIT_DB, 'Financials Database', FINANCIALS_ID_PROPS)
    exc = None

    try:
        db = custom_db.connect(host='financials-lb', port=3456)
        all_employees = db.query_path('/financials/employees')
        individual_contributors = all_employees.filter(lambda r: r.level < 3)
        salaries_by_dept = individual_contributors.sum(value='salary', group='dept', as='total')

        for dept, total in salaries_by_dept.extract('dept', 'total'):
            report_salary_data(dept, total)
    except Exception as exc:
        raise  # Assuming something above handles exceptions for you
    finally:
        #End the exit call
        end_exit_call(exit_call, exc)

Use exit_call context manager

If the business transaction starts and ends in the same context, you can use the simpler exit_call context manager instead.
PYTHON
from appdynamics.agent import api as appd
appd.init()

with appd.bt('department rollup') as bt_handle:
    with appd.exit_call(bt_handle, appd.EXIT_DB, 'Financials Database', FINANCIALS_ID_PROPS):
        db = custom_db.connect(host='financials-lb', port=3456)
        all_employees = db.query_path('/financials/employees')
        individual_contributors = all_employees.filter(lambda r: r.level < 3)
        salaries_by_dept = individual_contributors.sum(value='salary', group='dept', as='total')

        for dept, total in salaries_by_dept.extract('dept', 'total'):
            report_salary_data(dept, total)

The next example starts a custom exit call to a Cassandra backend from a business transaction that was auto-detected by the Python Agent default Flask instrumentation. It uses the Flask import feature to get the request object which it passes to appd_get_active_bt_handle().

Get bt handle using the flask request context:
PYTHON
from flask import request
from appdynamics.agent import api as appd

@app.route('/metrics/recent')
def metrics_recent():
    bt = appd.get_active_bt_handle(request)  # Get the active BT from the Flask request object
    with appd.exit_call(bt, appd.EXIT_DB, 'cassandra time-series', {'VENDOR': 'Cassandra', 'SERVER POOL': '10.0.0.1'}):
        load_recent_data_from_cassandra()

Other supported frameworks have different mechanisms for getting the request object.

Create Exit Call Error Reports

The ExitCallContextManager method automatically reports errors. If you want to add custom error reports, use the report_exit_call_error method. The method takes the following parameters:

  • error_name: Name of the error
  • error_message (Optional): Descriptive error message
  • http_status_code (Optional): The HTTP status code if available.

The code sample below demonstrates how you can use the exit call error report method:

PYTHON
import appdynamics
@appdynamics.tracer
def handler(event, context):
#Create an exit call
with appdynamics.ExitCallContextManager("DB", "DB", {"HOST": "ec2-12-123-123-12.us-west-2.compute.amazonaws.com", "PORT": "3306", "DATABASE": "movies", "VENDOR": "MYSQL"}) as ec:
movies = fetch_movies_from_mysql_db()
if movies == None:
#Create an exit call error report
ec.report_exit_call_error(error_name="DBError", error_message="Item not found") #ec is the object returned by ExitCallContextManager above

Create Transaction Error Reports

By default, the Python Tracer automatically detects transaction error reports. You can customize these error reports using the appdynamics.report_error(error_name: str, error_message: str) method to report transaction errors. The method takes the following parameters:

  • error_name: Name of the error

  • error_message (Optional): Descriptive error message

The code sample below demonstrates how you can use the transaction error report method:

PYTHON
import appdynamics # Add AppDynamics libraries. Must be the first line of code
import requests #Add request library
@appdynamics.tracer # Must come before the handler function
def my_handler(event, context):
try:
r = requests.get('https://api.github.com/events')
except Exception as e:
appdynamics.report_error(error_name=type(e).__name__, error_message=str(e)) # Reports a transaction error

Integrate the Python Tracer with End User Monitoring

Serverless APM for AWS Lambda is designed to integrate with your existing End User Monitoring (EUM) configurations. EUM integration provides complete end-to-end visibility on the performance of your web and mobile applications, linking calls from an end-user device through your serverless functions to continue your business transactions

AWS Lambda functions can correlate EUM and AWS Lambda-originated business transactions, in conjunction with the following EUM agents:

Note: This document assumes you are familiar with Splunk AppDynamicsEnd User Monitoring. See

End User Monitoring

.
1 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.