Package: signalfx-lambda
OverviewYou can use this document to add a SignalFx wrapper to your AWS Lambda for Python.The SignalFx Python Lambda Wrapper wraps around an AWS Lambda Python function handler, which allows metrics and traces to be sent to SignalFx.At a high-level, to add a SignalFx Python Lambda wrapper, you can package the code yourself, or you can use a Lambda layer containing the wrapper and then attach the layer to a Lambda function.To learn more about Lambda Layers, please visit the AWS documentation site and see [AWS Lambda Layers](https://docs.aws.amazon.com/lambda/latest/dg/configuration-layers.html).Step 1: Add the Lambda wrapper in AWSTo add the SignalFx wrapper, you have the following options:Option 1: In AWS, create a Lambda function, then attach a SignalFx-hosted layer with a wrapper.If you are already using Lambda layers, then SignalFx recommends that you follow this option.In this option, you will use a Lambda layer created and hosted by SignalFx.Option 2: In AWS, create a Lambda function, then create and attach a layer based on a SignalFx SAM (Serverless Application Model) template.If you are already using Lambda layers, then SignalFx also recommends that you follow this option.In this option, you will choose a SignalFx template, and then deploy a copy of the layer.Option 3: Use the wrapper as a regular dependency, and then create a Lambda function based on your artifact containing both code and dependencies.Option 1: Create a Lambda function, then attach the SignalFx-hosted Lambda layerIn this option, you will use a Lambda layer created and hosted by SignalFx.To verify compatibility, review the list of supported regions. See [Lambda Layer Versions](https://github.com/signalfx/lambda-layer-versions/blob/master/python/PYTHON.md).Open your AWS console.In the landing page, underCompute, clickLambda.ClickCreate functionto create a layer with SignalFx’s capabilities.ClickAuthor from scratch.InFunction name, enter a descriptive name for the wrapper.InRuntime, select the desired language.ClickCreate function.Click onLayers, then add a layer.MarkProvide a layer version.Enter an ARN number.To locate the ARN number, see [Lambda Layer Versions](https://github.com/signalfx/lambda-layer-versions/blob/master/python/PYTHON.md).Option 2: Create a Lambda function, then create and attach a layer based on a SignalFx templateIn this option, you will choose a SignalFx template, and then deploy a copy of the layer.Open your AWS console.In the landing page, underCompute, clickLambda.ClickCreate functionto create a layer with SignalFx’s capabilities.ClickBrowse serverless app repository.ClickPublic applications.In the search field, enter and selectsignalfx-lambda-python-wrapper.Review the template, permissions, licenses, and then clickDeploy.A copy of the layer will now be deployed into your account.Return to the previous screen to add a layer to the function, select from list of runtime compatible layers, and then select the name of the copy.Option 3: Install the wrapper package with pipRun the following installation script in your command line:pip install signalfx_lambdaStep 2: Locate and set the ingest endpointBy default, this function wrapper will send data to the us0 realm. As a result, if you are not in us0 realm and you want to use the ingest endpoint directly, then you must explicitly set your realm. To set your realm, use a subdomain, such as ingest.us1.signalfx.com or ingest.eu0.signalfx.com.To locate your realm:Open SignalFx and in the top, right corner, click your profile icon.ClickMy Profile.Next toOrganizations, review the listed realm.Step 3: Set environment variablesSet SIGNALFX_ACCESS_TOKEN with your correct access token. Review the following example.SIGNALFX_ACCESS_TOKEN=accesstokenIf you use Smart Gateway, or want to ingest directly from a realm other than us0, then you must set at least one endpoint variable. (For environment variables, SignalFx defaults to the us0 realm. As a result, if you are not in the us0 realm, you may need to set your environment variables.) There are two options:Option 1SetSIGNALFX_TRACING_URLandSIGNALFX_METRICS_URLto configure where traces and metrics will be sent to. The following example will send traces to the gateway and metrics directly to the ingest endpoint.SIGNALFX_METRICS_URL=https://ingest.us0.signalfx.comSIGNALFX_TRACING_URL=http://<my_gateway>:8080/v1/traceTo learn more, see:[Deploying the SignalFx Smart Gateway](https://docs.signalfx.com/en/latest/apm/apm-deployment/smart-gateway.html)(Optional) Set additional environment variables. Review the following examples.SIGNALFX_SEND_TIMEOUT=timeoutinsecondsforsendingdatapoint[default:0.3]SIGNALFX_TRACING_URL=tracingendpoint[default:https://ingest.signalfx.com/v1/trace]Step 4: Wrap a functionThere are two wrappers provided.The decorators can be used individually or together.For metrics, decorate your handler with@signalfx_lambda.emits_metrics. Review the following example.importsignalfx_lambda@signalfx_lambda.emits_metrics()defhandler(event,context):# your codeFor tracing, decorate your handler with@signalfx_lambda.is_traced. Review the following example.importsignalfx_lambda@signalfx_lambda.is_traced()defhandler(event,context):# your codeOptionally, you can tell the wrapper to not auto-create a span but still initialize tracing for manual usage.This is useful when processing SQS messages and you want each message to tie to the trace from producer that emitted the message.importsignalfx_lambda@signalfx_lambda.is_traced(with_span=False)defhandler(event,context):forrecordinevent.get('Records',[]):withsignalfx_lambda.tracing.create_span(record,context):# your code to process recordStep 5: Send custom metrics from a Lambda functionTo send custom metrics from a Lambda function, include the following code in your function:importsignalfx_lambda# sending application_performance metric with value 100 and dimension abc:defsignalfx_lambda.send_gauge('application_performance',100,{'abc':'def'})# sending counter metric with no dimensionsignalfx_lambda.send_counter('database_calls',1)Step 6: Add tracing to the Lambda functionTo trace critical parts of your handler function, include the following code in your function:importopentracing@signalfx_lambda.is_traced()defsome_function():# opentracing.tracer must be referenced from within# a function decorated with the is_traced() decorator# or it'll not reference the correct tracer initialized# for the lambda function.tracer=opentracing.tracerwithtracer.start_active_span("span_name",tags=tags)asscope:# do some workspan=scope.spanspan.set_tag("example_tag","example_value")To review more examples and usage details, see [Jaeger Python Tracer](https://github.com/signalfx/jaeger-client-python>).Propagating trace context to outgoing requests or lambda responseThe library ships a helper function to inject tracing context headers into a dictionary like object.
The function accepts two arguments. First argument must be a dictionary like object that the trace context is injected into.
The second argument is optional and must be a OpenTracing span context. If one is not provided, the function uses the currently
active span. Example:importsignalfx_lambda@signalfx_lambda.is_traced()defhandler(event,context):headers={}# inject trace context into the headers dictionarysignalfx_lambda.tracing.inject(headers)# Or inject traces from a specific span context instead of the# one from the active scope.# signalfx_lambda.tracing.inject(headers, span.context)request=urllib.request.Request('http://some-service',headers=headers)response=urllib.request.urlopen(request)# your codeAdditional informationMetrics and dimensions sent by the metrics wrapperThe Lambda wrapper sends the following metrics to SignalFx:Metric NameTypeDescriptionfunction.invocationsCounterCount number of
Lambda invocationsfunction.cold_startsCounterCount number of cold
startsfunction.errorsCounterCount number of
errors from
underlying Lambda
handlerfunction.durationGaugeMilliseconds in
execution time of
underlying Lambda
handlerThe Lambda wrapper adds the following dimensions to all data points sent
to SignalFx:DimensionDescriptionlambda_arnARN of the Lambda function
instanceaws_regionAWS Regionaws_account_idAWS Account IDaws_function_nameAWS Function Nameaws_function_versionAWS Function Versionaws_function_qualifierAWS Function Version Qualifier
(version or version alias if it
is not an event source mapping
Lambda invocation)event_source_mappingsAWS Function Name (if it is an
event source mapping Lambda
invocation)aws_execution_envAWS execution environment
(e.g. AWS_Lambda_python3.6)function_wrapper_versionSignalFx function wrapper
qualifier
(e.g. signalfx_lambda_0.0.2)metric_sourceThe literal value of
‘lambda_wrapper’Tags sent by the tracing wrapperThe tracing wrapper creates a span for the wrapper handler. This span contains the following tags:TagDescriptionaws_request_idAWS Request IDlambda_arnARN of the Lambda function
instanceaws_regionAWS Regionaws_account_idAWS Account IDaws_function_nameAWS Function Nameaws_function_versionAWS Function Versionaws_function_qualifierAWS Function Version Qualifier
(version or version alias if it
is not an event source mapping
Lambda invocation)event_source_mappingsAWS Function Name (if it is an
event source mapping Lambda
invocation)aws_execution_envAWS execution environment
(e.g. AWS_Lambda_python3.6)function_wrapper_versionSignalFx function wrapper
qualifier
(e.g. signalfx_lambda_0.0.2)componentThe literal value of
‘python-lambda-wrapper’Auto-instrumentation packagesThe SignalFx Python Lambda Wrapper can automatically instrument supported packages. All you need to do is to install instrumentations you need in addition tosignalfx_lambda. Below is a list of all instrumentation packages supported:Library/FrameworkInstrumentation Packageceleryhttps://github.com/signalfx/python-celery/tarball/0.0.1post0#egg=celery-opentracingdjangohttps://github.com/signalfx/python-django/tarball/0.1.18post1#egg=django-opentracingelasticsearchhttps://github.com/signalfx/python-elasticsearch/tarball/0.1.4post#egg=elasticsearch-opentracingflaskhttps://github.com/signalfx/python-flask/tarball/1.1.0post1#egg=flask_opentracingpsycopghttps://github.com/signalfx/python-dbapi/tarball/v0.0.5post1#egg=dbapi-opentracingpymongohttps://github.com/signalfx/python-pymongo/tarball/v0.0.3post1#egg=pymongo-opentracingpymysqlhttps://github.com/signalfx/python-dbapi/tarball/v0.0.5post1#egg=dbapi-opentracingredishttps://github.com/signalfx/python-redis/tarball/v1.0.0post1#egg=redis-opentracingrequestshttps://github.com/signalfx/python-requests/archive/v0.2.0post1.zip#egg=requests-opentracingtornadohttps://github.com/signalfx/python-tornado/archive/1.0.1post1.zip#egg=tornado_opentracingFor example, if your Lambda function usesrequests, then you should addhttps://github.com/signalfx/python-requests/archive/v0.2.0post1.zip#egg=requests-opentracingto yourrequirements.txtfile or make sure it gets installed into the Lambda environment.Test locallyIf you would like to test changes to a wrapper, run the following commands in your command line:pip install python-lambda-localpython-lambda-local tests/test.py tests/event.json -a 'arn:aws:lambda:us-east-1:accountId:function:functionNamePython:$LATEST'Publish a new versionIf you would like to publish a new version, run the following command in your command line to install a new Python package (build a wheel):python setup.py bdist_wheel --universalLicenseApache Software License v2. Copyright © 2014-2020 Splunk, Inc.