Giter Site home page Giter Site logo

datadog / serverless-plugin-datadog Goto Github PK

View Code? Open in Web Editor NEW
87.0 14.0 49.0 1.7 MB

Serverless plugin to automagically instrument your Lambda functions with Datadog

License: Apache License 2.0

TypeScript 94.80% JavaScript 0.20% Shell 3.07% Python 1.84% Ruby 0.10%

serverless-plugin-datadog's Introduction

build Code Coverage NPM Slack License

Datadog recommends the Serverless Framework Plugin for developers using the Serverless Framework to deploy their serverless applications. The plugin automatically enables instrumentation for applications to collect metrics, traces, and logs by:

  • Installing the Datadog Lambda library to your Lambda functions as a Lambda layer.
  • Installing the Datadog Lambda Extension to your Lambda functions as a Lambda layer (addExtension) or subscribing the Datadog Forwarder to your Lambda functions' log groups (forwarderArn).
  • Making the required configuration changes, such as adding environment variables or additional tracing layers, to your Lambda functions.

Getting started

To quickly get started, follow the installation instructions for Python, Node.js, Ruby, Java, Go, or .NET and view your function's enhanced metrics, traces, and logs in Datadog.

After installation is complete, configure the advanced options to suit your monitoring needs.

Upgrade

Each version of the plugin is published with a specific set of versions of the Datadog Lambda layers. To pick up new features and bug fixes provided by the latest versions of Datadog Lambda layers, upgrade the serverless framework plugin. Test the new version before applying it on your production applications.

Configuration parameters

To further configure your plugin, use the following custom parameters in your serverless.yml:

Parameter Description
site Set which Datadog site to send data to, such as datadoghq.com (default), datadoghq.eu, us3.datadoghq.com, us5.datadoghq.com, ap1.datadoghq.com, or ddog-gov.com. This parameter is required when collecting telemetry using the Datadog Lambda Extension.
apiKey Datadog API key. This parameter is required when collecting telemetry using the Datadog Lambda Extension. Alternatively, you can also set the DATADOG_API_KEY environment variable in your deployment environment.
appKey Datadog app key. Only needed when the monitors field is defined. Alternatively, you can also set the DATADOG_APP_KEY environment variable in your deployment environment.
apiKeySecretArn An alternative to using the apiKey field. The ARN of the secret that is storing the Datadog API key in AWS Secrets Manager. Remember to add the secretsmanager:GetSecretValue permission to the Lambda execution role.
apiKMSKey An alternative to using the apiKey field. Datadog API key encrypted using KMS. Remember to add the kms:Decrypt permission to the Lambda execution role.
env When set along with addExtension, a DD_ENV environment variable is added to all Lambda functions with the provided value. Otherwise, an env tag is added to all Lambda functions with the provided value. Defaults to the stage value of the serverless deployment.
service When set along with addExtension, a DD_SERVICE environment variable is added to all Lambda functions with the provided value. Otherwise, a service tag is added to all Lambda functions with the provided value. Defaults to the service value of the serverless project.
version When set along with addExtension, a DD_VERSION environment variable is added to all Lambda functions with the provided value. When set along with forwarderArn, a version tag is added to all Lambda functions with the provided value.
tags A comma separated list of key:value pairs as a single string. When set along with extensionLayerVersion, a DD_TAGS environment variable is added to all Lambda functions with the provided value. When set along with forwarderArn, the plugin parses the string and sets each key:value pair as a tag on all Lambda functions.
enableXrayTracing Set true to enable X-Ray tracing on the Lambda functions and API Gateway integrations. Defaults to false.
enableDDTracing Enable Datadog tracing on the Lambda function. Defaults to true.
enableASM Enable Datadog Application Security Management (ASM) on the Lambda function. Requires the Datadog extension to be present (using addExtension or manually added) and enableDDTracing. Defaults to false.
enableDDLogs Enable Datadog log collection using the Lambda Extension. Defaults to true. Note: This setting has no effect on logs sent by the Datadog Forwarder.
monitors When defined, the Datadog plugin configures monitors for the deployed function. Requires setting DATADOG_API_KEY and DATADOG_APP_KEY in your environment. To learn how to define monitors, see To Enable and Configure a Recommended Serverless Monitor.
captureLambdaPayload Captures incoming and outgoing AWS Lambda payloads in the Datadog APM spans for Lambda invocations. Defaults to false.
enableSourceCodeIntegration Enable Datadog Source Code Integration for the function. Defaults to true.
uploadGitMetadata Enable Git metadata uploading for the function, as a part of source code integration. Set this to false if you have the Datadog Github Integration installed, as it renders Git metadata uploading unnecessary. Defaults to true.
subscribeToAccessLogs Enable automatic subscription of the Datadog Forwarder to API Gateway access log groups. Requires setting forwarderArn. Defaults to true.
subscribeToExecutionLogs Enable automatic subscription of the Datadog Forwarder to HTTP API and Websocket log groups. Requires setting forwarderArn. Defaults to true.
forwarderArn The ARN of the Datadog Forwarder to be subscribed to the Lambda or API Gateway log groups.
addLayers Whether to install the Datadog Lambda library as a layer. Defaults to true. Set to false when you plan to package the Datadog Lambda library to your function's deployment package on your own so that you can install a specific version of the Datadog Lambda library (Python or Node.js).
addExtension Whether to install the Datadog Lambda Extension as a layer. Defaults to true. When enabled, it's required to set the apiKey and site.
exclude When set, this plugin ignores all specified functions. Use this parameter if you have any functions that should not include Datadog functionality. Defaults to [].
enabled When set to false, the Datadog plugin stays inactive. Defaults to true. You can control this option using an environment variable. For example, use enabled: ${strToBool(${env:DD_PLUGIN_ENABLED, true})} to activate/deactivate the plugin during deployment. Alternatively, you can also use the value passed in through --stage to control this option—see example.
customHandler When set, the specified handler is set as the handler for all the functions.
failOnError When set, this plugin throws an error if any custom Datadog monitors fail to create or update. This occurs after deploy, but will cause the result of serverless deploy to return a nonzero exit code (to fail user CI). Defaults to false.
logLevel The log level, set to DEBUG for extended logging.
skipCloudformationOutputs Set to true if you want to skip adding Datadog Cloudformation Outputs for your stack. This is useful if you are running into the 200 output limit which can cause the stack creation to fail.
enableColdStartTracing Set to false to disable Cold Start Tracing. Used in NodeJS and Python. Defaults to true.
coldStartTraceMinDuration Sets the minimum duration (in milliseconds) for a module load event to be traced via Cold Start Tracing. Number. Defaults to 3.
coldStartTraceSkipLibs optionally skip creating Cold Start Spans for a comma-separated list of libraries. Useful to limit depth or skip known libraries. Default depends on runtime.
subdomain Set an optional subdomain to use for app URLs which are printed to output. Defaults to app.
enableProfiling Enable the Datadog Continuous Profiler with true. Supported in Beta for NodeJS and Python. Defaults to false.
encodeAuthorizerContext When set to true for Lambda authorizers, the tracing context will be encoded into the response for propagation. Supported for NodeJS and Python. Defaults to true.
decodeAuthorizerContext When set to true for Lambdas that are authorized via Lambda authorizers, it will parse and use the encoded tracing context (if found). Supported for NodeJS and Python. Defaults to true.
apmFlushDeadline Used to determine when to submit spans before a timeout occurs, in milliseconds. When the remaining time in an AWS Lambda invocation is less than the value set, the tracer attempts to submit the current active spans and all finished spans. Supported for NodeJS and Python. Defaults to 100 milliseconds.
mergeStepFunctionAndLambdaTraces When set to true, Lambda traces merge with the calling Step Functions trace. Defaults to false.
enableStepFunctionsTracing Enable automatic subscription of the Datadog Forwarder to Step Function log groups and Step Functions tracing. If no Step Function log groups are configured, then they are automatically created. Requires setting forwarderArn. Defaults to false.
redirectHandlers Optionally disable handler redirection if set to false. This should only be set to false when APM is fully disabled. Defaults to true.
To use any of these parameters, add a custom > datadog section to your serverless.yml similar to this example:
custom:
  datadog:
    apiKeySecretArn: "{Datadog_API_Key_Secret_ARN}"
    enableXrayTracing: false
    enableDDTracing: true
    enableDDLogs: true
    subscribeToAccessLogs: true
    forwarderArn: arn:aws:lambda:us-east-1:000000000000:function:datadog-forwarder
    exclude:
      - dd-excluded-function

Webpack

If you are using a bundler, such as webpack, see Serverless Tracing and Webpack.

TypeScript

You may encounter the error of missing type definitions. To resolve the error, add datadog-lambda-js and dd-trace to the devDependencies list of your project's package.json.

If you are using serverless-typescript, make sure that serverless-datadog is above the serverless-typescript entry in your serverless.yml. The plugin will automatically detect .ts files.

plugins:
  - serverless-plugin-datadog
  - serverless-typescript

Disable Plugin for Particular Environment

If you'd like to turn off the plugin based on the environment (passed via --stage), you can use something similar to the example below.

provider:
  stage: ${self:opt.stage, 'dev'}

custom:
  staged: ${self:custom.stageVars.${self:provider.stage}, {}}

  stageVars:
    dev:
      dd_enabled: false

  datadog:
    enabled: ${self:custom.staged.dd_enabled, true}

Serverless Monitors

There are seven recommended monitors with default values pre-configured.

Monitor Metrics Threshold Serverless Monitor ID
High Error Rate aws.lambda.errors/aws.lambda.invocations >= 10% high_error_rate
Timeout aws.lambda.duration.max/aws.lambda.timeout >= 1 timeout
Out of Memory aws.lambda.enhanced.out_of_memory > 0 out_of_memory
High Iterator Age aws.lambda.iterator_age.maximum >= 24 hrs high_iterator_age
High Cold Start Rate aws.lambda.enhanced.invocations(cold_start:true)/
aws.lambda.enhanced.invocations
>= 20% high_cold_start_rate
High Throttles aws.lambda.throttles/aws.lambda.invocations >= 20% high_throttles
Increased Cost aws.lambda.enhanced.estimated_cost ↑20% increased_cost

To Enable and Configure a Recommended Serverless Monitor

To create a recommended monitor, you must use its respective serverless monitor ID. Note that you must also set the DATADOG_API_KEY and DATADOG_APP_KEY in your environment.

If you’d like to further configure the parameters for a recommended monitor, you can directly define the parameter values below the serverless monitor ID. Parameters not specified under a recommended monitor will use the default recommended value. The query parameter for recommended monitors cannot be directly modified and will default to using the query valued as defined above; however, you may change the threshold value in query by re-defining it within the options parameter. To delete a monitor, remove the monitor from the serverless.yml template. For further documentation on how to define monitor parameters, see the Datadog Monitors API.

Monitor creation occurs after the function is deployed. In the event that a monitor is unsuccessfully created, the function will still be successfully deployed.

To create a recommended monitor with the default values

Define the appropriate serverless monitor ID without specifying any parameter values

custom:
  datadog:
    addLayers: true
    monitors:
      - high_error_rate:
To configure a recommended monitor
custom:
  datadog:
    addLayers: true
    monitors:
      - high_error_rate:
          name: "High Error Rate with Modified Warning Threshold"
          message: "More than 10% of the function’s invocations were errors in the selected time range. Notify @[email protected] @slack-serverless-monitors"
          tags: ["modified_error_rate", "serverless", "error_rate"]
          require_full_window: true
          priority: 2
          options:
            include_tags: true
            notify_audit: true
            thresholds:
              ok: 0.025
              warning: 0.05
              critical: 0.1
To delete a monitor

Removing the serverless monitor ID and its parameters will delete the monitor.

To Enable and Configure a Custom Monitor

To define a custom monitor, you must define a unique serverless monitor ID string in addition to passing in the API key and Application key, DATADOG_API_KEY and DATADOG_APP_KEY, in your environment. The query parameter is required but every other parameter is optional. Define a unique serverless monitor ID string and specify the necessary parameters below. For further documentation on monitor parameters, see the Datadog Monitors API.

custom:
  datadog:
    addLayers: true
    monitors:
      - custom_monitor_id:
          name: "Custom Monitor"
          query: "max(next_1w):forecast(avg:system.load.1{*}, 'linear', 1, interval='60m', history='1w', model='default') >= 3"
          message: "Custom message for custom monitor. Notify @[email protected] @slack-serverless-monitors"
          tags: ["custom_monitor", "serverless"]
          priority: 3
          options:
            enable_logs_sample: true
            require_full_window: true
            include_tags: false
            notify_audit: true
            notify_no_data: false
            thresholds:
              ok: 1
              warning: 2
              critical: 3

Breaking Changes

v5.0.0

  • When used in conjunction with the Datadog Extension, this plugin sets service and env tags through environment variables instead of Lambda resource tags.
  • The enableTags parameter was replaced by the new service, env parameters.

