From c66aad7436853a13848675d4a7414f61f46a5c7f Mon Sep 17 00:00:00 2001 From: Maciej Skierkowski Date: Fri, 15 Sep 2023 10:26:58 -0700 Subject: [PATCH] docs: Update docs to reflect Dashboard v2 changes (#12155) * docs: Update content on new monitoring * docs: Add section on orgs & members * docs: Remove reference to concurrent builds * docs: Replace "Enterprise" with "Dashboard" * docs: Updates node.js SDK docs * docs: Update menu and add upgrade guide * docs: Adding docs on span() in node.js SDK * docs: Add setEndpoint, tagging API and migration * docs: Update Python SDK migration * docs: Update Python SDK * docs: Use env vars to dsiable auto spans * docs: Remove refernece to span.* Event methods * docs: Replace "end" with "close" methods * docs: Updates config notes per new SDKs * docs: Add note on wrapping * docs: Add instrumentation steps * docs: Update syntax for disabling monitoring * docs: Update syntax on disabling dashboard monitoring * docs: Running prettify --- docs/guides/cicd/faq.md | 42 +-- docs/guides/monitoring/README.md | 138 ++------ docs/guides/monitoring/instrumentation.md | 62 ++++ docs/guides/monitoring/metrics.md | 71 ++++- docs/guides/monitoring/trace-explorer.md | 113 +++++++ docs/guides/orgs.md | 46 +++ docs/guides/sdk/nodejs.md | 366 ++++++++++++++++------ docs/guides/sdk/python.md | 340 +++++++++++++++----- docs/guides/upgrade.md | 347 ++++++++++++++++++++ docs/menu.json | 8 +- 10 files changed, 1202 insertions(+), 331 deletions(-) create mode 100644 docs/guides/monitoring/instrumentation.md create mode 100644 docs/guides/monitoring/trace-explorer.md create mode 100644 docs/guides/orgs.md create mode 100644 docs/guides/upgrade.md diff --git a/docs/guides/cicd/faq.md b/docs/guides/cicd/faq.md index 62cd5574048..6e21c5f064a 100644 --- a/docs/guides/cicd/faq.md +++ b/docs/guides/cicd/faq.md @@ -15,46 +15,46 @@ layout: Doc ## Is there a free tier? -Yes, up to 1 concurrent build with the Free tier. No credit card required, just sign up. - -## How much does it cost if I need more? - -You get one free concurrent deployment with the Free tier. The Team tier includes 2 concurrent builds and you can buy -more for \$25/mo/concurrent build. +Yes. No credit card required, just sign up. Free tier only supports public +repos. Upgrade to a paid tier to use CI/CD with private repos. ## Do you support preview deployments from pull requests? -Yes! You can add preview deployments to your CI/CD Settings. This will automatically test and deploy your service from a -pull request. The results will be posted in the pull request status. You can also setup auto deletion of deployed -resources for preview deployments so that “sls remove” is automatically run when your feature branch is merged and -deleted. +Yes! You can add preview deployments to your CI/CD Settings. This will +automatically test and deploy your service from a pull request. The results will +be posted in the pull request status. You can also setup auto deletion of +deployed resources for preview deployments so that “sls remove” is automatically +run when your feature branch is merged and deleted. ## Can I deploy for multiple branches? -Yes! Add other branch deployments to configure from any branch to any stage. We see a lot of folks deploy to a staging -environment from the master branch, and to production from a production branch. +Yes! Add other branch deployments to configure from any branch to any stage. We +see a lot of folks deploy to a staging environment from the master branch, and +to production from a production branch. ## Can I use different AWS Accounts for each Stage? -Yes! You can use deployment profiles to add as many AWS Accounts as you would like, and map them to individual stages in -your application. +Yes! You can use deployment profiles to add as many AWS Accounts as you would +like, and map them to individual stages in your application. ## Is it just for Serverless Framework? -Yes! Serverless CI/CD is designed around the Serverless Framework to provide a seamless experience for developers. -Anything you can deploy with the Serverless Framework you can deploy with Serverless CI/CD. The Serverless Framework is +Yes! Serverless CI/CD is designed around the Serverless Framework to provide a +seamless experience for developers. Anything you can deploy with the Serverless +Framework you can deploy with Serverless CI/CD. The Serverless Framework is extensible with Plugins , so it works with a broad range of services. ## Are all runtimes supported? -Only the most popular runtimes, Node and Python, are currently supported. These two runtimes account for about 90% of -all serverless services. Support for other runtimes is coming soon. +Only the most popular runtimes, Node and Python, are currently supported. These +two runtimes account for about 90% of all serverless services. Support for other +runtimes is coming soon. ## Does Serverless CI/CD support AWS, Azure and GCP? -Only AWS is supported at this time; however, support for other cloud service providers is coming. +Only AWS is supported at this time; however, support for other cloud service +providers is coming. ## Do I need to host, manage, or operate any agents? -Nope! Serverless CI/CD is a 100% SaaS and managed for you. If you prefer to self-host, that is available as an option -with the Enterprise tier. +Nope! Serverless CI/CD is a 100% SaaS and managed for you. diff --git a/docs/guides/monitoring/README.md b/docs/guides/monitoring/README.md index e6ad0275fda..5a0c5b5d737 100644 --- a/docs/guides/monitoring/README.md +++ b/docs/guides/monitoring/README.md @@ -17,7 +17,7 @@ Serverless Monitoring help you monitor, develop and optimize your serverless app ## Installing -Monitoring is enabled by default when you deploy a Service using the Serverless Framework CLI. +Monitoring is enabled by default if `org` and `app` are defined in the `serverless.yml`, you just need to deploy your service once those lines are added. ## Configuration @@ -31,20 +31,15 @@ Serverless Framework, when configured to connect to the dashboard, will automati Serverless Framework will enable log collection by adding a CloudWatch Logs Subscription to send logs that match a particular pattern to our infrastructure for processing. This is used for generating metrics and alerts. -When deploying, Serverless Framework will also create an IAM role in your account that allows the Serverless Framework backend to call FilterLogEvents on the CloudWatch Log Groups that are created in the Service being deployed. This is used to display the CloudWatch logs error details views alongside the stack trace. - -If you have an existing CloudWatch Logs Subscription on your Log Group, please see the section on [pull-based log ingestion](#pull-based-log-ingestion). +When deploying, Serverless Framework will also create an IAM role in your account that allows the Serverless Framework backend access the CloudWatch Log Groups that are created in the Service being deployed. This is used to display the CloudWatch logs error details views alongside the stack trace. ## Disabling log collection -If you wish to disable log collection, set the following option: - -**serverless.yml** +If you wish to disable log collection, simply add this to `serverless.yml`. ```yaml -custom: - enterprise: - collectLambdaLogs: false +dashboard: + disableMonitoring: true ``` **AWS Spans** @@ -57,9 +52,9 @@ If you wish to disable AWS Span collection, set fhe following option: **serverless.yml** ```yaml -custom: - enterprise: - disableAwsSpans: true +provider: + environment: + SLS_DISABLE_AWS_SDK_MONITORING: true ``` **HTTP(s) Spans** @@ -72,118 +67,25 @@ If you wish to disable Http Span collection, set fhe following option: **serverless.yml** ```yaml -custom: - enterprise: - disableHttpSpans: true -``` - -## Advanced Configuration Options - -### Uploading Source Map - -The [New Error Alert](#new-error) and the [Error Metrics](#errors) can be used to view the stack trace for the occurrence of an error. Tools like Webpack and Typescript generate the packaged code and therefore may obfuscate the stack trace. The Serverless Framework Enterprise Plugin and SDK support sourcemaps to properly generate the stack trace. - -To use a sourcemap, ensure that your packaging directory includes the compiled source, original source, and the source maps. - -For example, if your directory structure is: - -``` -$ ls -l dist/* src/* --rw-r--r-- 1 dschep staff 576B Mar 21 17:21 dist/handler.js --rw-r--r-- 1 dschep staff 911B Mar 21 17:21 dist/handler.js.map --rw-r--r-- 1 dschep staff 451B Mar 22 12:13 src/handler.js -``` - -Then you should have a packaging directory that includes all the files above: - -```yaml -package: - patterns: - - src/*.js - - dist/*.js - - dist/*.js.map -``` - -### Capturing non-fatal errors - -Your lambda function may throw an exception, but your function handles it in order to respond to the requestor without throwing the error. One very common example is functions tied to HTTP endpoints. Those usually should still return JSON, even if there is an error since the API Gateway integration will fail rather than returning a meaningful error. - -For this case, we provide a `captureError` function available on either the `context` or on the module imported from `'./serverless_sdk'` in NodeJS or `serverless_sdk` in Python. This will cause the invocation to still display as an -error in the serverless dashboard while allowing you to return an error to the user. - -Here is an example of how to use it from the `context` object: - -```javascript -module.exports.hello = async (event, context) => { - try { - // do some real stuff but it throws an error, oh no! - throw new Error('aa'); - } catch (error) { - context.captureError(error); - } - return { - statusCode: 500, - body: JSON.stringify({ name: 'bob' }), - }; -}; +provider: + environment: + SLS_DISABLE_HTTP_MONITORING: true ``` -[Full NodeJS Documentation](../sdk/nodejs.md#captureerror) - -[Full Python Documentation](../sdk/python.md#capture_exception) - -### AWS SDK spans - -Serverless automatically instruments `aws-sdk` and `boto3`(`botocore` specifically) in NodeJS and -Python. Calls(service & operation. eg: S3 putItem) to the SDK are show in the invocation detail -in the dashboard. +## Custom instrumentation using the Serverless SDK -### HTTP spans +In addition to the automatic instrumentation provided by Serverless Framework Dashboard, you can also add custom instrumentation using the Serverless SDK. -Serverless also instruments your lambdas to report the spans for HTTP & HTTPS requests. In NodeJS -the `http` and `https` modules are instrumented, so any library built upon those will be captured. -In Python, the `urllib3`(thus `requests`) and `urllib2`(in Python2) and `urlib.request`(in Python3) -libraries are instrumented to capture HTTP & HTTPS requests. +You can use the Serverless SDK for a few use cases: -By default, requests to AWS are not captured because of the above AWS SDK instrumentation which -provides more insight into the request. +- Capturing handled errors +- Capturing custom spans +- Capturing error and warnings events +- Tagging traces for better searchability +- Integrating with structured logging libraries -[Configuration docs](../sdk/#advanced-span-configuration) - -### Custom function spans - -You can also instrument your own spans for services not covered by AWS SDK & HTTP span -instrumentation such as databases. - -Here's an example of how to instrument a block of code in NodeJS: - -```javascript -module.exports.handler = async (event, context) => { - await context.span('some-label', async () => { - // The execution of this function is captured as a span. - // It is automatically invoked with no arguments and awaited. - }); -}; -``` +See the SDK documentation for Node and Python for details. [Full NodeJS Documentation](../sdk/nodejs.md#span) [Full Python Documentation](../sdk/python.md#span) - -### Pull-based log ingestion - -The default monitoring path for the Serverless Framework involves setting up a Subscription Filter on your CloudWatch Log Group to send selected logs to the Serverless Framework ingestion system. - -AWS currently has a hard limit of one Subscription Filter per Log Group. If you try to deploy with the Serverless Framework plugin, you'll get an error saying the resource limit was exceeded. - -If you want to keep your existing Subscription while still adding Serverless Framework support, you can enable pull-based log ingestion using the following syntax in your `serverless.yml`: - -```yaml -custom: - enterprise: - logIngestMode: pull -``` - -With pull-based ingestion, the Serverless Framework infrastructure will periodically request logs from your CloudWatch Log Group and send them into our system. - -Please note that using the pull-based log ingestion method will result in delays in ingesting your logs. This delay is usually between 30 and 120 seconds. As such, we recommend only using the pull-based log ingestion method in a development environment or when testing the features of Serverless Framework. diff --git a/docs/guides/monitoring/instrumentation.md b/docs/guides/monitoring/instrumentation.md new file mode 100644 index 00000000000..8f6fb2d0d2e --- /dev/null +++ b/docs/guides/monitoring/instrumentation.md @@ -0,0 +1,62 @@ + + + + +### [Read this on the main serverless docs site](https://www.serverless.com/framework/docs/guides/monitoring/instrumentation/) + + + +# Instrumentation + +Once you have added the AWS Account Integration, you will need to enable +instrumentation on each AWS Lambda function to enable metric, log, trace, span, +and events collection in Serverless Framework Dashboard. + +Currently Instrumentation is supported for the Node.js 12+ and Python 3.8+ +runtimes only; however, other runtime support is coming soon. + +## Enabling instrumentation for a function + +To enable instrumentation go to **Settings** > **Integrations** and select the +AWS Integration, and click **Edit**. + +On the integration settings page you'll have the option to set the +**Instrumentation** to **On**. + +When instrumentation is enabled, then metrics, logs, traces, spans, and events +are collected and made available on Metrics and Explorer in Serverless Framework +Dashboard. Instrumentation is optimized for production use, as it adds virtually +no latency to the Lambda function, and Trace Sampling limits the number of +ingested traces. + +## Trace Sampling + +To help you reduce costs, Serverless Framework Dashboard provides Trace Sampling +to limit the number of ingested traces. + +No further action is needed to enable sampling. + +Trace sampling is applied progressively in proportion to invocation load. At +low volumes the sample rate will be 0%, meaning 100% of invocations will +generate traces, while at high volumes only 20% of successful invocations will +be generate traces. + +If a trace contains any error or warning events, including any warnings +generated by the SDK (e.g. invalid tag key on `setTag()`), then the Trace will +not be sampled. This ensures that all errors and warnings will be available in +the Trace Explorer. + +Metrics are not subject to Sampling. All metrics generated and collected by the +Instrumentation will continue to work, even if the trace was successful. + +## Custom Instrumentation + +In addition to the automatic instrumentation of your AWS Lambda functions, you +can also add custom instrumentation for setting tags, and events in your code. + +Use the [Node.js](./nodejs-sdk.md) and [Python](./python-sdk.md) Serverless SDK +to add custom instrumentation. diff --git a/docs/guides/monitoring/metrics.md b/docs/guides/monitoring/metrics.md index 7c45bc9e382..91d6f6d3f5d 100644 --- a/docs/guides/monitoring/metrics.md +++ b/docs/guides/monitoring/metrics.md @@ -12,12 +12,73 @@ layout: Doc # Metrics -As part of the Serverless Insights feature we also include a set of pre-configured metrics and charts, including the following: +Metrics is a Serverless Dashboard feature which enables viewing metrics across +AWS Accounts and Lambda functions. -## Errors and Invocations +To get started you need to [add an AWS Account integration](./integrations/aws.md) +and [enable Dev or Prod Instrumentation Mode](./instrumentation.md). -The errors and invocations chart shows error count trends and the aggregate number of invocations for a particular service for a selected time period. Click into any bar on the chart to see function specific metrics. +Once instrumentation is enabled, go to the **Metrics** page to view all of your +AWS Lambda function metrics including durations, invocations, and event counts. -## Durations +Currently Metrics are supported on the Node.js 12+ and Python 3.8+ runtimes on +AWS Lambda only. Support for other runtimes is coming soon. -The durations chart shows the aggregate duration times for all functions in a particular Service for a selected time period. Click into any point on the chart to see function specific metrics. +## Metric Aggregation + +Metrics are automatically aggregated on the charts over an interval as small as +1 minute, and as large as 1 day, depending on the time interval you select. As +such, the metrics are only available in aggregate, not as individual data +points. + +## Available Charts + +The metrics page features a number of charts, including Invocations, Uncaught +Errors, and more. The title of each chart provides a tooltip with a detailed +description of the metric. + +You can also hover over individual bars to get a detailed breakdown of the +metrics for that point in time. + +Majority of the charts are interactive. You can click on the chart, which will +send you to the Trace Explorer to view the full chart and individual traces +which meat the same filter criteria. + +## Saving Views + +From the title, you can select to create a new custom view of the Metrics. All +the filters will be saved with that view. This enables you to create views for +specific use cases. When filters are updated, they are saved in the view. + +## Filters + +Applying filters to the metrics view allows you to narrow in on +specific functions, or use cases that are of interest to you. Filters can be +saved as a shared views to collaborate with team mates on specific searches. + +- **Resources** - Filter for specific AWS Resources in any of the integrated + AWS Accounts. Currently this only supports AWS Lambda, but other AWS resources + will be made available soon. +- **Namespace** - Namespaces are configured on individual AWS Lambda functions + on the AWS Integrations page. Filtering by namespace allows you to filter the + metrics based on the namespaces that were configured on the functions for which + the metric applies. +- **Environment** - Like namespaces, environments are configured on the AWS + Integration page for each AWS Lambda function. The are also automatically + determined from the CloudFormation stack if applicable. Filtering by environment + allows you to filter the metrics based on the environments that were configured + on the functions for which the metric applies. +- **Region** - Region is the specific AWS Region of the Lambda function. +- **AWS Account** - If you have multiple AWS Account integrations in your + org, you can filter for metrics for individual AWS Accounts. +- **Events** - Individual invocations may produce multiple errors or warnings. + The Serverless SDK may also produce errors and warnings. Filtering by Events + enables filtering for invocations which include any of the selected Event types. + You can find more details about Event types on the [Trace Explorer](./trace-explorer.md). +- **Cold start** - Filters for metrics on AWS Lambda invocations that were a + cold start. +- **Duration** - Filters based on the AWS Lambda response duration. +- **Custom Tags** - Filters for metrics on invocations that had the provided + custom tags. Custom tags on traces, errors, and warnings are all queried. Use + the [Node.js](../nodejs-sdk.md) or [Python](./python-sdk.md) Serverless SDK to + set custom tags. diff --git a/docs/guides/monitoring/trace-explorer.md b/docs/guides/monitoring/trace-explorer.md new file mode 100644 index 00000000000..eebed25f36a --- /dev/null +++ b/docs/guides/monitoring/trace-explorer.md @@ -0,0 +1,113 @@ + + + + +### [Read this on the main serverless docs site](https://www.serverless.com/framework/docs/guides/monitoring/trace-explorer/) + + + +# Trace Explorer + +Traces, Spans, Logs, and Events are captured and made available in Trace +Explorer for your AWS Lambda functions when [Instrumentation](./instrumentation.md) +is enabled. + +Serverless Dashboard provides a set of tools to analyzing Traces. + +## Trace Explorer List + +Similar to the [Metrics View](./metrics.md), the Trace Explorer provides a +starting point for troubleshooting AWS Lambda function invocations across your +org. You can use the rich filters to narrow in on errors, warnings, and +performance issues across all of your AWS Lambda functions across your org. + +## Filters + +Filtering allows you to narrow in on particular behavior and time frame for +to isolate invocations. You can filter on: + +- **Event Types** - Errors and Warnings can be captured in the trace, these + includes user defined as well as SDK defined errors and warnings. More details + on each Event type is available below. +- **Event Messages** - When an Event like an error or warning is captured, a + message string is saved with the Event. You can filter for the Traces based on + the Event messages that were captured in the trace. Traces are filtered if any + of the Events in the Trace contained the message string. +- **Resource** - You can select the specific resource by AWS ARN, like a + specific Lambda function. +- **Environment**, **Namespace** - These properties are inferred from the + CloudFormation stack when Instrumentation is added, or they are set manually + on the Integration settings page. Once set, you can filter the traces based on + these properties set on the function. +- **AWS Account**, **Region** - Serverless Dashboard collects information for all + instrumented Lambda functions across AWS accounts and regions; you can filter + on any of these properties. +- **Timeframe** - Any timeframe within the last 30 days can be used. + +## Event Types + +- **Uncaught Error** (`ERROR_TYPE_UNCAUGHT`) - The Lambda function handler had a + fatal error and caused the invocation to fail. +- **Caught Error** (`ERROR_TYPE_CAUGHT_USER`) - The Lambda function handler had + an error that was captured using the SDK, structured logging library (e.g. Pino, + AWS Lambda PowerTools, Winston), or standard out (e.g. `console.error`). +- **Warning** (`WARNING_TYPE_USER`) - The Lambda function handler had a warning + that was captured using the SDK, structured logging library (e.g. Pino, AWS + Lambda PowerTools, Winston), or standard out (e.g. `console.warn`). +- **SDK Error** (`ERROR_TYPE_CAUGHT_SDK_USER`) - An SDK usage error that was + reported due to misuse of the SDK. These errors do not cause handler failures, + but misusage of the SDK may result in partial collection. For example, using the + `setTag` method with invalid inputs will result in this type of error, and the + tag will not be set. +- **SDK Warning** (`WARNING_TYPE_SDK_USER`) - A warning reported by the SDK due + to user misuse in the handler, but not due to misuse of the SDK. For example, if + both a callback and Promise resolution is attached this will cause unwanted + side-effects on the SDK. + +## Trace Details + +Trace Details provides a way to look at the details of an individual AWS Lambda +Invocation trace, including the spans, tags, logs, and events. + +The Trace details are deep-linked so you can easily share the URL with your +team when collaboratively troubleshooting. + +The pane on the right, the Inspector, presents the details about the Trace. If +a Span, or an Events are selected from the timeline, then the Inspector will +show details about the selected item. + +The Inspector for the trace will present details about the trace as tags. These +tags include information about the runtime, like `Cold Start`, `Request ID`, +and `Arch`, as well as metrics like `Memory Used`, `Billed ms`, `Invoke`. Check +out the tooltips for details on each of the tags. + +### Spans + +A Trace contains a set of Spans associated with and displayed in the style of a +Gantt chart. This chart provides you with context for when, and how long various +subsequent interactions took. + +A span can be selected from the timeline to view the details of the span in the +Inspector. + +### Logs + +Logs are also collected and made available in the Trace details. To view the +logs for the Lambda invocation, select the root span, `aws.lambda`. + +If the logs are structured and formatted as JSON, they will be parsed and +displayed with pretty formatting. + +### Events + +Events, like Spans, are displayed on the timeline. Events can be selected to +view the details. + +Events include a `name`, `message`, and `stack` when available. The Node.js and +Python Serverless SDKs capture the stacktraces for all requests when possible. +It also captures `Error` objects, so the `name`, `message`, and `stack` from the +`Error` are made available as an error in the Inspector. diff --git a/docs/guides/orgs.md b/docs/guides/orgs.md new file mode 100644 index 00000000000..e2c6e2330be --- /dev/null +++ b/docs/guides/orgs.md @@ -0,0 +1,46 @@ + + + + +### [Read this on the main serverless docs site](https://www.serverless.com/framework/docs/guides/orgs/) + + + +# Orgs & Members + +## Creating an Org + +An org is a unique tenant within Serverless Framework Dashboard. When you sign +up, Serverless Framework Dashboard generates a default org name which you can +change. You can create any number of orgs. Members can be added to an org, and a +member can belong to multiple orgs. + +## Adding Team Members + +Serverless Framework Dashboard currently supports the following basic roles +which are shared across your org. + +- **Owner** - Owner of the account. Can add other contributors and access the + Org Settings. Only one owner per account can be present. +- **Contributor** - Contributors can use all of Serverless Framework Dashboard + but can not add other users or access the Org Settings directly. + +## Changing Org Name + +Org names can be changed from the Org Settings section of Serverless Framework +Dashboard. Keep in mind that org names do need to be globally unique across +Serverless, so your desired organization name may not be available. + +## Using Serverless Dashboard Orgs + +If you have an existing Serverless Framework Dashboard org and you log into +Serverless Framework Dashboard you will automatically start using your existing +org. Additionally if you are a member of a Serverless Framework Dashboard org +you will automatically be made a member of that org in Serverless Framework +Dashboard. diff --git a/docs/guides/sdk/nodejs.md b/docs/guides/sdk/nodejs.md index 3996fe996a0..177489af8a0 100644 --- a/docs/guides/sdk/nodejs.md +++ b/docs/guides/sdk/nodejs.md @@ -10,146 +10,314 @@ layout: Doc -# Node.js SDK +Serverless Dashboard, when Instrumentation is enabled on an AWS Lambda function, +will hook into the AWS Lambda runtime environment and automatically report +metrics, traces, spans, and events. To capture handled errors, warnings, and to +set custom tags, the SDK library must be added and instrumented in your AWS +Lambda function handler. + +## Key terms + +- An **Event** is an instance of an error, warning, or notice that is captured + as a part of a Trace. Multiple events can be captured in a single trace. +- A **Captured Error** is an instance of an error that is sent to Serverless + Dashboard as an Event. It can be viewed in the Trace Explorer Details. +- A **Captured Warning** is one instance of a string in Node.js that is sent to + Serverless Dashboard as an Event, much like a Captured Error. +- A **Tag** is a key/value-pair that can be set on the Trace or an individual + Event, and sent to Serverless Dashboard. Tags can be viewed on the Trace + Explorer Details. + +## Installation + +### Install the package + +When Tracing is enabled in Serverless Dashboard, an AWS Lambda Layer is added +to your AWS Lambda function with the `@serverless/sdk` package. While the AWS +Lambda layer is added by Serverless Dashboard, it is possible for the layer to +be removed temporarily if you deploy manually or with some infrastructure as +code tools. As such, we recommend bundling the SDK with your handler to avoid +unresolved references to the SDK. -## `captureError` +``` +npm install @serverless/sdk --save +# or +yarn add @serverless/sdk +``` + +### Using a bundler + +If you use a bundler, like esbuild, the AWS Lambda Layer for Serverless +Dashboard will instrument native Node.js APIs like `http` and `console`, and +APIs available on the runtime like the AWS SDK; however, if the handler bundles +APIs, like `express` or the AWS SDK, then Serverless Dashboard will not be able +to auto-instrument. To enable auto-instrumentation for these APIs, you will need +to manually add the AWS-specific auto-instrumentation library and initiate +auto-instrumentation. + +Install the `@serverless/aws-lambda-sdk` package locally. This replaces the need +for the `@serverless/sdk` package, so you do not need both. + +``` +npm install @serverless/aws-lambda-sdk --save +# or +yarn add @serverless/aws-lambda-sdk +``` + +Use the following methods to instrument the AWS client libraries and Express.js. + +```javascript +const express = require('express'); +const serverlessSdk = require('@serverless/aws-lambda-sdk'); + +// Instrument AWS SDK v2 +serverlessSdk.instrumentation.awsSdkV2.install(AWS); + +// Instrument AWS SDK v3 client +serverlessSdk.instrumentation.awsSdkV3Client.install(client); + +// Instruments Express.js +const expressApp = express(); +// Ensure you install the SDK instrumentation before +// installing any express middleware +serverlessSdk.instrumentation.expressApp.install(expressApp); +``` + +Additionally, in some instrumentation cases, it's important to ensure that +the bundler doesn't change the function names, as span names and tags are +resolved from them. In [esbuild](https://esbuild.github.io/) this can be ensured +with [`--keep-names`](https://esbuild.github.io/api/#keep-names) option. + +### Enable Instrumentation -Your lambda function may throw an exception, but your function handles it in order to respond to -the requester without throwing the error. One very common example is functions tied to HTTP -endpoints. Those usually should still return JSON, even if there is an error since the API Gateway -integration will fail rather than returning a meaningful error. +The SDK will merely generate the necessary Tags, Spans, and Events; however, +you must [Enable Instrumentation](/framework/docs/guide/monitoring/instrumentation) +for each of your functions for Serverless Dashboard to ingest the data. -For this case, we provide a `captureError` function available on either the `context.serverlessSdk` or on the -module imported from `'./serverless_sdk'`. This will cause the invocation to still display as an -error in the serverless dashboard while allowing you to return an error to the user. +## Usage -Here is an example of how to use it from the `context` object: +The package does not require any configuration as the credentials are +automatically set on the AWS Lambda function environment variables when Tracing +is enabled in Serverless Dashboard. + +To use the Serverless SDK you must require the `@serverless/sdk` method in your +AWS Lambda function handler. ```javascript -module.exports.hello = async (event, context) => { - try { - // do some real stuff but it throws an error, oh no! - throw new Error('aa'); - } catch (error) { - context.serverlessSdk.captureError(error); - } - return { - statusCode: 500, - body: JSON.stringify({ name: 'bob' }), - }; -}; +const serverlessSdk = require('@serverless/sdk'); ``` -And to import it instead, import with -`const { captureError } = require('./serverless_sdk')` then call `captureError` instead of -`context.serverlessSdk.captureError`. +### Capturing Errors + +The most common use case for the Serverless SDK is to capture handled errors. +There are two mechanisms for capturing handled errors. + +#### Using captureError ```javascript -const { captureError } = require('./serverless_sdk'); +try { + // an error is thrown +} catch (ex) { + serverlessSdk.captureError(ex); +} +``` + +#### Using console.error -module.exports.hello = async (event) => { - try { - // do some real stuff but it throws an error, oh no! - throw new Error('aa'); - } catch (error) { - captureError(error); - } - return { - statusCode: 500, - body: JSON.stringify({ name: 'bob' }), - }; -}; +```javascript +try { + // an error is thrown +} catch (ex) { + console.error(ex); +} ``` -## `span` +The Serverless SDK automatically instruments the `console.error` method to +capture errors. This makes instrumentation much easier as you may already be +using `console.error` to display the errors. + +This method can be used to capture `Error` objects, as well as any combination +of strings. If only an `Error` object is provided, then the stack trace in +Console will show the stack trace of the error object. If a string, or a +combination of a string and `Error`, are provided, then the stack trace of the +`console.error` will be captured. -While the `serverless_sdk` automatically instruments AWS SDK and HTTP spans, you may be interested -in capturing span data for functions that do numerical computation or functions making database -queries. For this use-case, you can use the `span` function provided by `serverless_sdk`. The first -argument is a string, which will be used as the label of your span in the Dashboard. And the second -argument is a function. If it returns a `Promise`, then so will `span` if it does not, `span` will -return nothing. +### Capturing Warnings -Example from context with an async function: +#### Using captureWarning ```javascript -module.exports.handler = async (event, context) => { - await context.serverlessSdk.span('some-label', async () => { - // The execution of this function is captured as a span. - // It is automatically invoked with no arguments and awaited. - }); -}; +serverlessSdk.captureWarning('Something bad will happen soon'); ``` -Example from context with a sync function: +#### Using console.warn ```javascript -module.exports.handler = async (event, context) => { - context.serverlessSdk.span('some-label', () => { - // The execution of this function is captured as a span. - // It is automatically invoked with no arguments. - }); -}; +console.warn('My Warning'); ``` -You can also import the function from `'./serverless_sdk'` +The Serverless SDK automatically instruments the `console.warn` method to +capture warnings. This makes instrumentation easier as you may already be using +`console.warn` to display warnings. + +This method only supports capturing strings. + +We recommend avoiding using unique instance values for the strings. For example, +if you need to include a userId, email, request ID, or any ID that may be unique +to the individual invocation, we recommend using Tagging instead. + +This method will capture the stack trace of the `console.warn` call so it +is easy to identify in Serverless Dashboard. + +### Tagging + +#### Setting Tags on the Trace ```javascript -const { span } = require('./serverless_sdk'); -module.exports.handler = async (event, context) => { - span('some-label', () => { - // The execution of this function is captured as a span. - // It is automatically invoked with no arguments. - }); -}; +serverlessSdk.setTag('userId', 'bd86489cf036'); ``` -## `tagEvent` +Using the `setTag` method will create Tags associated with the entire Trace. +You'll be able to see the Tags on the Trace Details page in the Trace Explorer. + +All Tags set with `setTag` are also inherited by all the Captured Errors and +Captured Warnings. -Busy applications can invoke hundreds of thousands of requests per minute! At these rates, finding specific invocations can be like -searching for a needle in a haystack. We've felt this pain, which is why we've introduced tagged events. -Tagged Events are a simple way to identify invocations in the Serverless Dashboard. You can tag an invocation with any string you like, and find -all invocations associated with that tag. To provide extra context, you can specify a tag value to optionally filter on. If you're accustomed to -logging out a debugging object, you can pass a third `custom` attribute that will be surfaced in the dashboard as well. +Tag keys may only contain alphanumeric, `.`, `-`, and `_` characters. Tag values +may contain any string value. Invalid tag keys will not throw errors, instead, +an SDK error will be made available in Trace Details. + +#### Settings Tags with console.error and console.warn + +```javascript +serverlessSdk.setTag('userId', 'bd86489cf036'); +console.warn('warning message'); +console.error(new Error('some error')); +``` -The `tagEvent` function is available on either the `context.serverlessSdk` or on the -module imported from `'./serverless_sdk'`. +Using `setTag` sets the Tag values on both the Trace and all Captured Errors +and Captured Warnings. Captured Errors and Captured Warnings can be created +using the `console.error` and `console.warn` methods. Therefore, Tags set with +`setTag` will apply to all Captured Errors and Captured Warnings created using +`console.error` and `console.warn`. -Here is an example of how to use it from the `context.serverlessSdk` object: +#### Setting Tags on Captured Errors ```javascript -module.exports.hello = async (event, context) => { - // ... set up some state/custom logic - context.serverlessSdk.tagEvent('customer-id', event.body.customerId, { - demoUser: true, - freeTrialExpires: '2020-09-01', - }); - return { - statusCode: 200, - body: JSON.stringify({ name: 'bob' }), - }; -}; +serverlessSdk.captureError(ex, { tags: { userId: '1b8b4c6b4b14' } }); ``` -## Automatic route instrumentation with application middleware +Tags can also be set on the individual error. If you previously set a Tag using +`setTag` then the Tags set on `captureError` will override the Tags on the +Captured Error, while keeping the Tag on the trace unmodified. -Faced with practical considerations (a big one being CloudFormation stack resource limit), developers often reach for a single function solution with routing being handled by the application layer. This is usually accomplished either by leveraging plugins that extend popular application frameworks to play nicely with the Lambda runtime (e.g. [serverless-express](https://serverless.com/plugins/serverless-express/)), using a purpose-built one (like [lambda-api](https://github.com/jeremydaly/lambda-api)), or even rolling their own (via [lambda-router](https://github.com/trek10inc/lambda-router)). +Tag keys on `captureError` are validated the same way as tag keys on `setTag`. -An unfortunate downside of this approach is the loss of visibility into the mapped route for invocations. Instead, you're left with either the catch-all API Gateway resource path (`/{proxy+}`) or the raw request url itself (e.g. `/org/foo/user/bar/orders`). Neither of which are conducive for exploration and debugging invocations. The former is not very useful and the latter wouldn't let you group invocations by their routed endpoints to bubble up say, performance issues. +#### Setting Tags on Captured Warnings -To alleviate these issues, for an application using `serverless-express` or `lambda-api`, the SDK will automatically instrument incoming invocations to set the routed endpoint. There's zero setup required! +```javascript +serverlessSdk.captureWarning('warning message', { tags: { userId: 'eb661c69405c' } }); +``` + +Tags can also be added on the individual Captured Warnings, just like Captured +Errors. + +Tag keys on `captureWarning` are validated the same way as tag keys on +`setTag`. + +### Structured Logs with captureError and captureWarning + +The `captureWarning` and `captureError` methods will send the content to +Serverless Console in a binary format. To enable human-readability these +methods will also output a structured-log JSON string, like the one shown +below. + +This string is easier to read, and can also be used with other tools like +CloudWatch Log Insights to parse and search. + +```javascript +{ + "source": "serverlessSdk", + "type": "ERROR_TYPE_CAUGHT_USER", + "message": "User not found", + "stackTrace": "...", + "tags": { + "userId": "eb661c69405c" + } +} +``` + +To disable the output of the structured logs with `captureError` and +`captureWarning`, set this environment variable in the runtime. + +```bash +SLS_DISABLE_CAPTURED_EVENTS_STDOUT=true +``` + +### Creating Custom Spans + +Spans are part of the Trace that show when something started and stopped. Spans +can be nested and they can contain Events. Spans are automatically created by +the Serverless SDK for AWS and HTTP requests. These methods show you how you can +create your own custom spans and nest them. + +#### Create a Custom Span + +```javascript +const customSpan1 = serverlessSdk.createSpan('mySpan'); +// do some work +customSpan1.close(); +``` + +#### Creating a Custom Span with a callback + +Instead of creating a span and stopping it using `close()`, you can also pass a +callback method to `createSpan` to automatically start/stop the span when the +callback starts/stops. + +```javascript +serverlessSdk.createSpan('mySpan', () => { + // do some work +}); +``` + +This also supports `async` callbacks. + +```javascript +serverlessSdk.createSpan('mySpan', async () => { + // do some work +}); +``` + +#### Creating Nested Spans + +Spans can also be nested by calling the `createSpan` method on a Span. + +```javascript +const span1 = serverlessSdk.createSpan('span1'); +const span2 = span1.createSpan('span2'); +// do some work +span2.close(); +// do additional work +span1.close(); +``` -If your application is using a custom-built router, you can still work around this issue by calling the `setEndpoint` SDK function described below. +Child spans must be stopped via `close()` before the parent Span is stopped. If +a parent span is stopped, then all child spans will be stopped. -Once set, invocations can be explored and inspected by endpoint in the Dashboard. +### Setting a custom endpoint -## `setEndpoint` +When using a mono-lambda architecture, in which a single lambda function with a +framework like Express.js is routed from a single API Gateway endpoint, the +request on API Gateway is captured as a proxy endpoint. As a result, the request +may appear as `/{proxy+}` instead of the intended path. The Serverless SDK +automatically instruments frameworks like Express.js, KOA, etc. to capture the +correct endpoint. This enables you to filter for HTTP requests using the +inteded path. -Allows the application to explicitly set the routed endpoint for an invocation. Like the other SDK methods, `setEndpoint` is available on either the context object: `context.serverlessSdk`, or can be imported manually from the base directory: `const { setEndpoint } = require('./serverless_sdk')`. Example usage: +In some cases, it may be necessary to manually set the endpoint. In such cases +you can use the `setEndpoint` method to customize the endpoint path. ```javascript -module.exports.api = async (event, context) => { - context.serverlessSdk.setEndpoint('/api/foo'); - // application code... -}; +serverlessSdk.setEndpoint('/my/custom/endpoint'); ``` diff --git a/docs/guides/sdk/python.md b/docs/guides/sdk/python.md index e070e230983..1161e9c1b95 100644 --- a/docs/guides/sdk/python.md +++ b/docs/guides/sdk/python.md @@ -12,130 +12,298 @@ layout: Doc # Python SDK -## `capture_exception` +Serverless Console, when Instrumentation is enabled on an AWS Lambda function, +will hook into the AWS Lambda runtime environment and automatically report +metrics, traces, spans, and events. To capture handled errors, warnings, and to +set custom tags, the SDK library must be added and instrumented in your AWS +Lambda function handler. + +## Key terms + +- An **Event** is an instance of an error, warning, or notice that is captured + as a part of a Trace. Multiple events can be captured in a single trace. +- A **Captured Error** is an instance of an error that is sent to Serverless + Console as an Event. It can be viewed in Dev Mode or the Trace Explorer Details. +- A **Captured Warning** is one instance of a string in Python that is sent to + Serverless Console as an Event, much like a Captured Error. +- A **Tag** is a key/value-pair that can be set on the Trace or an individual + Event, and sent to Serverless Console. Tags can be viewed on the Trace Explorer + Details and Dev Mode. + +## Compatibility + +While Serverless Console is developed by the makers of the Serverless Framework, +the entire Serverless Console product and this SDK are 100% agnostic of the +deployment tool you use. Serverless Console and this SDK work just as well with +Terraform, CDK, SAM, Pulumi, etc, as as they do with Serverless Framework. + +## Installation + +### Install the package + +When Tracing is enabled in Serverless Console, an AWS Lambda Layer is added to +your AWS Lambda function with the `sls_sdk` package. While the AWS +Lambda layer is added by Serverless Console, it is possible for the layer to be +removed temporarily if you deploy manually or with some infrastructure as code +tools. As such, we recommend bundling the SDK with your handler to avoid +unresolved references to the SDK. -Your lambda function may throw an exception, but your function handles it in order to respond to -the requester without throwing the error. One very common example is functions tied to HTTP -endpoints. Those usually should still return JSON, even if there is an error since the API Gateway -integration will fail rather than returning a meaningful error. +``` +pip install serverless-sdk +``` + +### Enable Instrumentation + +The SDK will merely generate the necessary Tags, Spans, and Events; however, +you must [Enable Instrumentation](/console/docs/instrumentation) for each of +your functions for Serverless Console to ingest the data. + +## Usage + +The package does not require any configuration as the credentials are +automatically set on the AWS Lambda function environment variables when Tracing +is enabled in Serverless Console. + +To use the Serverless SDK you must import the `sls_sdk` package in your +AWS Lambda function handler. + +```python +from sls_sdk import serverlessSdk +``` -For this case, we provide a `captureError` function available on either the `context.serverless_sdk` or on the -module imported from `'serverless_sdk'`. This will cause the invocation to still display as an -error in the serverless dashboard while allowing you to return an error to the user. +### Capturing Errors -Here is an example of how to use it from the `context` object: +The most common use case for the Serverless SDK is to capture handled errors. +There are two mechanisms for capturing handled errors. + +#### Using capture_error ```python -def hello(event, context): - try: - # do some real stuff but it throws an error, oh no! - raise Exception('aa') - except Exception as exc: - context.serverless_sdk.capture_exception(exc) - return { - 'statusCode': 500, - 'body': '{"name": "bob"}', - } -``` - -And to import it instead, import with -`from serverless_sdk import capture_exception` then call `capture_exception` instead of -`context.serverless_sdk.capture_exception`. +serverlessSdk.capture_error(Exception("Unexpected")) +``` + +#### Using logging ```python -from serverless_sdk import capture_exception +import logging -def hello(event, context): - try: - # do some real stuff but it throws an error, oh no! - raise Exception('aa') - except Exception as exc: - capture_exception(exc) - return { - 'statusCode': 500, - 'body': '{"name": "bob"}', - } +logging.error("Logged error") ``` -## `span` +The Serverless SDK automatically instruments the `logging.error` method to +capture errors. This makes instrumentation much easier as you may already be +using `logging.error` to display the errors. + +This method can be used to capture `Exception` objects, as well as any +combination of strings. If only an `Exception` object is provided, then the +stack trace in Console will show the stack trace of the error object. If a +string, or a combination of a string and `Exception`, are provided, then the +stack trace of the `logging.error` will be captured. -While the `serverless_sdk` automatically instruments AWS SDK and HTTP spans, you may be interested -in capturing span data for functions that do numerical computation or functions making database -queries. For this use-case, you can use the `span` context manager provided by `serverless_sdk`. -It accepts one argument of a label. The code within the `with` statement using the context manager -will be captured as a span in the Dashboard. +### Capturing Warnings + +#### Using capture_warning ```python -def handler(event, context): - with context.serverless_sdk.span('some-label'): - pass # the execution of this `with` statement will be captured as a span +serverlessSdk.capture_warning("Captured warning") ``` -You can also import the function from `serverless_sdk` +#### Using logging.warning ```python -from serverless_sdk import span -def handler(event, context): - with span('some-label'): - pass # the execution of this `with` statement will be captured as a span +import logging + +logging.warning("Logged warning %s %s", 12, True) ``` -It also works as an async context manager for use with `async with`. +The Serverless SDK automatically instruments the `logging.warning` method to +capture warnings. This makes instrumentation easier as you may already be using +`logging.warning` to display warnings. -## `tag_event` +This method only supports capturing strings. -Busy applications can invoke hundreds of thousands of requests per minute! At these rates, finding specific invocations can be like -searching for a needle in a haystack. We've felt this pain, which is why we've introduced tagged events. -Tagged Events are a simple way to identify invocations in the Serverless Dashboard. You can tag an invocation with any string you like, and find -all invocations associated with that tag. To provide extra context, you can specify a tag value to optionally filter on. If you're accustomed to -logging out a debugging object, you can pass a third `custom` attribute that will be surfaced in the dashboard as well. +We recommend avoiding using unique instance values for the strings. For example, +if you need to include a userId, email, request ID, or any ID that may be unique +to the individual invocation, we recommend using Tagging instead. -The `tag_event` function is available on either the `context.serverless_sdk` or on the -module imported from `'./serverless_sdk'`. +This method will capture the stack trace of the `logging.warning` call so it +is easy to identify in Console. -Here is an example of how to use it from the `context.serverless_sdk` object: +### Tagging + +#### Setting Tags on the Trace ```python -def hello(event, context): - # ... set up some state/custom logic - context.serverless_sdk.tagEvent( - 'customer-id', - event.body.customerId, - { 'demoUser': 'true', 'freeTrialExpires': '2020-09-01' } - ) - return { - 'statusCode': 500, - 'body': '{"name": "bob"}', - } +serverlessSdk.set_tag("userId", user_id) ``` -## Automatic route instrumentation with application middleware +Using the `set_tag` method will create Tags associated with the entire Trace. +You'll be able to see the Tags on the Trace Details page in the Trace Explorer. + +All Tags set with `set_tag` are also inherited by all the Captured Errors and +Captured Warnings. -Faced with practical considerations (a big one being CloudFormation stack resource limit), developers often reach for a single function solution with routing being handled by the application layer. This is typically accomplished by leveraging the [serverless-wsgi](https://github.com/logandk/serverless-wsgi) plugin to deploy existing WSGI applications (Flask/Django/Pyramid etc). Rolling your own custom router is another option as well. +Tag keys may only contain alphanumeric, `.`, `-`, and `_` characters. Tag values +may contain any string value. Invalid tag keys will not throw errors, instead, +an SDK error will be made available in Dev Mode and Trace Details. -An unfortunate downside of this approach is the loss of visibility into the mapped route for invocations. Instead, you're left with either the catch-all API Gateway resource path (`/{proxy+}`) or the raw request url itself (e.g. `/org/foo/user/bar/orders`). Neither of which are conducive for exploration and debugging invocations. The former is not very useful and the latter wouldn't let you group invocations by their routed endpoints to bubble up say, performance issues. +#### Settings Tags with console.error and console.warn -To alleviate this issue, when deploying a [Flask](https://flask.palletsprojects.com/en/1.1.x/) application, the SDK will automatically instrument incoming invocations to set the routed endpoint. There's zero setup required! +```python +import logging -If your application is using a custom-built router, you can still work around this issue by calling the `set_endpoint` SDK function described below. +serverlessSdk.set_tag("userId", user_id) -Once set, invocations can be explored and inspected by endpoint in the Dashboard. +logging.error("Logged error") +logging.warning("Logged warning %s %s", 12, True) +``` -## `set_endpoint` +Using `set_tag` sets the Tag values on both the Trace and all Captured Errors +and Captured Warnings. Captured Errors and Captured Warnings can be created +using the `logging.error` and `logging.warning` methods. Therefore, Tags set +with `set_tag` will apply to all Captured Errors and Captured Warnings +created using `logging.error` and `logging.warning`. -Allows the application to explicitly set the routed endpoint for an invocation. Like the other SDK methods, `setEndpoint` is available on either the context object: `context.serverless_sdk`. +#### Setting Tags on Captured Errors ```python -def handler(event, context): - context.serverless_sdk.set_endpoint('/api/foo') - # application code... +serverlessSdk.capture_error( + Exception("Captured error"), + tags={"userId": "example", "invocationId": invocation_id}, +) ``` -You can also import the function from `serverless_sdk` +Tags can also be set on the individual error. If you previously set a Tag using +`set_tag` then the Tags set on `capture_error` will override the Tags on the +Captured Error, while keeping the Tag on the trace unmodified. + +Tag keys on `capture_error` are validated the same way as tag keys on +`set_tag`. + +#### Setting Tags on Captured Warnings + +```python +serverlessSdk.capture_warning( + "Captured warning", + tags={"userId": "example", "invocationid": invocation_id}, +) +``` + +Tags can also be added on the individual Captured Warnings, just like Captured +Errors. + +Tag keys on `capture_warning` are validated the same way as tag keys on +`set_tag`. + +### Capturing Unhandled Exceptions with Flask + +Serverless Console will capture unhandled exceptions thrown from the handler +method. This can be achieved without including the `sls_sdk` package, as +it is provided by the AWS Lambda Layer added to your Lambda function when +instrumentation is enabled. + +If you are using Flask, it will automatically handle unhandled exceptions. As a +result, the exceptions do not propagate to the handler or the Serverless Console +instrumentation layer. You can set the `PROPAGATE_EXCEPTIONS` configuration +property in Flask for it to propagate the exception and make it available to +Serverless Console. This will enable you to search for traces with unhandled +exceptions in Serverless Console. + +```python +app.config['PROPAGATE_EXCEPTIONS'] = True +``` + +Note, changing this behavior changes the behavior of the handler response so +other updates may be necessary. + +### Structured Logs with capture_error and capture_warning + +The `capture_warning` and `capture_error` methods will send the content to +Serverless Console in a binary format. To enable human-readability these +methods will also output a structured-log JSON string, like the one shown +below. + +This string is easier to read, and can also be used with other tools like +CloudWatch Log Insights to parse and search. + +```json +{ + "source": "serverlessSdk", + "type": "ERROR_TYPE_CAUGHT_USER", + "message": "User not found", + "stackTrace": "...", + "tags": { + "userId": "eb661c69405c" + } +} +``` + +To disable the output of the structured logs with `capture_error` and +`capture_warning`, set this environment variable in the runtime. + +```bash +SLS_DISABLE_CAPTURED_EVENTS_STDOUT=true +``` + +### Custom Spans + +Spans are part of the Trace that show when something started and stopped. Spans +can be nested and they can contain Events. Spans are automatically created by +the Serverless SDK for AWS and HTTP requests. These methods show you how you can +create your own custom spans and nest them. + +#### Creating a Custom Span + +```python +from sls_sdk import serverlessSdk +span = serverlessSdk.create_span('some-label') +# some work +span.close() +``` + +#### Create a Custom Span using `with` + +Instead of creating a span and stopping it using `close()`, you can also use +`with` to automatically stop the span. + +```python +from sls_sdk import serverlessSdk + +with serverlessSdk.create_span('some-label'): + pass # the execution of this `with` statement will be captured as a span +``` + +#### Create a nested Span + +Spans can also be nested by calling the `create_span` method inside another. + +```python +from sls_sdk import serverlessSdk + +span1 = serverlessSdk.create_span('span1') +span2 = span1.create_span('span2') + +# do some work +span2.close(); +# do additional work +span1.close(); +``` + +Child spans must be stopped via `close()` before the parent Span is stopped. If +a parent span is stopped, then all child spans will be stopped. + +### Setting a custom endpoint + +When using a mono-lambda architecture, in which a single lambda function with a +framework like Flask is routed from a single API Gateway endpoint, the +request on API Gateway is captured as a proxy endpoint. As a result, the request +may appear as `/{proxy+}` instead of the intended path. The Serverless SDK +automatically instruments Flask to capture the correct endpoint. This enables +you to filter for HTTP requests using the inteded path. + +In some cases, it may be necessary to manually set the endpoint. In such cases +you can use the `set_endpoint` method to customize the endpoint path. ```python -from serverless_sdk import set_endpoint -def handler(event, context): - set_endpoint('/api/foo') - # application code... +serverlessSdk.set_endpoing('/my/custom/endpoint'); ``` diff --git a/docs/guides/upgrade.md b/docs/guides/upgrade.md new file mode 100644 index 00000000000..0cbc2bf0e6a --- /dev/null +++ b/docs/guides/upgrade.md @@ -0,0 +1,347 @@ + + + + +### [Read this on the main serverless docs site](https://www.serverless.com/framework/docs/guides/upgrade/) + + + +# Upgrade Guide + +## Connect AWS & Add Instrumentation + +The new monitoring features require an integration with AWS. The previous +version of Serverless Dashboard created this integration from the CLI when a +service was deployed. The new version of Serverless Dashboard provides two +options for adding the integration, you can use the Dashboard UI or the CLI. + +The Dashboard UI is the easier method of the two, as it does not require +the Serverless Framework to be upgrade, and it does not require redeployment. + +### Using the Dashboard UI + +To enable the new monitoring, you must first create an integration with AWS in +Serverless Dashboard, and instrument each AWS Lambda function. + +When you visit any of the monitoring features in Dashboard, you will be prompted +to add the Integration if one doesn't already exist. You can also visit +**Settings > Integrations** to create the integration. + +Once the integration is created, you will be prompted on the app view page to +add the instrumentation. You can also visit **Settings > Instrumentation**, and +click **Edit** on the Integration to enable instrumentation on functions +one-by-one or in bulk. + +### Using the CLI + +Update the Serverless Framework CLI to version 3.35.0 or higher. + +``` +npm install serverless --global +``` + +As an existing Serverless Dashboard user, the `serverless.yml` will already +contain `org` and `app` properties. These properties are required for Serverless +Dashboard to continue working. + +Redeploy your service. + +``` +serverless deploy +``` + +The first time you deploy your service after upgrading the Serverless Framework, +the CLI will create the Dashboard integration, including the necessary IAM Role. + +Additionally, the service must be instrumented, which is done automatically +upon deployment. The instrumentation adds the AWS CloudWatch Log subscription +and adds the necessary AWS Lambda layer. + +To use the new monitoring, you must redeploy each service with this version. + +Alternatively, you can use the Dashboard UI to both add the integration and +the instrumentation to each function. This does not require upgrade or +deployment. + +## Updating serverless.yml + +For majority of users no changes are necessary to the `serverless.yml`; however, +if you used one of the less frequently used features, you may need to make +updates to your `serverless.yml` file to remove dependencies on deprecated +features. + +### Remove reference to logIngestMode + +When Dashboard monitoring was first released, there was a limit of one +subscription per CloudWatch Log Group. Since then, the limit has increased to +two. This means that the `logIngestMode` option is no longer necessary in most +orgs. + +Remove references in `serverless.yml` to `custom.enterprise.logIngestMode`: + +```yaml +custom: + enterprise: + logIngestMode: pull +``` + +### Replace reference to disableAwsSpan and disableHttpSpan + +These two options disable the automatic collection of AWS and HTTP Spans in +traces. Previous these options were avilable in `custom.enterprise` in the +`serverless.yml` file. These options have been replaced with environment +variables that must be set on the lambda function. + +```yaml +custom: + enterprise: + disableAwsSpan: true + disableHttpSpans: true +``` + +Set the environment variables on all the functions in the `serverless.yml` + +```yaml +provider: + environment: + SLS_DISABLE_HTTP_MONITORING: true + SLS_DISABLE_AWS_SDK_MONITORING: true +``` + +### Replace collectLambdaLogs + +If you are using features like Parameters, Providers, or Outputs, but not using +the Monitoring features, you can disable monitoring. We've simplified the syntax +for disabling monitoring in Dashboard. + +This option is now deprecated: + +```yaml +custom: + enterprise: + collectLambdaLogs: false +``` + +Use the `monitor` option to disable monitoring instead: + +```yaml +dashboard: + disableMonitoring: true +``` + +### Remove Dashboard SDK Wrapping (optional) + +The Serverless Framework automatically includes the Dashboard SDK in the Lambda +package by wrpaping the AWS Lambda function handler on deployment. As of version +3.35.0+ of the Serverless Framework, the Dashboard SDK has been replaced with +no-op methods as to not break deployments. The next major release of the +Serverless Framework will fully deprecate the Dashboard SDK and disable +wrapping. + +If you used the Dashboard SDK, you'll need to follow the "Update Node.js SDK" +and "Update Python SDK" sections to update the SDK usage. + +In some cases, the Dashboard SDK wrapping may break your code. In these cases +wrapping is automatically disabled: + +- You are using `.mjs` files +- You have set `"type": "module"` in `package.json` +- You are using Python version 3.11 or higher + +You can also manually disable the Wrapping by including the following in your +`serverless.yml`. + +```yaml +custom: + enterprise: + disableWrapping: true +``` + +## Updating Node.js SDK + +The Serverless Framework Dashboard SDK has been deprecated and replaced with the +Serverless SDK. The new Serverless SDK provides support for additional features. +In most cases the methods are drop-in replacements; however, some methods have +been replaced with new methods. + +### Loading SDK + +The Dashboard SDK can be loaded either by requiring `./serverless_sdk` or by +using the methods automatically loaded in `context.serverlessSdk`. + +The `context.serverlessSdk` methods are now deprecated and therefore you will +need to load the SDK via `require("@serverless/sdk")`. + +If you use `require("./serverless_sdk")` you will need to update your code to +load the SDK via `require("@serverless/sdk")`. + +```javascript +// Replace this +const serverlessSdk = require('./serverless_sdk'); + +// with this +const serverlessSdk = require('@serverless/sdk'); +``` + +### Replace captureError() + +The `captureError` method for capturing errors in Dashboard SDK is available as +a drop-in replacement in the Serverless SDK. + +```javascript +// Replace this +context.serverlessSdk.captureError(error); + +// with this +const serverlessSdk = require('@serverless/sdk'); +serverlessSdk.captureError(ex); +``` + +### Replace tagEvents() + +The `tagEvents` method was available in Dashboard SDK for tagging the Traces. +The `setTag` has been introduced to support tagging of both Traces and Events. +To replace `tagEvents` use `setTag` to tag the Trace. + +```javascript +// Replace this +context.serverlessSdk.tagEvents('someKey', 'someValue', { demoUser: true }); + +// with this +const serverlessSdk = require('@serverless/sdk'); +serverlessSdk.setTag('someKey', 'someValue'); +serverlessSdk.setTag('demoUser', true); +``` + +The third parameter in `tagEvents` allowed for adding additional context that +was not searchable in Dashboard. The Serverless SDK does not support such a +parameter and instead, it is recommended that you add this additional context as +new tags. + +### Replace span() + +The `span` method for creating spans in Dashboard SDK is available as +a drop-in replacement in the Serverless SDK using the `createSpan` method. + +```javascript +// Replace this +context.serverlessSdk.span('some-label', () => { + // Some work +}); + +// with this +const serverlessSdk = require('@serverless/sdk'); +serverlessSdk.createSpan('some-label', () => { + // Some work +}); +``` + +### Replace setEndpoint() + +The `setEndpoint()` method for setting the endpoint in Dashboard SDK is +available as a drop-in replacement in the Serverless SDK. + +```javascript +// Repalce this +context.serverlessSdk.setEndpoint('/api/foo'); + +// with this +const serverlessSdk = require('@serverless/sdk'); +serverlessSdk.setEndpoint('/api/foo'); +``` + +## Updating Python SDK + +The Serverless Framework Dashboard SDK has been deprecated and replaced with the +Serverless SDK. The new Serverless SDK provides support for additional features. +In most cases the methods are drop-in replacements; however, some methods have +been replaced with new methods. + +### Loading SDK + +The Dashboard SDK can be loaded adding the `serverless_sdk` module or by +using the methods automatically loaded in `context.serverless_sdk`. + +The `context.serverless_sdk` methods are now deprecated and therefore you will +need to load the SDK by adding the `serverless_sdk` module. + +If you load the module you'll need to replace `serverless_sdk` with `sls_sdk`. + +```python +# Replace this +from serverless_sdk import capture_exception, span, tag_event, set_endpoint + +# with this +from sls_sdk import serverlessSdk +``` + +### Replace capture_error() + +The `capture_error` method for capturing errors in Dashboard SDK is available as +a drop-in replacement in the Serverless SDK. + +```python +# Replace this +context.serverless_sdk.capture_error(Exception("Unexpected")); + +# with this +from sls_sdk import serverlessSdk; +serverlessSdk.capture_error(Exception("Unexpected")); +``` + +### Replace tag_event() + +The `tag_event` method was available in Dashboard SDK for tagging the Traces. +The `set_tag` has been introduced to support tagging of both Traces and Events. +To replace `tag_event` use `set_tag` to tag the Trace. + +```python +# Replace this +context.serverless_sdk.tag_event('someKey', 'someValue', { 'demoUser': 'true' }); + +# with this +from sls_sdk import serverlessSdk +serverlessSdk.set_tag('someKey', 'someValue'); +serverlessSdk.set_tag('demoUser', 'true'); +``` + +The third parameter in `tag_event` allowed for adding additional context that +was not searchable in Dashboard. The Serverless SDK does not support such a +parameter and instead, it is recommended that you add this additional context as +new tags. + +### Replace span() + +The `span` method for creating spans in Dashboard SDK is available as +a drop-in replacement in the Serverless SDK using the `create_span` method. + +```python +# Replace this +with context.serverless_sdk.span('some-label'): + pass # some work + +# with this +from sls_sdk import serverlessSdk +with serverlessSdk.create_span('some-label'): + pass # some work +``` + +### Replace set_endpoint() + +The `set_endpoint()` method for setting the endpoint in Dashboard SDK is +available as a drop-in replacement in the Serverless SDK. + +```python +# Repalce this +context.serverless_sdk.set_endpoint('/api/foo'); + +# with this +from sls_sdk import serverlessSdk +serverlessSdk.set_endpoint('/api/foo'); +``` diff --git a/docs/menu.json b/docs/menu.json index 652a39ef37c..5f03f103307 100644 --- a/docs/menu.json +++ b/docs/menu.json @@ -447,11 +447,14 @@ "Monitoring": { "Overview": "guides/monitoring", "Alerts": "guides/monitoring/alerts", + "Instrumentation": "guides/monitoring/instrumentation", "Metrics": "guides/monitoring/metrics", - "Notifications": "guides/monitoring/notifications" + "Notifications": "guides/monitoring/notifications", + "Trace Explorer": "guides/monitoring/trace-explorer" }, "Outputs": "guides/output-variables", "Providers": "guides/providers", + "Orgs & Members": "guides/orgs", "CI/CD": { "Overview": "guides/cicd", "Branch Deployments": "guides/cicd/branch-deployments", @@ -471,7 +474,8 @@ "nodejs": "guides/sdk/nodejs", "python": "guides/sdk/python" }, - "Testing": "guides/testing" + "Testing": "guides/testing", + "Upgrading": "guides/upgrade" }, "Serverless.yml Reference": "providers/aws/guide/serverless.yml", "CLI Reference": {