v4.0.0

  • The Datadog Lambda Extension is now the default mechanism for transmitting telemetry to Datadog.

Working with serverless-plugin-warmup

This library is compatible at best effort with serverless-plugin-warmup. If you want to exclude the warmer function from Datadog, use the exclude feature of this library.

To properly package your application, this plugin must be listed after serverless-plugin-warmup in your serverless.yml file:

plugins:
  - serverless-plugin-warmup
  - serverless-plugin-datadog

Opening Issues

If you encounter a bug with this package, let us know by filing an issue! Before opening a new issue, please search the existing issues to avoid duplicates.

When opening an issue, include your Serverless Framework version, Python/Node.js version, and stack trace if available. Also, please include the steps to reproduce when appropriate.

You can also open an issue for a feature request.

Contributing

If you find an issue with this package and have a fix, open a pull request following the procedures.

Community

For product feedback and questions, join the #serverless channel in the Datadog community on Slack.

License

Unless explicitly stated otherwise, all files in this repository are licensed under the Apache License Version 2.0.

This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2021 Datadog, Inc.

serverless-plugin-datadog's People

Contributors

adambartholomew avatar agocs avatar astuyve avatar czechh avatar darcyraynerdd avatar dependabot[bot] avatar duncanista avatar duncanpharvey avatar dylanlovescoffee avatar hannahqjiang avatar hghotra avatar hjiang27 avatar ivantopolcic avatar jcstorms1 avatar joeyzhao2018 avatar jybp avatar kimi-p avatar lironer avatar lizapressman avatar maxday avatar nhinsch avatar nhulston avatar nine5two7 avatar purple4reina avatar romainmuller avatar rpelliard avatar sfirrin avatar thedavl avatar tianchu avatar zarodz11z avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

serverless-plugin-datadog's Issues

Plugin does not work when packaging individual python ƛ

Expected Behavior

Datadog handler should be added to lambdas when packaging individual functions in Serverless.

Actual Behavior

The plugin adds the handler to the first archive that is created but not the final one used to actually deploy to aws. It happens when we use that option in Serverless.yaml:

package:
  individually: true

The plugin probably needs to add more hooks when lambdas are packaged individually.

Steps to Reproduce the Problem

  1. clone branch https://github.com/cscetbon/sls-dd-missing-folder/tree/dd
  2. run sls package
  3. check content of archive .serverless/f1.zip
unzip -l .serverless/f1.zip
Archive:  .serverless/f1.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
      148  01-01-1980 00:00   datadog_handlers/f1.py
      116  01-01-1980 00:00   f1/handler.py
---------                     -------
      264                     2 files
  1. check content of archive .serverless/f1-sls-dd-missing-folder-dev-f1.zip
unzip -l .serverless/f1-sls-dd-missing-folder-dev-f1.zip 
Archive:  .serverless/f1-sls-dd-missing-folder-dev-f1.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
      116  01-01-2098 00:00   handler.py
---------                     -------
      116                     1 file

Specifications

  • Serverless Framework version: 1.70.1
  • Datadog Serverless Plugin version: 0.26.0
  • Lambda function runtime (Python 3.7, Node 10, etc.): Python 3.7

Go support lambda extension

Hello,

Per Datadog engineering team, the lambda extension is now supporting Go.
We used this plugin with Go successfully so far.

But, using addExtension doesn't add a layer on a Go lambda function.
And, using the log forwarder works correctly but doesn't report the metrics correctly.

Any thoughts on this?

Thanks

Request: Support log groups with an existing subscription

Expected Behavior

That log groups with only one unknown subscription would still allow a subscription to the datadog forwarder to be created

Somewhat recently, cloudwatch was updated to allow two parallel subscriptions on a log group: https://aws.amazon.com/about-aws/whats-new/2020/10/amazon-cloudwatch-logs-now-supports-two-subscription-filters-per-log-group/. This should make it OK for the plugin to find only one unknown subscription and still create a subscription for the datadog forwarder

Actual Behavior

If the log group has any unknown subscription at all, the plugin will not create one.

Steps to Reproduce the Behaviour

  1. Create a lambda function and deploy it with a log group subscription to something other than the datadog forwarder
  2. Add the datadog serverless plugin to the serverless.yml and configure it to forward logs to an existing datadog forwarder lambda
  3. You will get a message when deploying saying Subscription already exists for log group [insert log group name]. Skipping subscribing Datadog forwarder and the datadog forwarder subscription will not be created

It seems right to me that this would be supported now, would be curious to hear if there are any concerns or reservations around this. Happy to make a PR if it's not a problem to just change the requirements for creating a subscription from "As long as the log group doesn't have an unknown subscription" to "As long as the log group doesn't have 2 unknown subscriptions"

Don't validate the forwarder ARN when using the sls package command

Expected Behavior

I would like to call sls package to validate that that lambdas can be packaged and IaC generated without requiring credentials to an AWS account that will be used with sls deploy.

This is something that's useful if the build environment is separated from the deployment environment, and for almost all resources other than the custom.datadog.forwarderArn it works, and validation usually is at most on the form of an ARN. In this style, I would usually use a placeholder value like this one for the forwarder ARN: arn:aws:lambda:us-east-1:012345678901:function:placeholder.

Packages produced this way wouldn't deploy, but they would produce CloudFormation that passes for the aws cloudformation validate-template command.

Actual Behavior

When I call sls package, if the custom.datadog.forwarderArn is not a real ARN accessible by the current environment, DatadogForwarderNotFoundError is thrown.

Steps to Reproduce the Problem

  1. Specify a placeholder for the custom.datadog.forwarderArn value that's not a real lambda ARN
  2. Attempt to sls package

Specifications

  • Serverless Framework version: "serverless": "2.30.3",
  • Datadog Serverless Plugin version: "serverless-plugin-datadog": "^2.29.0",
  • Lambda function runtime (Python 3.7, Node 10, etc.): Node 12

Stacktrace

The output is filtered through sls depending on the debug settings, but the throw originates here

throw new DatadogForwarderNotFoundError(`Could not perform GetFunction on ${functionArn}.`);

TCP Connection error on cold starts by datadog-lambda-js

Expected Behavior

I would expect my services not to throw errors in every cold start execution.

Actual Behavior

Every time the lambda execution has a cold start https://github.com/DataDog/datadog-lambda-js will try to check if the agent is running by making a request to 127.0.0.1:8124/lambda/hello which fails and throws an error of connection refused but the rest of the execution is successful.

This is polluting the traces with a lot of false errors.

Specifications

  • Serverless Framework version: ^2.8.0
  • Datadog Serverless Plugin version: 2.7.0
  • Lambda function runtime node12

Stacktrace

Error: connect ECONNREFUSED 127.0.0.1:8124
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1107:14)  

Plugin forwarder doesn't work with newly created serverless log group

Expected Behavior

It should work even on new log group

Actual Behavior

It is having error when a new function is added and new log group is created.

Steps to Reproduce the Problem

  1. Attach arn to forwarder property
  2. Remove subscription filter form existing lambda
  3. Deploy successfully
  4. Create a new function which will create a new log group
  5. Deployment failed ( Deployment succeed when removing forwarder property )

Specifications

  • Serverless Framework version: 1.76.1
  • Datadog Serverless Plugin version: 0.26.0
  • Lambda function runtime (Python 3.7, Node 10, etc.): Node

Stacktrace

The following resource(s) failed to create: [ListxxxxLambdaFunction. 

Resource limit exceeded. (Service: AWSLogs; Status Code: 400; Error Code: LimitExceededException; Request ID: xxxx)

addExtension should default to true or readme improvement

Expected Behavior

  • Custom metrics should be sent

Actual Behavior

  • Custom metrics are sent but not reported

Steps to Reproduce the Problem

  1. Use DD forwarder
  2. Send a custom metrics
  3. Look at the dashboard desperately not knowing why the custom metrics are not reported

Specifications

  • Datadog Serverless Plugin version: latest
  • Lambda function runtime (Python 3.7, Node 10, etc.): Go

Summary

Our use case: we were not using the datadog forwarder at first, then we started using it, using flushMetricsToLogs to true and precising the forwarder arn there: forwarderArn. While it improved the performance drastically, we lost all custom metrics. After a lot of back and forth with DD support, our team realized that the custom metrics using cloudwatch logs was deprecated.

https://docs.datadoghq.com/serverless/custom_metrics/

Our changes required to retrieve the metrics:

# BEFORE

datadog:
    addLayers: true
    flushMetricsToLogs: true
    enableXrayTracing: true
    enableDDTracing: true
    enableTags: true
    forwarderArn: ${self:custom.DDForwarder}
    logLevel: "info"
    subscribeToApiGatewayLogs: false
    subscribeToHttpApiLogs: false
    subscribeToWebsocketLogs: false
    site: ${env:DATADOG_SITE}

# AFTER

datadog:
    addLayers: true
    flushMetricsToLogs: true
    enableXrayTracing: true
    enableDDTracing: true
    enableTags: true
    forwarderArn: ${self:custom.DDForwarder}
    logLevel: "info"
    subscribeToApiGatewayLogs: false
    subscribeToHttpApiLogs: false
    subscribeToWebsocketLogs: false
    site: ${env:DATADOG_SITE}
    addExtension: true
    apiKey: ${env:DATADOG_TOKEN}

Screen Shot 2021-07-12 at 9 32 16 AM

Then my question would, should we not enable addExtension to true or at least could we mention that in the README of this plugin (that with a forwarder and without the extension it doesn't work) ?
We are not sure what is the extension doing so I'm not able to properly assess what should be the decision for the question above.

It took us close to a month to retrieve our metrics, we hope that our learnings and struggle would not be experienced by other teams.

Ability to global enable/disable plugin (so that can be used for different envs)

Expected Behavior

Want to be able to disable plugin activity (function rewriting etc) for certain envs (eg. personal stacks)

Actual Behavior

Currently, having this kind of config results in a successful deployment via sls deploy but functions fail on execution.

dataDogForwarderLambdaArn:
    none: ''
    staging: arn:aws:lambda:us-east-1:blah:function:datadog-ForwarderStack-blah-Forwarder-blah
    prod: arn:aws:lambda:us-east-1:blah:function:datadog-ForwarderStack-blah-Forwarder-blah
  datadogEnabled:
    dev: false
    staging: true
    prod: true
  datadog:
    enableDDTracing: ${self:custom.datadogEnabled.${opt:stackName, 'dev'}, false}
    addLayers: ${self:custom.datadogEnabled.${opt:stackName, 'dev'}, false}
    forwarder: ${self:custom.dataDogForwarderLambdaArn.${opt:stackName, 'none'}, ''}

Functions fail with:

"errorType": "Runtime.ImportModuleError",
    "errorMessage": "Error: Cannot find module 'handler'\nRequire stack:\n- /var/runtime/UserFunction.js\n- /var/runtime/index.js",
    "stack": [
        "Runtime.ImportModuleError: Error: Cannot find module 'handler'",
        "Require stack:",
        "- /var/runtime/UserFunction.js",
        "- /var/runtime/index.js",
        "    at _loadUserApp (/var/runtime/UserFunction.js:100:13)",
        "    at Object.module.exports.load (/var/runtime/UserFunction.js:140:17)",
        "    at Object.<anonymous> (/var/runtime/index.js:43:30)",
        "    at Module._compile (internal/modules/cjs/loader.js:1015:30)",
        "    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1035:10)",
        "    at Module.load (internal/modules/cjs/loader.js:879:32)",
        "    at Function.Module._load (internal/modules/cjs/loader.js:724:14)",
        "    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:60:12)",
        "    at internal/main/run_main_module.js:17:47"
    ]

which I suspect is to do with the plugin "half" doing it's job, eg. having a forwarder with value '' ?

Steps to Reproduce the Problem

Specifications

  • Serverless Framework version: 2.11.1
  • Datadog Serverless Plugin version: 2.10.1
  • Lambda function runtime (Python 3.7, Node 10, etc.): Node 12.19

Note, plugin works as expected for staging & prod stackNames in this config.

Lambda trace logs appearing in CloudWatch/Datadog logs

Hi there!

We're currently seeing trace logs for our serverless Lambda functions emitted into CloudWatch/Datadog logs alongside 'real' logs for our functions. This is resulting in huge log volume, most of which is trace information that is of no interest and makes it harder to access real logs. Note that traces are working for our functions, so we don't want to interfere with that, we just want to prevent the trace information making it into logs. We've isolated this issue to something with this library as the unwanted logs are present in CloudWatch as well as Datadog, so the log forwarder function is working as expected.

Function details

Runtime: nodejs12.x
Serverless framework version: 1.83.0
Serverless Datadog plugin version: 1.1.0

An example trace log
{
    "traces": [
        [
            {
                "trace_id": "xxx",
                "span_id": "xxx",
                "parent_id": "xxx",
                "name": "aws.lambda",
                "resource": "handler",
                "error": 0,
                "meta": {
                    "service": "my-function",
                    "cold_start": "false",
                    "function_arn": "arn:aws:lambda:us-east-1:012345678910:function:my-function",
                    "function_version": "$LATEST",
                    "request_id": "xxx",
                    "resource_names": "my-function",
                    "language": "javascript"
                },
                "metrics": {
                    "_sample_rate": 1,
                    "_sampling_priority_v1": 2
                },
                "start": 1608589168898002000,
                "duration": 10888428,
                "service": "my-function",
                "type": "serverless"
            }
        ]
    ]
}

We don't do much manual instrumentation of our functions for tracing or logging, we mainly rely on the serverless-plugin-datadog library with the following config:

  datadog:
    addLayers: true
    apiKey: xxx
    flushMetricsToLogs: true
    enableTags: true
    forwarder: <datadog-log-forwarder function>

What we've tried

So far we've tried the following on one of our functions currently logging trace information:

  • Setting enableDDTracing = false: this stopped all logging, including real logs
  • Setting injectLogContext = false: this made no difference

Any guidance you can give us on why this might be happening and how we could fix it is greatly appreciated. Let me know if you need any more information from our side.

plugin duplicates all entry files

Background

Because of the way that the DataDog plugin wraps the functions, all of the files are duplicated. Today, this caused my Lambda size to become 3 times the original size. This is especially a problem with serverless-webpack, as each file becomes much larger than usual.

Repository showing issue
https://github.com/dncrews/datadog-serverless-bug#issue-2-multiple-uses-of-a-handler-file-multiplies-the-filesize

Expected Behavior

the file should be re-used.

Actual Behavior

the file is replicated for each different function.

Specifications

  • Serverless Framework version: 1.65.0
  • Datadog Serverless Plugin version: 0.16.0
  • Lambda function runtime: nodejs10.x
  • Serverless Webpack version: 5.2.0

Workaround

The current workaround is to deploy the serverless functions "individually". Unfortunately, this also causes the build to take incrementally longer for each webpack build that it has to perform.

# serverless.yml
package:
  individually: true

Support for multiple regions

Is multiple regions supported by this plugin?

Dev and prod stages run on different regions on AWS and I need to support observability for both stages.

`exclude´ still injects a function handler property, does not work with the new `image` property

Hi there.

I am developing a service where one of our lambdas will be running using a custom ECR image as per AWS's announcement on container image support. The serverless framework supports this in the new 2.15 version and you can now specify image instead of handler per function. If you supply both, it fails, which is expected and wanted behavior.

However, the serverless-plugin-datadog injects a custom handler which makes serverless to fail the validation check before deploying.

I tried to include my function in custom.datadog.exclude but it seems to still inject the handler. I had to make a foo runtime which this plugin does not understand to mitigate the problem.

Expected Behavior

a) exclude does not inject a handler to the function
b) this plugin does not try to inject handlers to functions specified with image and optionally gives a warning

Actual Behavior

Serverless deployment fails with Either "handler" or "image" property (not both) needs to be set on function "convert-docker".

Steps to Reproduce the Problem

  1. add serverless-plugin-datadog to your project
  2. add a new function foo with an image attribute
  3. add foo to custom.datadog.exclude

Specifications

  • Serverless Framework version: 2.15.0
  • Datadog Serverless Plugin version: 2.9.0
  • Lambda function runtime (Python 3.7, Node 10, etc.): n/a

Let me know what you think! Future plans and discussions for helping users with datadog integrations in docker containers in AWS lambda would also be really interesting.

The Datadog-Node10-x:29 lambda layer might not have the right access policy

Expected Behavior

Upgrading to serverless-plugin-datadog 2.2.2 works

Actual Behavior

It does not work and the error I get contains this information (some account numbers, guids and timestamps elided)

ServerlessError: An error occurred: ProviderLambdaFunction - User: arn:aws:sts::012345678901:assumed-role/admin/aws-sdk-js-1598381214288 is not authorized to perform: lambda:GetLayerVersion on resource: arn:aws:lambda:us-east-1:464622532012:layer:Datadog-Node10-x:29 (Service: AWSLambdaInternal; Status Code: 403; Error Code: AccessDeniedException; Request ID: 00000000-0000-0000-0000-000000000000; Proxy: null).

Steps to Reproduce the Problem

  1. Upgrade a project to use serverless-plugin-datadog 2.2.2 and try to deploy with my AWS credentials (sorry, but honest)

Specifications

  • Serverless Framework version: "serverless": "^1.79.0",
  • Datadog Serverless Plugin version: "serverless-plugin-datadog": "^2.2.2",
  • Lambda function runtime (Python 3.7, Node 10, etc.): 10

Stacktrace

Some account numbers, guids, timestamps, and paths elided

ServerlessError: An error occurred: ProviderLambdaFunction - User: arn:aws:sts::012345678901:assumed-role/admin/aws-sdk-js-1598381214288 is not authorized to perform: lambda:GetLayerVersion on resource: arn:aws:lambda:us-east-1:464622532012:layer:Datadog-Node10-x:29 (Service: AWSLambdaInternal; Status Code: 403; Error Code: AccessDeniedException; Request ID: 00000000-0000-0000-0000-000000000000; Proxy: null).
    at C:\service\node_modules\serverless\lib\plugins\aws\lib\monitorStack.js:125:33
From previous event:
    at AwsDeploy.monitorStack (C:\service\node_modules\serverless\lib\plugins\aws\lib\monitorStack.js:28:12)  
    at C:\service\node_modules\serverless\lib\plugins\aws\lib\updateStack.js:134:28
From previous event:
    at AwsDeploy.update (C:\service\node_modules\serverless\lib\plugins\aws\lib\updateStack.js:134:8)
From previous event:
    at AwsDeploy.<anonymous> (C:\service\node_modules\serverless\lib\plugins\aws\lib\updateStack.js:148:35)   
From previous event:
    at AwsDeploy.updateStack (C:\service\node_modules\serverless\lib\plugins\aws\lib\updateStack.js:144:33)   
From previous event:
    at AwsDeploy.<anonymous> (C:\service\node_modules\serverless\lib\plugins\aws\deploy\index.js:127:39)      
From previous event:
    at Object.aws:deploy:deploy:updateStack [as hook] (C:\service\node_modules\serverless\lib\plugins\aws\deploy\index.js:123:30)
    at C:\service\node_modules\serverless\lib\classes\PluginManager.js:489:55
From previous event:
    at PluginManager.invoke (C:\service\node_modules\serverless\lib\classes\PluginManager.js:489:22)
    at PluginManager.spawn (C:\service\node_modules\serverless\lib\classes\PluginManager.js:509:17)
    at AwsDeploy.<anonymous> (C:\service\node_modules\serverless\lib\plugins\aws\deploy\index.js:93:48)       
From previous event:
    at Object.deploy:deploy [as hook] (C:\service\node_modules\serverless\lib\plugins\aws\deploy\index.js:89:30)
    at C:\service\node_modules\serverless\lib\classes\PluginManager.js:489:55
From previous event:
    at PluginManager.invoke (C:\service\node_modules\serverless\lib\classes\PluginManager.js:489:22)
    at C:\service\node_modules\serverless\lib\classes\PluginManager.js:524:24
From previous event:
    at PluginManager.run (C:\service\node_modules\serverless\lib\classes\PluginManager.js:524:8)
    at C:\service\node_modules\serverless\lib\Serverless.js:136:33
From previous event:
    at Serverless.run (C:\service\node_modules\serverless\lib\Serverless.js:123:74)
    at C:\service\node_modules\serverless\scripts\serverless.js:54:26
    at processImmediate (internal/timers.js:456:21)
    at process.topLevelDomainCallback (domain.js:137:15)
From previous event:
    at Object.<anonymous> (C:\service\node_modules\serverless\scripts\serverless.js:54:4)
    at Module._compile (internal/modules/cjs/loader.js:1133:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1153:10)
    at Module.load (internal/modules/cjs/loader.js:977:32)
    at Function.Module._load (internal/modules/cjs/loader.js:877:14)
    at Module.require (internal/modules/cjs/loader.js:1019:19)
    at require (internal/modules/cjs/helpers.js:77:18)
    at Object.<anonymous> (C:\service\node_modules\serverless\bin\serverless.js:41:1)
    at Module._compile (internal/modules/cjs/loader.js:1133:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1153:10)
    at Module.load (internal/modules/cjs/loader.js:977:32)
    at Function.Module._load (internal/modules/cjs/loader.js:877:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:74:12)
    at internal/main/run_main_module.js:18:47

plugin does not function with serverless dashboard

Expected Behavior

serverless-plugin-datadog functions correctly and applies the datadog layer, but serverless dashboard pieces also work.

Actual Behavior

[ERROR] AttributeError: module 'app' has no attribute 'handler'
Traceback (most recent call last):
  File "/var/task/serverless_sdk/__init__.py", line 107, in wrapped_handler
    return user_handler(event, context)
  File "/var/task/s_app.py", line 19, in error_handler
    raise e
  File "/var/task/s_app.py", line 14, in <module>
    user_handler = serverless_sdk.get_user_handler('datadog_handlers/app.handler')
  File "/var/task/serverless_sdk/__init__.py", line 57, in get_user_handler
    return getattr(user_module, user_handler_name)

If you comment out app and org in serverless.yml then the error does not occur and the app functions properly.

Steps to Reproduce the Problem

  1. clone https://github.com/rparsonsbb/flask-dd-serverless-plugin-example
  2. set app, org and custom.datadog.apiKey
  3. sls deploy
  4. attempt to call /quote

Specifications

  • Serverless Framework version:
  Your Environment Information ---------------------------
     Operating System:          linux
     Node Version:              10.16.3
     Framework Version:         1.59.3
     Plugin Version:            3.2.6
     SDK Version:               2.2.1
     Components Core Version:   1.1.2
     Components CLI Version:    1.4.0
  • Datadog Serverless Plugin version: 0.10.0
  • Lambda function runtime (Python 3.7, Node 10, etc.): Python 3.7

Stacktrace

[ERROR] AttributeError: module 'app' has no attribute 'handler'
Traceback (most recent call last):
File "/var/task/serverless_sdk/__init__.py", line 107, in wrapped_handler
  return user_handler(event, context)
File "/var/task/s_app.py", line 19, in error_handler
  raise e
File "/var/task/s_app.py", line 14, in <module>
  user_handler = serverless_sdk.get_user_handler('datadog_handlers/app.handler')
File "/var/task/serverless_sdk/__init__.py", line 57, in get_user_handler
  return getattr(user_module, user_handler_name)

Cannot Read Property Resources

Expected Behavior

Running serverless deploy --function <my_function> should work just the same as running serverless deploy for all functions.

Actual Behavior

Deploying a single function fails serverless deploy --function <my_function>

Additionally I see this error if I do a local invoke

serverless invoke local -f <my_function> -p ./event.json

Is there a way to disable this plugin for these types of invocations / deploys?

Steps to Reproduce the Problem

  1. deploy all your functions by running serverless deploy
  2. now try to deploy a single function `serverless deploy <my_function>

Specifications

  • Serverless Framework version: 1.77.1
  • Datadog Serverless Plugin version: 2.2.1
  • Lambda function runtime (Python 3.7, Node 10, etc.): nodejs12.x

Stacktrace

  TypeError: Cannot read property 'Resources' of undefined
      at Object.<anonymous> (/Users/davidfox-powell/dev/good-rx/cross-origin-ab-test/node_modules/serverless-plugin-datadog/src/forwarder.ts:31:69)
      at Generator.next (<anonymous>)
      at /Users/davidfox-powell/dev/good-rx/cross-origin-ab-test/node_modules/serverless-plugin-datadog/dist/forwarder.js:8:71
      at new Promise (<anonymous>)
      at __awaiter (/Users/davidfox-powell/dev/good-rx/cross-origin-ab-test/node_modules/serverless-plugin-datadog/dist/forwarder.js:4:12)
      at Object.addCloudWatchForwarderSubscriptions (/Users/davidfox-powell/dev/good-rx/cross-origin-ab-test/node_modules/serverless-plugin-datadog/dist/forwarder.js:19:12)
      at ServerlessPlugin.<anonymous> (/Users/davidfox-powell/dev/good-rx/cross-origin-ab-test/node_modules/serverless-plugin-datadog/src/index.ts:91:28)
      at Generator.next (<anonymous>)
      at /Users/davidfox-powell/dev/good-rx/cross-origin-ab-test/node_modules/serverless-plugin-datadog/dist/index.js:34:71
      at new Promise (<anonymous>)
      at __awaiter (/Users/davidfox-powell/dev/good-rx/cross-origin-ab-test/node_modules/serverless-plugin-datadog/dist/index.js:30:12)
      at ServerlessPlugin.afterPackageFunction (/Users/davidfox-powell/dev/good-rx/cross-origin-ab-test/node_modules/serverless-plugin-datadog/dist/index.js:110:16)
      at /Users/davidfox-powell/dev/good-rx/cross-origin-ab-test/node_modules/serverless/lib/classes/PluginManager.js:483:55
      at tryCatcher (/Users/davidfox-powell/dev/good-rx/cross-origin-ab-test/node_modules/bluebird/js/release/util.js:16:23)
      at Object.gotValue (/Users/davidfox-powell/dev/good-rx/cross-origin-ab-test/node_modules/bluebird/js/release/reduce.js:168:18)
      at Object.gotAccum (/Users/davidfox-powell/dev/good-rx/cross-origin-ab-test/node_modules/bluebird/js/release/reduce.js:155:25)
      at Object.tryCatcher (/Users/davidfox-powell/dev/good-rx/cross-origin-ab-test/node_modules/bluebird/js/release/util.js:16:23)
      at Promise._settlePromiseFromHandler (/Users/davidfox-powell/dev/good-rx/cross-origin-ab-test/node_modules/bluebird/js/release/promise.js:547:31)
      at Promise._settlePromise (/Users/davidfox-powell/dev/good-rx/cross-origin-ab-test/node_modules/bluebird/js/release/promise.js:604:18)
      at Promise._settlePromise0 (/Users/davidfox-powell/dev/good-rx/cross-origin-ab-test/node_modules/bluebird/js/release/promise.js:649:10)
      at Promise._settlePromises (/Users/davidfox-powell/dev/good-rx/cross-origin-ab-test/node_modules/bluebird/js/release/promise.js:729:18)
      at _drainQueueStep (/Users/davidfox-powell/dev/good-rx/cross-origin-ab-test/node_modules/bluebird/js/release/async.js:93:12)
      at _drainQueue (/Users/davidfox-powell/dev/good-rx/cross-origin-ab-test/node_modules/bluebird/js/release/async.js:86:9)
      at Async._drainQueues (/Users/davidfox-powell/dev/good-rx/cross-origin-ab-test/node_modules/bluebird/js/release/async.js:102:5)
      at Immediate.Async.drainQueues (/Users/davidfox-powell/dev/good-rx/cross-origin-ab-test/node_modules/bluebird/js/release/async.js:15:14)
      at processImmediate (internal/timers.js:456:21)
      at process.topLevelDomainCallback (domain.js:137:15)

Problem with deploy service using Sub function to to build forwarder arn

Expected Behavior

When I run sls package gets an error, lambda function exists on environment, I used before serverless-pseudo-parameters to construct forwarder arn and it worked.

datadog:
    forwarder: "arn:aws:lambda:#{AWS::Region}:#{AWS::AccountId}:function:datadog-logs-forwarder"

But this package is deprecated, this functionality is now natively supported in Serverless Framework.
So I try to use Sub function

datadog:
    forwarder: !Sub "arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:datadog-logs-forwarder"

Actual Behavior

When I try to package my service I get an error using Sub(CloudFormation) function to build forwarder arn

Steps to Reproduce the Problem

  1. Setup serverless framework environment
  2. Deploy forwarder
  3. Try to deploy (separate service) your service using Sub function to build forwarder arn

Specifications

  • Serverless Framework version: 2.22.0
  • Datadog Serverless Plugin version: 2.15.0
  • Lambda function runtime (Python 3.7, Node 10, etc.): Node14

Stacktrace

Serverless: Packaging service...
Serverless: [AWS lambda undefined 0.021s 0 retries] getFunction({
FunctionName: {
  'Fn::Sub': 'arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:datadog-logs-forwarder'
}
})

Datadog Forwarder Not Found Error ----------------------

DatadogForwarderNotFoundError: Could not perform GetFunction on [object Object].
    at /home/runner/work/my-service/my-service/node_modules/serverless-plugin-datadog/src/forwarder.ts:48:11
    at Generator.throw (<anonymous>)
    at rejected (/home/runner/work/my-service/my-service/node_modules/serverless-plugin-datadog/dist/src/forwarder.js:6:65)

Get Support --------------------------------------------
   Docs:          docs.serverless.com
   Bugs:          github.com/serverless/serverless/issues
   Issues:        forum.serverless.com

Your Environment Information ---------------------------
   Operating System:          linux
   Node Version:              14.15.4
   Framework Version:         2.22.0 (local)
   Plugin Version:            4.4.2
   SDK Version:               2.3.2
   Components Version:        3.6.2

Error: Process completed with exit code 1.

Cannot read property 'X-Amzn-Trace-Id' of null

Expected Behavior

When logging error using console, it should log error.

Actual Behavior

Instead of logging actual error, it is causing trace-id issue.

Steps to Reproduce the Problem

  1. Throw the error
  2. and log the error using console

Specifications

  • Serverless Framework version:
  • Datadog Serverless Plugin version:
  • Lambda function runtime (Python 3.7, Node 10, etc.):

Stacktrace

Invoke Error	{"errorType":"TypeError","errorMessage":"Cannot read property 'X-Amzn-Trace-Id' of null","stack":["TypeError: Cannot read property 'X-Amzn-Trace-Id' of null","    at /var/task/serverless_sdk/index.js:9:87215","    at /opt/nodejs/node_modules/datadog-lambda-js/utils/handler.js:150:25","    at Object.<anonymous> (/opt/nodejs/node_modules/datadog-lambda-js/index.js:154:62)","    at step (/opt/nodejs/node_modules/datadog-lambda-js/index.js:44:23)","    at Object.next (/opt/nodejs/node_modules/datadog-lambda-js/index.js:25:53)","    at fulfilled (/opt/nodejs/node_modules/datadog-lambda-js/index.js:16:58)"]}  ```

subscribeToApiGatewayLogs: false causes 502 and no logs on dashboard

Expected Behavior

We want to see the function logs on both serverless and datadog, and have a successful execution.

Actual Behavior

Currently our endpoints are giving 502 internal error.

Steps to Reproduce the Problem

  1. Remove log groups of development environment from AWS
  2. Call the endpoints again so log groups get populated
  3. Deploy to development environment with these settings in serverless.yml:
dd_enabled:
    local: false
    development: true
    production: false
datadog:
    enabled: ${self:custom.dd_enabled.${sls:stage}, false}
    site: datadoghq.eu
    forwarder: arn:aws:lambda:eu-central-XXXXXXXXXX
    subscribeToApiGatewayLogs: false
  1. Deployment is successful but we are not seeing any log on Serverless dashboard anymore and we cannot execute the functions due to an internal error in datadog-lambda-js as the last end which is a dependency I guess.
  2. When I remove subscribeToApiGatewayLogs: false, it works.

Specifications

  • Serverless Framework version:
    • Framework Core: 2.51.0
      Plugin: 5.4.3
      SDK: 4.2.3
      Components: 3.13.3
  • Datadog Serverless Plugin version: 2.27.0
  • Lambda function runtime (Python 3.7, Node 10, etc.): Node 14

Stacktrace

{
              "trace_id": "68028eb3864a1576",
              "span_id": "68028eb3864a1576",
              "parent_id": "0000000000000000",
              "name": "aws.lambda",
              "resource": "checkout-api-development-process_create_deal",
              "error": 1,
              "meta": {
                  "_dd.origin": "lambda",
                  "service": "checkout-api-development-process_create_deal",
                  "cold_start": "true",
                  "function_arn": "arn:aws:lambda:eu-central-1:747800237849:XXXXXXXXXXXXXX",
                  "function_version": "$LATEST",
                  "request_id": "ef0f17fa-7b42-4fbd-a31b-140975742c9a",
                  "resource_names": "checkout-api-development-process_create_deal",
                  "datadog_lambda": "3.56.0",
                  "dd_trace": "0.34.0",
                  "function_trigger.event_source": "api-gateway",
                  "function_trigger.event_source_arn": "arn:aws:apigateway:eu-central-1::/restapis/7p608b3ccf/stages/development",
                  "http.url": "dev-api-checkout.finn.auto",
                  "http.url_details.path": "/processDealCreation",
                  "http.method": "POST",
                  "http.status_code": "502",
                  "error.type": "TypeError",
                  "error.msg": "Cannot read property 'then' of null",
                  "error.stack": "TypeError: Cannot read property 'then' of null\n    at /opt/nodejs/node_modules/datadog-lambda-js/utils/handler.js:152:57\n    at Object.<anonymous> (/opt/nodejs/node_modules/datadog-lambda-js/index.js:168:62)\n    at step (/opt/nodejs/node_modules/datadog-lambda-js/index.js:44:23)\n    at Object.next (/opt/nodejs/node_modules/datadog-lambda-js/index.js:25:53)\n    at /opt/nodejs/node_modules/datadog-lambda-js/index.js:19:71\n    at new Promise (<anonymous>)\n    at __awaiter (/opt/nodejs/node_modules/datadog-lambda-js/index.js:15:12)\n    at /opt/nodejs/node_modules/datadog-lambda-js/index.js:162:108\n    at /opt/nodejs/node_modules/dd-trace/packages/dd-trace/src/tracer.js:96:56\n    at /opt/nodejs/node_modules/dd-trace/packages/dd-trace/src/tracer.js:47:56\n    at Scope._activate (/opt/nodejs/node_modules/dd-trace/packages/dd-trace/src/scope/async_resource.js:53:14)\n    at Scope.activate (/opt/nodejs/node_modules/dd-trace/packages/dd-trace/src/scope/base.js:12:19)\n    at DatadogTracer.trace (/opt/nodejs/node_modules/dd-trace/packages/dd-trace/src/tracer.js:47:35)\n    at /opt/nodejs/node_modules/dd-trace/packages/dd-trace/src/tracer.js:96:23\n    at Object.<anonymous> (/opt/nodejs/node_modules/datadog-lambda-js/index.js:187:31)\n    at step (/opt/nodejs/node_modules/datadog-lambda-js/index.js:44:23)\n    at Object.next (/opt/nodejs/node_modules/datadog-lambda-js/index.js:25:53)\n    at fulfilled (/opt/nodejs/node_modules/datadog-lambda-js/index.js:16:58)"
              },
              "metrics": {
                  "_dd.agent_psr": 1,
                  "_sample_rate": 1,
                  "_sampling_priority_v1": 1
              },
              "start": 1626345838760067300,
              "duration": 81641113,
              "service": "aws.lambda",
              "type": "serverless"
          }

Unable to use serverless-plugin-datadog when the project uses custom plugins

Expected Behavior

The deployment of a serverless service is successful when command sls deploy is run.

Actual Behavior

Type Error ---------------------------------------------

TypeError: plugins.find is not a function

Steps to Reproduce the Problem

  1. Create a serverless project using the command: serverless create --template aws-nodejs --path your-service
  2. In the serverless.yml file, add:
plugins:
  localPath: "./serverless_plugins"
  modules:
    - serverless-plugin-datadog
    - any-custom-plugin
  1. Deploy: sls deploy

Specifications

  • Serverless Framework version: 1.64.0
  • Datadog Serverless Plugin version: 0.23.0
  • Lambda function runtime (Python 3.7, Node 10, etc.): Node 10

Stacktrace

Serverless: Auto instrumenting functions with Datadog

Type Error ---------------------------------------------

TypeError: plugins.find is not a function
    at Object.hasWebpackPlugin (/Users/userone/development/scratchpad/js/node_modules/serverless-plugin-datadog/src/util.ts:54:18)
    at Object.entries.map (/Users/userone/development/scratchpad/js/node_modules/serverless-plugin-datadog/src/layer.ts:73:15)
    at Array.map (<anonymous>)
    at Object.findHandlers (/Users/userone/development/scratchpad/js/node_modules/serverless-plugin-datadog/src/layer.ts:56:6)
    at ServerlessPlugin.<anonymous> (/Users/userone/development/scratchpad/js/node_modules/serverless-plugin-datadog/src/index.ts:69:22)
    at Generator.next (<anonymous>)
    at /Users/userone/development/scratchpad/js/node_modules/serverless-plugin-datadog/dist/index.js:15:71
    at new Promise (<anonymous>)
    at __awaiter (/Users/userone/development/scratchpad/js/node_modules/serverless-plugin-datadog/dist/index.js:11:12)
    at ServerlessPlugin.beforeDeployFunction (/Users/userone/development/scratchpad/js/node_modules/serverless-plugin-datadog/dist/index.js:66:16)
    at BbPromise.reduce (/usr/local/lib/node_modules/serverless/lib/classes/PluginManager.js:490:55)
    at tryCatcher (/usr/local/lib/node_modules/serverless/node_modules/bluebird/js/release/util.js:16:23)
    at Object.gotValue (/usr/local/lib/node_modules/serverless/node_modules/bluebird/js/release/reduce.js:168:18)
    at Object.gotAccum (/usr/local/lib/node_modules/serverless/node_modules/bluebird/js/release/reduce.js:155:25)
    at Object.tryCatcher (/usr/local/lib/node_modules/serverless/node_modules/bluebird/js/release/util.js:16:23)
    at Promise._settlePromiseFromHandler (/usr/local/lib/node_modules/serverless/node_modules/bluebird/js/release/promise.js:547:31)
    at Promise._settlePromise (/usr/local/lib/node_modules/serverless/node_modules/bluebird/js/release/promise.js:604:18)
    at Promise._settlePromise0 (/usr/local/lib/node_modules/serverless/node_modules/bluebird/js/release/promise.js:649:10)
    at Promise._settlePromises (/usr/local/lib/node_modules/serverless/node_modules/bluebird/js/release/promise.js:729:18)
    at _drainQueueStep (/usr/local/lib/node_modules/serverless/node_modules/bluebird/js/release/async.js:93:12)
    at _drainQueue (/usr/local/lib/node_modules/serverless/node_modules/bluebird/js/release/async.js:86:9)
    at Async._drainQueues (/usr/local/lib/node_modules/serverless/node_modules/bluebird/js/release/async.js:102:5)
    at Immediate.Async.drainQueues (/usr/local/lib/node_modules/serverless/node_modules/bluebird/js/release/async.js:15:14)
    at runCallback (timers.js:705:18)

Plugin doesn't create policy for the DD_FETCH_LAMBDA_TAGS

Expected Behavior

Since the release aws-dd-forwarder-3.2.0 of the lambda forwarder, it's possible to get the lambda function tags.

However, in order to do this you need to add the tag:GetResources permission to the the lambda functions.

See the datadog documentation here : https://docs.datadoghq.com/integrations/amazon_lambda/?tab=awsconsole#enabling-enhanced-real-time-lambda-metrics

So the expected behaviour would be to automatically add this permission to all the lambda if the we choose the DD_FETCH_LAMBDA_TAGS

Actual Behavior

The permission is not added, and the lambda forwarder cannot get the lambda functions tags in the logs

Steps to Reproduce the Problem

  1. Have the lambda forwarder with DD_FETCH_LAMBDA_TAGS set to true
  2. Use this plugin for logs
  3. Check you function logs in datadog, the tags are missing

Specifications

  • Serverless Framework version: 1.60.1
  • Datadog Serverless Plugin version: latest
  • Lambda function runtime (Python 3.7, Node 10, etc.): Node 10

Unable to build / test / contribute

Expected Behavior

I was going to make a PR contribution to this project, but I was unable to build and test the changes.

Failure are related to not being able to generate a layers.json file. Not having this file blocks both the build and the test runner.

Actual Behavior

User should be able to contribute following posted guidelines in markdown readme.

Steps to Reproduce the Problem

  1. Fork and clone the repo
  2. Install yarn dependencies
  3. Attempt to run the build - informed you must run generate_layers_json.sh
  4. Run ./scripts/generate_layers_json.sh
  5. Unable to poll layers

image

Specifications

  • Serverless Framework version: N/A
  • Datadog Serverless Plugin version: master
  • Lambda function runtime (Python 3.7, Node 10, etc.): node 12

Stacktrace

N/A

DataDog Serverless Plugin Does Not Allow For Idempotency with Webpack-based Services

Expected Behavior

A deployment artifact created with serverless package can be deployed using serverless deploy to ensure idempotent service deployments. This process worked fine before adding the plugin and its dependencies ("aws-xray-sdk": "^3.0.1", "datadog-lambda-js": "^2.23.0", "dd-trace": "^0.20.3")

Actual Behavior

After creating a package using serverless package, unzipping the package in a clean directory with only the essential files, and then running sls deploy the package fails to deploy with the error shown in the Stacktrace section.

From inspecting the files before and after sls deploy is ran: Before running, the files under datadog_handlers appear to be compiled by webpack. However, after running deploy, the files appear to be their original plugin-generated versions, trying to reference the other uncompiled source.

I believe these files get overridden as a result of the serverless plugin-initialization/run phase during deploy, i.e. the first two steps in this output:

/tmp -> npx sls deploy --stage test
Serverless: Auto instrumenting functions with Datadog
Serverless: Adding Lambda Layers to functions
Serverless: Bundling with Webpack...
Time: 1300ms

Steps to Reproduce the Problem

  1. In your serverless directory, run serverless package --stage <stage>. When finished, a .zip file should be created under the .serverless folder within the same directory you ran serverless package.
  2. Copy the .zip folder into a new directory.
  3. Copy over any needed files. In my case, I also needed to copy over serverless.yml serverless.<stage>.yml source-map-install.js tsconfig.json webpack.config.js
  4. Run serverless deploy --stage <stage>

Specifications

  • Serverless Framework version: 1.62.0
  • Datadog Serverless Plugin version: 0.26.0
  • Lambda function runtime (Python 3.7, Node 10, etc.): nodejs10.x

Stacktrace

309 | Serverless: Auto instrumenting functions with Datadog
310 | Serverless: Adding Lambda Layers to functions
311 | Serverless: Bundling with Webpack...
312 | Time: 76ms
313 | Built at: 05/15/2020 8:53:01 PM
314 | Asset      Size  Chunks  Chunk Names
315 | datadog_handlers/customAuthorizer.js  4.87 KiB       0  datadog_handlers/customAuthorizer
316 | datadog_handlers/getData.js  4.84 KiB       1  datadog_handlers/getData
317 | Entrypoint datadog_handlers/customAuthorizer = datadog_handlers/customAuthorizer.js
318 | Entrypoint datadog_handlers/getData = datadog_handlers/getData.js
319 | [0] ./source-map-install.js 41 bytes {0} {1} [built]
320 | [1] external "source-map-support" 42 bytes {0} {1} [built]
321 | [2] external "dd-trace" 42 bytes {0} {1} [built]
322 | [3] external "datadog-lambda-js" 42 bytes {0} {1} [built]
323 | [4] multi ./source-map-install.js ./datadog_handlers/customAuthorizer.js 40 bytes {0} [built]
324 | [5] ./datadog_handlers/customAuthorizer.js 263 bytes {0} [built]
325 | [6] multi ./source-map-install.js ./datadog_handlers/getData.js 40 bytes {1} [built]
326 | [7] ./datadog_handlers/getData.js 239 bytes {1} [built]
327 |  
328 | ERROR in ./datadog_handlers/customAuthorizer.js
329 | Module not found: Error: Can't resolve '../src/handlers/api/custom-authorizer/handler' in '/codebuild/output/src864296957/src/datadog_handlers'
330 | @ ./datadog_handlers/customAuthorizer.js 4:0-74 6:34-53
331 | @ multi ./source-map-install.js ./datadog_handlers/customAuthorizer.js
332 |  
333 | ERROR in ./datadog_handlers/getData.js
334 | Module not found: Error: Can't resolve '../src/handlers/api/handler' in '/codebuild/output/src864296957/src/datadog_handlers'
335 | @ ./datadog_handlers/getData.js 4:0-56 6:31-47
336 | @ multi ./source-map-install.js ./datadog_handlers/getData.js

ES2015 default imports are incorrectly patched

After enabling this plugin I get Cannot set property 'default' of undefined" error in all functions that use handler.default reference in serverles.yml

Steps to Reproduce the Problem

  1. Create a simple sls function with handler: myFunc/handler.default
  2. Add serverless-plugin-datadog

Specifications

  • Serverless Framework version: 1.57.0
  • Datadog Serverless Plugin version: 0.7.0
  • Lambda function runtime: Node 10.x

Stacktrace

{
errorType: "TypeError",
errorMessage: "Cannot set property 'default' of undefined",
stack: [
  "TypeError: Cannot set property 'default' of undefined",
  "    at Module.<anonymous> (/var/task/datadog_handlers/webpack:/datadog_handlers/updateAppStatisticsHook.js:3:1)",
  "    at Module.<anonymous> (/var/task/datadog_handlers/updateAppStatisticsHook.js:96722:30)",
  "    at __webpack_require__ (/var/task/datadog_handlers/webpack:/webpack/bootstrap:19:1)",
  "    at /var/task/datadog_handlers/webpack:/webpack/bootstrap:83:1",
  "    at Object.<anonymous> (/var/task/datadog_handlers/updateAppStatisticsHook.js:87:10)",
  "    at Module._compile (internal/modules/cjs/loader.js:778:30)",
  "    at Object.Module._extensions..js (internal/modules/cjs/loader.js:789:10)",
  "    at Module.load (internal/modules/cjs/loader.js:653:32)",
  "    at tryModuleLoad (internal/modules/cjs/loader.js:593:12)",
  "    at Function.Module._load (internal/modules/cjs/loader.js:585:3)",
  "    at Module.require (internal/modules/cjs/loader.js:692:17)",
  "    at require (internal/modules/cjs/helpers.js:25:18)",
  "    at _tryRequire (/var/runtime/UserFunction.js:75:12)",
  "    at _loadUserApp (/var/runtime/UserFunction.js:95:12)",
  "    at Object.module.exports.load (/var/runtime/UserFunction.js:140:17)",
  "    at Object.<anonymous> (/var/runtime/index.js:45:30)"
]
}

failed to send traces to Datadog Agent at http://localhost:8126

Expected Behavior

send log in aws cloudwatch to dataDog

provider: aws
runtime: python3.6
plugins:

  • serverless-python-requirements
  • serverless-wsgi
  • serverless-dynamodb-local
  • serverless-plugin-datadog
    custom:
    datadog:
    addExtension: true
    apiKey: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Actual Behavior

failed to send traces to Datadog Agent at http://localhost:8126

Steps to Reproduce the Problem

  1. sls deploy --stage dev --config config/serverless.dev.yml
  2. test endpoints apiGetway method get exp. "url/getuser"
  3. goto aws cloudwatch view log

Specifications

  • Serverless Framework version: 2
  • Datadog Serverless Plugin version: "^2.29.0"
  • Lambda function runtime: Python 3.6

Stacktrace

service: serverless-flask

plugins:
- serverless-python-requirements
- serverless-wsgi
- serverless-dynamodb-local
- serverless-plugin-datadog

package:
exclude:
  - node_modules/**
  - venv/**

custom:
datadog:
  addExtension: true
  apiKey: xxxxxxxxxxxxxxxxxx
  addLayers: true
  logLevel: "info"
  enableDDTracing: true
  enableDDLogs: true
  enableTags: true
  injectLogContext: true
  site: "datadoghq.com"
tableName: 'users-table-${self:provider.stage}'
wsgi:
  app: app.app
  packRequirements: false
pythonRequirements:
  dockerizePip: non-linux
dynamodb:
  start:
    migrate: true
  stages:
    - dev

provider:
name: aws
runtime: python3.6
stage: dev
profile: xxxxx
region: us-east-1
iamRoleStatements:
  - Effect: Allow
    Action:
      - dynamodb:Query
      - dynamodb:Scan
      - dynamodb:GetItem
      - dynamodb:PutItem
      - dynamodb:UpdateItem
      - dynamodb:DeleteItem
    Resource:
      - { "Fn::GetAtt": [ "UsersDynamoDBTable", "Arn" ] }
environment:
  USERS_TABLE: ${self:custom.tableName}
  STATE_MANUAL: ${self:provider.stage}

functions:
app:
  handler: wsgi.handler
  events:
    - http: ANY /
    - http: 'ANY {proxy+}'
getUser:
  handler: wsgi.handler
  events:
    - http: 'GET /users/{proxy+}'
createUser:
  handler: wsgi.handler
  events:
    - http: 'POST /users'

resources:
Resources:
  UsersDynamoDBTable:
    Type: 'AWS::DynamoDB::Table'
    Properties:
      AttributeDefinitions:
        -
          AttributeName: userId
          AttributeType: S
      KeySchema:
        -
          AttributeName: userId
          KeyType: HASH
      ProvisionedThroughput:
        ReadCapacityUnits: 1
        WriteCapacityUnits: 1
      TableName: ${self:custom.tableName}

Can not use forwarder when stackname is set

Expected Behavior

Set Cloudwatch log group subscription when forwarder ARN is provided

Actual Behavior

When stackname and datadog forwarder Serverless parameters are set, during the first deployment, subscription is well configured but in the second deployment subscription is removed.

expectedSubName is not the same when stackname is defined

Steps to Reproduce the Problem

  1. put a stackname and add the datadog forwrader arn to the forwarder parameter
provider:
  name: aws
  stackName: ${opt:stage}-datadog-forwarder
  runtime: nodejs12.x

custom:
  datadog:
    flushMetricsToLogs: true
    enableDDTracing: true
    enableTags: true
    forwarder: arn:aws:lambda:region:account_id:function:datadog-forwarder-Forwarder-xxx
  1. deploy it
❯ sls deploy --stage test-arnaud --region us-west-2
Serverless: Auto instrumenting functions with Datadog
Serverless: Adding Lambda Layers to functions
Serverless: Packaging service...
Serverless: Excluding development dependencies...
Serverless: Adding service and environment tags to functions
Serverless: Creating Stack...
Serverless: Checking Stack create progress...
........
Serverless: Stack create finished...
Serverless: Uploading CloudFormation file to S3...
Serverless: Uploading artifacts...
Serverless: Uploading service foo.zip file to S3 (29.86 KB)...
Serverless: Validating template...
Serverless: Updating Stack...
Serverless: Checking Stack update progress...
..................
Serverless: Stack update finished...
Service Information
service: foo
stage: test-arnaud
region: us-west-2
stack: bar
resources: 7
api keys:
  None
endpoints:
  None
functions:
  hello: foo-test-arnaud-hello
layers:
  None
  1. redeploy it with a change
❯ sls deploy --stage test-arnaud --region us-west-2
Serverless: Auto instrumenting functions with Datadog
Serverless: Adding Lambda Layers to functions
Serverless: Packaging service...
Serverless: Excluding development dependencies...
filter name : bar-HelloLogGroupSubscription-13VEY3OKXIRT0, expectedSubName : foo-test-arnaud-HelloLogGroupSubscription-
Serverless: Subscription already exists for log group /aws/lambda/foo-test-arnaud-hello. Skipping subscribing Datadog forwarder.
Serverless: Adding service and environment tags to functions
Serverless: Uploading CloudFormation file to S3...
Serverless: Uploading artifacts...
Serverless: Uploading service foo.zip file to S3 (29.86 KB)...
Serverless: Validating template...
Serverless: Updating Stack...
Serverless: Checking Stack update progress...
.......
Serverless: Stack update finished...
Service Information
service: foo
stage: test-arnaud
region: us-west-2
stack: bar
resources: 6
api keys:
  None
endpoints:
  None
functions:
  hello: foo-test-arnaud-hello
layers:
  None

And you will see Subscription already exists

The filter name : bar-HelloLogGroupSubscription-13VEY3OKXIRT0, expectedSubName : foo-test-arnaud-HelloLogGroupSubscription- came from a console.log. filter and expectedSubName does not match.

Specifications

  • Serverless Framework version: 1.80.0
  • Datadog Serverless Plugin version: 2.3.0
  • Lambda function runtime: nodejs12.x

plugin does not work correctly with webpack

Background

Per the serverless-webpack documentation, since aws-sdk is included in all Lambdas, you should exclude it. The expected way to do this is

# serverless.yml
custom:
  webpack:
    includeModules:
      forceExclude:
        - aws-sdk

Repository showing issue
https://github.com/dncrews/datadog-serverless-bug#issue-1-does-not-properly-exclude-aws-sdk

Expected Behavior

aws-sdk should be excluded

Actual Behavior

aws-sdk is included

Specifications

  • Serverless Framework version: 1.65.0
  • Datadog Serverless Plugin version: 0.16.0
  • Lambda function runtime: nodejs10.x
  • Serverless Webpack version: 5.2.0

Error on deployment of single function via `serverless deploy function -f functionName`

Expected Behavior

Deploying a function via node ./node_modules/.bin/serverless deploy -f functionName should work.

Actual Behavior

Deploying a function does not work and Serverless Framework will throw the following error after uploading the function zip.
See https://www.serverless.com/framework/docs/providers/aws/cli-reference/deploy-function/

Type Error ---------------------------------------------

  TypeError: Cannot read property 'Outputs' of undefined
      at Object.<anonymous> (/path/to/my/project/node_modules/serverless-plugin-datadog/src/output.ts:15:78)
      at Generator.next (<anonymous>)
      at fulfilled ((/path/to/my/project/node_modules/serverless-plugin-datadog/dist/src/output.js:5:58)

Steps to Reproduce the Problem

  1. create serverless project
  2. add serverless-plugin-datadog plugin
  3. deploy stack
  4. change function and deploy single function

Specifications

  • Serverless Framework version: 2.3.0
  • Datadog Serverless Plugin version: 2.6.2
  • Lambda function runtime (Python 3.7, Node 10, etc.): Node 12.x

Stacktrace

Type Error ---------------------------------------------

  TypeError: Cannot read property 'Outputs' of undefined
      at Object.<anonymous> (/path/to/my/project/node_modules/serverless-plugin-datadog/src/output.ts:15:78)
      at Generator.next (<anonymous>)
      at fulfilled ((/path/to/my/project/node_modules/serverless-plugin-datadog/dist/src/output.js:5:58)

Packaging from windows seems to embed an incorrect path

Expected Behavior

Packaging from windows works, results in a handler path like datadog_handlers/hello.handler, and the function executes

Actual Behavior

Packaging from windows, results in a handler path like datadog_handlers\\hello.handler, and the function doesn't execute with an error like
{"errorMessage":"Cannot find module '/var/task/datadog_handlers\\hello'","errorType":"Error","stackTrace":["Module.require (module.js:596:17)","require (internal/module.js:11:18)"]}

Steps to Reproduce the Problem

  1. On windows, add serverless-plugin-datadog to the serverless project
  2. Package/Deploy
  3. Observe in .serverless\cloudformation-template-update-stack.json that the AWS::Lambda::Function Handler properties all have paths that use double backslash as a path separator
  4. Try to execute the function from API Gateway's test functionality, get an error in part like {"errorMessage":"Cannot find module '/var/task/datadog_handlers\\hello'","errorType":"Error","stackTrace":["Module.require (module.js:596:17)","require (internal/module.js:11:18)"]}

Specifications

  • Serverless Framework version: 1.43.0
  • Datadog Serverless Plugin version: 0.9.0
  • Lambda function runtime (Python 3.7, Node 10, etc.): nodejs8.10

Stacktrace Error Log

Tue Dec 03 23:35:48 UTC 2019 : Endpoint response body before transformations: {"errorMessage":"Cannot find module '/var/task/datadog_handlers\\hello'","errorType":"Error","stackTrace":["Module.require (module.js:596:17)","require (internal/module.js:11:18)"]}
Tue Dec 03 23:35:48 UTC 2019 : Lambda execution failed with status 200 due to customer function error: Cannot find module '/var/task/datadog_handlers\hello'. Lambda request id: f965f844-e9c1-4b22-8115-e0563e4b1937

Clarify Behavior around `forwarderArn` option

Expected Behavior

The documentation for the forwarderArn states:

Setting this parameter subscribes the given Datadog forwarder to the Lambda functions’ CloudWatch log groups. Required when enableDDTracing is set to true. Do not set addExtension to true when using forwarderArn.

Because it its Required, we'd expect an error to be thrown. WE ACTUALLY DO NOT WANT THIS BEHAVIOR

Actual Behavior

When something else has added the datadog forwarder - such as the Datadog AWS Integration - tracing works as expected. WE ACTUALLY DO LIKE THIS BEHAVIOR

We would like this to continue to be the case and not have the forwarder or forwarderArn be required. Right now, this works as desired but I'd like to have the docs changed to reflect that you just need SOMETHING to create the forwarder and not require it in serverless.yaml.

Our use case:

  • We have dozens, maybe over a hundred lambdas - we have even more log groups
  • Half of the lambdas are in serverless, the other half are in terraform, we also have non-lambda things generating logs
  • We use the DD aws integtration to automatically subscribe our log groups to the forwarder
  • We'd prefer to allow the DD AWS integration to handle subscription - if it is off, devs have to rememeber to add it, if its on but devs add this, there is a double subscription

I am happy to open an MR to do this but before I do, I just want to make sure there isn't some other reason to leave it as is. What we want to avoid is someone seeing that blurb, then seeing that serverless isn't enforcing that behavior, then updating serverless to enforce that behavior.

Steps to Reproduce the Problem

  1. In serverless, create a lambda w/o tracing or a sub filter
  2. Outside of serverless, create a subscription filter to a datadog forwarder
  3. In serverless, specific enableDDTracing: true, do not specifiy forwarder or forwarderArn, trace any function
  4. Deploy and test tracing -> this will deploy and trace w/o error

Specifications

  • Serverless Framework version: 1.78.1
  • Datadog Serverless Plugin version: 2.17.0
  • Lambda function runtime (Python 3.7, Node 10, etc.): Python 3.8

TypeError: Cannot set property 'handler' of undefined with webpack

Expected Behavior

running with datadog plugin enabled should behave the same as running without

Actual Behavior

crash "TypeError: Cannot set property 'handler' of undefined" when running with this plugin and, apparently, webpack

Steps to Reproduce the Problem

  1. clone this repo: https://github.com/frsechet/datadog-sls-reproduce-issue
  2. npm install
  3. npm start
  4. visit http://localhost:3042
  5. you should see "hello world" but instead you get a crash

This reproduces the issue locally using serverless-offline, but exactly the same thing happens on live AWS environments.

Specifications

  • Serverless Framework version: 1.60.1
  • Datadog Serverless Plugin version: 0.14.0
  • Lambda function runtime (Python 3.7, Node 10, etc.): node10

Stacktrace

"TypeError: Cannot set property 'handler' of undefined",
"at Module.<anonymous> (/Users/frsechet/clevy/csml/saas/datadog-sls/.webpack/service/datadog_handlers/webpack:/datadog_handlers/myfunc.js:3:1)",
"at Module../datadog_handlers/myfunc.js (/Users/frsechet/clevy/csml/saas/datadog-sls/.webpack/service/datadog_handlers/myfunc.js:109:30)",
"at __webpack_require__ (/Users/frsechet/clevy/csml/saas/datadog-sls/.webpack/service/datadog_handlers/webpack:/webpack/bootstrap:19:1)",
"at /Users/frsechet/clevy/csml/saas/datadog-sls/.webpack/service/datadog_handlers/webpack:/webpack/bootstrap:83:1",
"at Object.<anonymous> (/Users/frsechet/clevy/csml/saas/datadog-sls/.webpack/service/datadog_handlers/myfunc.js:87:10)",
"at Module._compile (internal/modules/cjs/loader.js:776:30)",
"at Object.Module._extensions..js (internal/modules/cjs/loader.js:787:10)",
"at Module.load (internal/modules/cjs/loader.js:653:32)",
"at tryModuleLoad (internal/modules/cjs/loader.js:593:12)",
"at Function.Module._load (internal/modules/cjs/loader.js:585:3)",
"at Module.require (internal/modules/cjs/loader.js:690:17)",
"at require (internal/modules/cjs/helpers.js:25:18)",
"at Object.createHandler (/Users/frsechet/clevy/csml/saas/datadog-sls/node_modules/serverless-offline/src/functionHelper.js:215:15)",
"at handler (/Users/frsechet/clevy/csml/saas/datadog-sls/node_modules/serverless-offline/src/ApiGateway.js:485:40)",
"at module.exports.internals.Manager.execute (/Users/frsechet/clevy/csml/saas/datadog-sls/node_modules/@hapi/hapi/lib/toolkit.js:41:33)",
"at Object.internals.handler (/Users/frsechet/clevy/csml/saas/datadog-sls/node_modules/@hapi/hapi/lib/handler.js:46:48)",
"at exports.execute (/Users/frsechet/clevy/csml/saas/datadog-sls/node_modules/@hapi/hapi/lib/handler.js:31:36)",
"at Request._lifecycle (/Users/frsechet/clevy/csml/saas/datadog-sls/node_modules/@hapi/hapi/lib/request.js:312:68)"

DD plugin logs: `ERROR datadog:failed to extract http tags from api-gateway event` on each AWS Lambda call

Expected Behavior

No error being reported by the datadog serverless plugin.

Actual Behavior

The AWS Lambda function using the datadog serverless plugin suddenly started to log the following error in DD logs / cloudwatch:

ERROR [dd.trace_id=123 dd.span_id=123] {"status":"error","message":"datadog:failed to extract http tags from api-gateway event"}

  • It happens when the Lambda function is invoking the DD function from the datadog-ForwarderStack
  • I have been using the serverless plugin for the past 3 months without any issues.
  • The underlying AWS infrastructure has not been updated since 1 month.
  • Copy of the DatadogAWSIntegrationPolicy Iam role:
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "apigateway:GET",
                "autoscaling:Describe*",
                "budgets:ViewBudget",
                "cloudfront:GetDistributionConfig",
                "cloudfront:ListDistributions",
                "cloudtrail:DescribeTrails",
                "cloudtrail:GetTrailStatus",
                "cloudwatch:Describe*",
                "cloudwatch:Get*",
                "cloudwatch:List*",
                "codedeploy:List*",
                "codedeploy:BatchGet*",
                "directconnect:Describe*",
                "dynamodb:List*",
                "dynamodb:Describe*",
                "ec2:Describe*",
                "ecs:Describe*",
                "ecs:List*",
                "elasticache:Describe*",
                "elasticache:List*",
                "elasticfilesystem:DescribeAccessPoints",
                "elasticfilesystem:DescribeFileSystems",
                "elasticfilesystem:DescribeTags",
                "elasticloadbalancing:Describe*",
                "elasticmapreduce:List*",
                "elasticmapreduce:Describe*",
                "es:ListTags",
                "es:ListDomainNames",
                "es:DescribeElasticsearchDomains",
                "health:DescribeEvents",
                "health:DescribeEventDetails",
                "health:DescribeAffectedEntities",
                "kinesis:List*",
                "kinesis:Describe*",
                "lambda:AddPermission",
                "lambda:GetPolicy",
                "lambda:List*",
                "lambda:RemovePermission",
                "logs:TestMetricFilter",
                "logs:PutSubscriptionFilter",
                "logs:DeleteSubscriptionFilter",
                "logs:DescribeSubscriptionFilters",
                "rds:Describe*",
                "rds:List*",
                "redshift:DescribeClusters",
                "redshift:DescribeLoggingStatus",
                "route53:List*",
                "s3:GetBucketLogging",
                "s3:GetBucketLocation",
                "s3:GetBucketNotification",
                "s3:GetBucketTagging",
                "s3:ListAllMyBuckets",
                "s3:PutBucketNotification",
                "ses:Get*",
                "sns:List*",
                "sns:Publish",
                "sqs:ListQueues",
                "states:ListStateMachines",
                "states:DescribeStateMachine",
                "support:*",
                "tag:GetResources",
                "tag:GetTagKeys",
                "tag:GetTagValues",
                "xray:BatchGetTraces",
                "xray:GetTraceSummaries"
            ],
            "Resource": "*",
            "Effect": "Allow"
        }
    ]
}

Steps to Reproduce the Problem

  1. setup a lambda function with HTTP event
  2. add the serverless datadog plugin
  3. "status":"error","message":"datadog:failed to extract http tags from api-gateway event may appear in DD logs / cloudwatch

Specifications

  • Serverless Framework version: 2.3.0
  • Datadog Serverless Plugin version: 2.16.0
  • Lambda function runtime (Python 3.7, Node 10, etc.): Python 3.7

Stacktrace

"status":"error","message":"datadog:failed to extract http tags from api-gateway event

Cloudwatch log group subscription filter being deleted/recreated alternately on every deployment

Running a serverless deploy causes the subscription filter to be alternately created and destroyed. One deployment will destroy the subscription filter and the next will create the subscription filter and repeat.

Config:

plugins:
  - serverless-plugin-datadog

custom:
  datadog:
    flushMetricsToLogs: true
    forwarder: <forwarder lambda arn>

Expected Behavior

Subscription filter is created, not deleted

Actual Behavior

Deploy 1:
CloudFormation - CREATE_COMPLETE - AWS::Logs::SubscriptionFilter - ServiceUnderscoremethodUnderscorecallLogGroupSubscription
CloudFormation - CREATE_COMPLETE - AWS::Logs::SubscriptionFilter - PostUnderscoredeployLogGroupSubscription

Deploy 2:
CloudFormation - DELETE_COMPLETE - AWS::Logs::SubscriptionFilter - ServiceUnderscoremethodUnderscorecallLogGroupSubscription
CloudFormation - DELETE_COMPLETE - AWS::Logs::SubscriptionFilter - PostUnderscoredeployLogGroupSubscription

Repeat

Steps to Reproduce the Problem

  1. Serverless Deploy (subscribes first time)
  2. Serverless Deploy (unsubscribes)
  3. Serverless Deploy (subscribes)
  4. Serverless Deploy (unsubscribes)
  5. etc

Specifications

  • Serverless Framework version: 1.70.0
  • Datadog Serverless Plugin version: 1.1.0
  • Lambda function runtime: Python 3.6

[Question] Does the plugin support Datadog APM/tracing?

Per documentation it seems like the plugin supports auto-magic addition of Lambda layers to functions pre-req to metrics instrumentation. Just wondering if it also supports APM/tracing for lambda functions?

My use case has a lot of lambda timeout errors and I would like to investigate/understand bottlenecks by integrating APM/tracing into the serverless app/lambda handlers.

Support Typescript

Expected Behavior

It would be great to have support with the typescript serverless plugin (generate .ts files instead of .js files in datadog handler)

Actual Behavior

An error is thrown where the typescript plugin is looking for ts files but the dd plugin only generates .js files.

Steps to Reproduce the Problem

  1. sls deploy --noDeploy in a typescript project with the typescript and dd plugin

Specifications

  • Serverless Framework version:
  • Datadog Serverless Plugin version:
  • Lambda function runtime (Python 3.7, Node 10, etc.): Node 10

Stacktrace

Serverless: Auto instrumenting functions with Datadog
Serverless: Adding Lambda Layers to functions
Serverless: Compiling with Typescript...
Serverless: Using local tsconfig.json
{ file: undefined,
start: undefined,
length: undefined,
messageText:
 "File 'datadog_handlers/clear-business-credits.ts' not found.",
category: 1,
code: 6053,
reportsUnnecessary: undefined }

Type Error ---------------------------------------------

TypeError: Cannot read property 'getLineAndCharacterOfPosition' of undefined

ENOENT: no such file or directory, stat '/var/runtime/node_modules/aws-sdk/node_modules/aws-sdk/package.json

Expected Behavior

Traces and logs are error free

Actual Behavior

The following errors are showing up in our logs:

			{
                "trace_id": "2335ba9203685fb4",
                "span_id": "5ed4b2a01489dbfb",
                "parent_id": "2335ba9203685fb4",
                "name": "fs.operation",
                "resource": "statSync",
                "error": 0,
                "meta": {
                    "error.msg": "ENOENT: no such file or directory, stat '/var/runtime/node_modules/aws-sdk/node_modules/aws-sdk/package.json'",
                    "error.type": "Error",
                    "error.stack": "Error: ENOENT: no such file or directory, stat '/var/runtime/node_modules/aws-sdk/node_modules/aws-sdk/package.json'\n    at Object.statSync (fs.js:1009:3)\n    at /opt/nodejs/node_modules/dd-trace/packages/dd-trace/src/tracer.js:93:53\n    at /opt/nodejs/node_modules/dd-trace/packages/dd-trace/src/tracer.js:45:56\n    at Scope._activate (/opt/nodejs/node_modules/dd-trace/packages/dd-trace/src/scope/async_hooks.js:53:14)\n    at Scope.activate (/opt/nodejs/node_modules/dd-trace/packages/dd-trace/src/scope/base.js:12:19)\n    at DatadogTracer.trace (/opt/nodejs/node_modules/dd-trace/packages/dd-trace/src/tracer.js:45:35)\n    at Object.statSync (/opt/nodejs/node_modules/dd-trace/packages/dd-trace/src/tracer.js:93:23)\n    at isFile (/opt/nodejs/node_modules/resolve/lib/sync.js:10:23)\n    at loadAsDirectorySync (/opt/nodejs/node_modules/resolve/lib/sync.js:137:13)\n    at loadNodeModulesSync (/opt/nodejs/node_modules/resolve/lib/sync.js:178:25)",
                    "_dd.origin": "lambda",
                    "service": "repro-dev-auth-api",
                    "component": "fs",
                    "span.kind": "internal",
                    "file.path": "/var/runtime/node_modules/aws-sdk/node_modules"
                },
                "metrics": {
                    "_sample_rate": 1,
                    "_sampling_priority_v1": 1
                },
                "start": 1597448244683117300,
                "duration": 5001709,
                "service": "repro-dev-auth-api-fs"
            },
            {
                "trace_id": "2335ba9203685fb4",
                "span_id": "598947ec0fa2f3c4",
                "parent_id": "2335ba9203685fb4",
                "name": "fs.operation",
                "resource": "statSync",
                "error": 0,
                "meta": {
                    "error.msg": "ENOENT: no such file or directory, stat '/var/runtime/node_modules/aws-sdk/node_modules/aws-sdk/package.json'",
                    "error.type": "Error",
                    "error.stack": "Error: ENOENT: no such file or directory, stat '/var/runtime/node_modules/aws-sdk/node_modules/aws-sdk/package.json'\n    at Object.statSync (fs.js:1009:3)\n    at /opt/nodejs/node_modules/dd-trace/packages/dd-trace/src/tracer.js:93:53\n    at /opt/nodejs/node_modules/dd-trace/packages/dd-trace/src/tracer.js:45:56\n    at Scope._activate (/opt/nodejs/node_modules/dd-trace/packages/dd-trace/src/scope/async_hooks.js:53:14)\n    at Scope.activate (/opt/nodejs/node_modules/dd-trace/packages/dd-trace/src/scope/base.js:12:19)\n    at DatadogTracer.trace (/opt/nodejs/node_modules/dd-trace/packages/dd-trace/src/tracer.js:45:35)\n    at Object.statSync (/opt/nodejs/node_modules/dd-trace/packages/dd-trace/src/tracer.js:93:23)\n    at isFile (/opt/nodejs/node_modules/resolve/lib/sync.js:10:23)\n    at loadpkg (/opt/nodejs/node_modules/resolve/lib/sync.js:117:14)\n    at loadAsFileSync (/opt/nodejs/node_modules/resolve/lib/sync.js:86:19)",
                    "_dd.origin": "lambda",
                    "service": "repro-dev-auth-api",
                    "component": "fs",
                    "span.kind": "internal",
                    "file.path": "/var/runtime/node_modules/aws-sdk/node_modules"
                },
                "metrics": {
                    "_sample_rate": 1,
                    "_sampling_priority_v1": 1
                },
                "start": 1597448244688188400,
                "duration": 311768,
                "service": "repro-dev-auth-api-fs"
            },

and

			{
                "trace_id": "7b691e3bf3c8a9be",
                "span_id": "5d5e282f55a4c54f",
                "parent_id": "3d4de664637c2c43",
                "name": "fs.operation",
                "resource": "openSync",
                "error": 0,
                "meta": {
                    "error.msg": "ENOENT: no such file or directory, open '/home/sbx_user1051/.aws/config'",
                    "error.type": "Error",
                    "error.stack": "Error: ENOENT: no such file or directory, open '/home/sbx_user1051/.aws/config'\n    at Object.openSync (fs.js:458:3)\n    at /opt/nodejs/node_modules/dd-trace/packages/dd-trace/src/tracer.js:93:53\n    at /opt/nodejs/node_modules/dd-trace/packages/dd-trace/src/tracer.js:45:56\n    at Scope._activate (/opt/nodejs/node_modules/dd-trace/packages/dd-trace/src/scope/async_hooks.js:53:14)\n    at Scope.activate (/opt/nodejs/node_modules/dd-trace/packages/dd-trace/src/scope/base.js:12:19)\n    at DatadogTracer.trace (/opt/nodejs/node_modules/dd-trace/packages/dd-trace/src/tracer.js:45:35)\n    at Object.openSync (/opt/nodejs/node_modules/dd-trace/packages/dd-trace/src/tracer.js:93:23)\n    at Object.readFileSync (fs.js:360:35)\n    at /opt/nodejs/node_modules/dd-trace/packages/dd-trace/src/tracer.js:93:53\n    at /opt/nodejs/node_modules/dd-trace/packages/dd-trace/src/tracer.js:45:56",
                    "_dd.origin": "lambda",
                    "service": "repro-dev-auth-api",
                    "component": "fs",
                    "span.kind": "internal",
                    "file.path": "/home/sbx_user1051/.aws/config",
                    "file.flag": "r"
                },
                "metrics": {
                    "_sample_rate": 1,
                    "_sampling_priority_v1": 1
                },
                "start": 1597447653414957800,
                "duration": 355469,
                "service": "repro-dev-auth-api-fs"
            },
            {
                "trace_id": "7b691e3bf3c8a9be",
                "span_id": "3d4de664637c2c43",
                "parent_id": "280b566833b63848",
                "name": "fs.operation",
                "resource": "readFileSync",
                "error": 0,
                "meta": {
                    "error.msg": "ENOENT: no such file or directory, open '/home/sbx_user1051/.aws/config'",
                    "error.type": "Error",
                    "error.stack": "Error: ENOENT: no such file or directory, open '/home/sbx_user1051/.aws/config'\n    at Object.openSync (fs.js:458:3)\n    at /opt/nodejs/node_modules/dd-trace/packages/dd-trace/src/tracer.js:93:53\n    at /opt/nodejs/node_modules/dd-trace/packages/dd-trace/src/tracer.js:45:56\n    at Scope._activate (/opt/nodejs/node_modules/dd-trace/packages/dd-trace/src/scope/async_hooks.js:53:14)\n    at Scope.activate (/opt/nodejs/node_modules/dd-trace/packages/dd-trace/src/scope/base.js:12:19)\n    at DatadogTracer.trace (/opt/nodejs/node_modules/dd-trace/packages/dd-trace/src/tracer.js:45:35)\n    at Object.openSync (/opt/nodejs/node_modules/dd-trace/packages/dd-trace/src/tracer.js:93:23)\n    at Object.readFileSync (fs.js:360:35)\n    at /opt/nodejs/node_modules/dd-trace/packages/dd-trace/src/tracer.js:93:53\n    at /opt/nodejs/node_modules/dd-trace/packages/dd-trace/src/tracer.js:45:56",
                    "_dd.origin": "lambda",
                    "service": "repro-dev-auth-api",
                    "component": "fs",
                    "span.kind": "internal",
                    "file.path": "/home/sbx_user1051/.aws/config",
                    "file.flag": "r"
                },
                "metrics": {
                    "_sample_rate": 1,
                    "_sampling_priority_v1": 1
                },
                "start": 1597447653414909200,
                "duration": 424072,
                "service": "repro-dev-auth-api-fs"
            },

Steps to Reproduce the Problem

Please see the reproduction code/project here:

  1. Clone project
  2. yarn install
  3. sls deploy
  4. Create any test payload for the lambda function, even {} works
  5. Manually invoke the function and inspect the logs

Specifications

  • Serverless Framework version: 1.78.1
  • Datadog Serverless Plugin version: 2.1.0 (note this shows up as early as v0.25.0 of the plugin)
  • Lambda function runtime (Python 3.7, Node 10, etc.): Node 12

Stacktrace

See above or log output from repro steps

Console Patching Doesn't Consider stdout and stderr

Expected Behavior

I'd expect all data sent to logs to contain the trace id prefix, including output contained in stdout and stderr, as console.* writes to these streams.

Actual Behavior

Anything written directly with stdout or stderr lacks the trace id prefix. Only logs written with console.* are prefixed.

No doubt there were considerations made in choosing to only patch console.* methods, but for the ecosystem, the decision is rather short-sighted. At this point in time, our only choice is to create a writable stream that wraps console.* - that comes with massive performance implications as output in pino is compiled for what stdout.write/sterr.write expect, and requires a large amount of extra processing to prepare a single log message for use in console.* (mostly due to line break issues). We've seen an order of magnitude increase in the amount of time a log line takes to be sent to the std stream as a result.

I might be having an "it's too early in the day moment," but I'm unable to track down where the monkeypatching of console.log is taking place within this package, so handling that ourselves isn't looking too promising.

Steps to Reproduce the Problem

  1. Add pino to any serverless project utilizing this plugin
  2. Initialize a new logger with default settings
  3. Log data
  4. Observe the lack of prefix in datadog

Specifications

  • Serverless Framework version: 1.78.1
  • Datadog Serverless Plugin version: ^2.5.0
  • Lambda function runtime (Python 3.7, Node 10, etc.): Node 12

Stacktrace

n/a

Plugin does not respect provider.tags configuration

Expected Behavior

When provider.stackTags are set in Serverless, they should be used to configure tags on individual Lambda function resources within the stack, unless a conflicting tag is set using provider.tags or functions.functionName.tags, per the README documentation for the enableTags setting (emphasis added):

When set, the plugin will try to automatically tag lambdas with service and env, but will not override existing tags. Defaults to true.

Therefore, when I configure Serverless like this:

service:
  name: my-service

plugins:
  - serverless-plugin-datadog

custom:
  datadog:
    addLayers: true
    enableTags: true

provider:
  name: aws
  stage: my-stage
  tags:  # Can also be set using stackTags
    env: production
    service: some-service

functions:
  MyFunction:
    handler: functions.handler
    runtime: python3.8

I expect that the MyFunction Lambda would be tagged with env: production and service: some-service.

Actual Behavior

The MyLambda plugin is tagged with env:my-stage and service:my-service because custom.datadog.enableTags is set to true (the default value). The only way I can ensure that MyFunction is tagged with env: production and service: some-service is if functions.MyFunction.tags.env and functions.MyFunction.tags.service are set explicitly. For services with more that one function, this quickly becomes a nuisance, especially since the provider.tags setting is specifically provided by the Serverless framework for this purpose.

Steps to Reproduce the Problem

  1. Configure provider.tags.env to a value other than that of provider.stage and configure provider.tags.service to a value other than that of service.name.
  2. Do not set tags.env or tags.service on at least one Lambda function
  3. Ensure that datadog.enableTags is not set to false
  4. Deploy and inspect the tags of the deployed function(s). You will see that env: is set to the value of provider.stage and service: is set to the value of service.name, instead of the values configured at provider.tags.env and provider.tags.service, respectively.

Specifications

  • Serverless Framework version: 1.73.1
  • Datadog Serverless Plugin version: 1.0.0
  • Lambda function runtime (Python 3.7, Node 10, etc.): Reproduced using python3.8 and node10 runtimes

Stacktrace

N/A

Newer versions of the plugin are causing "Function code combined with layers exceeds the maximum allowed size" errors

Expected Behavior

Serverless is able to upload reasonably-sized function code and the datadog layer without erroring.

Actual Behavior

I'm receiving An error occurred: PostBidLambdaFunction - Function code combined with layers exceeds the maximum allowed size of 262144000 bytes. The actual size is 264579366 bytes. (Service: AWSLambdaInternal; Status Code: 400; Error Code: InvalidParameterValueException; Request ID: 8d181d55-7773-45fd-9713-c8f36f435a28; Proxy: null). errors when trying to deploy.

Zipped, the function code size is 15.54 MB. Unzipped, the function code is 85 MB. So it shouldn't be an issue of just barely pushing past the limit.

Using [email protected] works as expected. Trying to upgrade to latest (2.17.0) caused this to manifest.

Steps to Reproduce the Problem

  1. Create a function with >85MB unzipped function code size
  2. Add [email protected]
  3. Attempt to deploy

Specifications

  • Serverless Framework version: 2.28.7
  • Datadog Serverless Plugin version: 2.17.0
  • Lambda function runtime (Python 3.7, Node 10, etc.): Node 12

One potentially odd tidbit: My first assumption was that the fault was on my function code for being too large. Sure enough, unzipped it was over 260MB. I cut out some duplicated versions and brought it down to the 85MB described above. However, it didn't make a difference. In addition, rolling back to 2.12 with that large function package ALSO was successful. So the common factor seems to be the size of this layer.

The error message with the 260MB package was interestingly only slightly different in the "actual size" that it spit out. An error occurred: PostBidLambdaFunction - Function code combined with layers exceeds the maximum allowed size of 262144000 bytes. The actual size is 264574862 bytes. (Service: AWSLambdaInternal; Status Code: 400; Error Code: InvalidParameterValueException; Request ID: d0b9b944-6f6a-45e9-bb9e-1ca083c68c7f; Proxy: null).

Switching Extension and Forwarder implementations not working

Expected Behavior

We should be easily able to switch/change "serverless-datadog-plugin" settings between "forwarder" and "addExtension" implementation

Actual Behavior

Switching "forwarder" -> "addExtension" -> "forwarder" settings produce an error (see "Stacktrace" below)

Steps to Reproduce the Problem

Minimal Reproducible Example: https://github.com/VladimirRubin/serverless-datadog-plugin-test

  1. serverless deploy --datadog-api-key <apiKey> --datadog-type forwarder --datadog-forwarder <forwarderArn> -> deploy is passing
  2. serverless deploy --datadog-api-key <apiKey> --datadog-type extension -> deploy is passing
  3. serverless deploy --datadog-api-key <apiKey> --datadog-type forwarder --datadog-forwarder <forwarderArn> -> deploy failing with the error (see "Stacktrace" below)

Specifications

  • Serverless Framework version: 1.83.2
  • Datadog Serverless Plugin version: 2.27.0
  • Lambda function runtime (Python 3.7, Node 10, etc.): Node 14

Stacktrace

An error occurred: ExecutionLogGroup - Resource handler returned message: "Resource of type 'AWS::Logs::LogGroup'
with identifier '{"/properties/LogGroupName":"API-Gateway-Execution-Logs_<restApiID>/development"}' already exists."
(RequestToken: <requestToken>, HandlerErrorCode: AlreadyExists).

As a workaround setup subscribeToApiGatewayLogs: false helps

with tracing enabled, JSON output is broken when logging to CloudWatch with console.log

When using this plugin, console.log is automatically patched so it adds the trace id's as a prefix to every log statement. When logging text, this is fine, but when logging JSON it would be far better to include the trace id's inside the JSON, or to at least allow the user to disable this behaviour altogether, so it can be configured manually.

Ironically, Datadog itself is the obvious victim, because it is unable to parse these logs as objects, and reads them as text.

As a simple start, it would be nice if the plugin exposed a configuration option injectLogContext that is passed to the patched Lambda handlers, just like mergeDatadogXrayTraces to disable this behaviour.

Monitor names doesn't replace the placeholders

Actual Behavior

When I create the recommended monitors through the plugin the placeholders in their name are not replaced properly in Datadog.

image

My serverless definition file is in typescript, so the config is like:

 datadog: {
      addExtension: true,
      apiKey: '',
      monitorsAppKey: '',
      monitorsApiKey: '',
      monitors: [
        { high_error_rate: {} },
        { timeout: {} },
        { out_of_memory: {} },
        { high_cold_start_rate: {} },
        { high_throttles: {} },
        { increased_cost: {} },
      ],
    },

Steps to Reproduce the Problem

  1. Create the recommended monitors using the plugin

Specifications

  • Serverless Framework version: 2.52.0
  • Datadog Serverless Plugin version: 2.28.0

[Feature Request] Cannot customize handler

Expected Behavior

Be able to put specific datadog-lambda-js in a layer.

Actual Behavior

According to this line, the handler can be /opt/nodejs/node_modules/datadog-lambda-js/handler.handler with addLayers: true and node_modules/datadog-lambda-js/dist/handler.handler with addLayers: false.

What could be great is to have handler /opt/nodejs/node_modules/datadog-lambda-js/dist/handler.handler with addLayers: false

Why ?

Long story short... We have an issue with @aws-crypto/client-node using readable-stream under the hood and throwing module resolution errors in an other layer. This occurs only if datadog-lambda-js wraps our handler. So the idea is to have only one layer with everything in it because we can't get it work even with changing layers order...

How ?

The addLayers configuration could be improved by a layer setting that could be a string or a boolean. e.g.

layers: true => Handler: /opt/nodejs/node_modules/datadog-lambda-js/handler.handler + add Layer (default)
layers: false => Handler: /node_modules/datadog-lambda-js/handler.handler + no Layer
To keep the old behavior
layers: my/path/to/datadog-lambda-js => Handler: my/path/to/datadog-lambda-js + no Layer
For this feature

Specifications

  • Serverless Framework version: 2.23.0
  • Datadog Serverless Plugin version: 2.16.2
  • Lambda function runtime (Python 3.7, Node 10, etc.): node14

Stacktrace

NA

Thanks anyway for the great job

EDIT

BTW I can do a PR on this if this feature is OK for you

EDIT 2

The readable stream issue occurs because it is in v1.1.14 inside the datadog layer but @aws-crypto/[email protected] requires it at version ^3.6.0 in @aws-crypto/[email protected]

EDIT 3
The same behaviour could be done for the datadog SAM macro

Invalid wrapper code when the entrypoint is in a folder called "lambda"

Background

I have a python 3.7 project structured like this:

serverless.yml
some_module/
  some_file.py
lambda/
  handler.py

The some_module package contains the actual business logic / reusable code, and the lambda folder contains just my lambda handler functions -- so my serverless.yml specifies handler: lambda.handler.some_function. The handler.py function then imports some_module.some_file and uses that.

This works fine without serverless-plugin-datadog. However, when deployed with serverless-plugin-datadog, the plugin wraps the handler to add instrumentation, and generates code like this:

from datadog_lambda.wrapper import datadog_lambda_wrapper
from lambda.handler import some_function as some_function_impl
some_function = datadog_lambda_wrapper(some_function_impl)

This causes a syntax error because lambda can't be used as an identifier.

Expected Behavior

The plugin should at least warn about this issue and suggest renaming the folder to lambda_handlers or something like that.

Actual Behavior

The plugin quietly deploys invalid code, leading to internal server errors when the lambda function is invoked.

Specifications

  • Serverless Framework version: 1.67.3
  • Datadog Serverless Plugin version: 0.24.0
  • Lambda function runtime (Python 3.7, Node 10, etc.): Python 3.7

Stacktrace

[ERROR] Runtime.UserCodeSyntaxError: Syntax error in module 'datadog_handlers/extract_signature': invalid syntax (extract_signature.py, line 2)
Traceback (most recent call last):
  File "/var/task/datadog_handlers/extract_signature.py" Line 2
    from lambda.handler import extract as extract_impl  

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.