Giter Club home page Giter Club logo

datadog-cdk-constructs's Introduction

Datadog CDK Constructs

NPM NPM PyPI PyPI Go License

Use this Datadog CDK Construct Library to deploy serverless applications using AWS CDK .

This CDK library automatically configures ingestion of metrics, traces, and logs from your serverless applications by:

  • Installing and configuring the Datadog Lambda layers for your .NET, Java, Node.js, and Python Lambda functions.
  • Enabling the collection of traces and custom metrics from your Lambda functions.
  • Managing subscriptions from the Datadog Forwarder to your Lambda and non-Lambda log groups.

AWS CDK v1 vs AWS CDK v2

WARNING: AWS CDK v1 has reached end-of-support and datadog-cdk-constructs will no longer be receiving updates. It's strongly recommended to upgrade to AWS CDK v2 (official migration guide) and switch to using datadog-cdk-constructs-v2.

Two separate versions of Datadog CDK Constructs exist; datadog-cdk-constructs and datadog-cdk-constructs-v2. These are designed to work with AWS CDK v1 and AWS CDK v2 respectively.

  • datadog-cdk-constructs-v2 requires Node >= 14, while datadog-cdk-constructs supports Node >= 12.
  • datadog-cdk-constructs-v2 contains more features.
  • Otherwise, the use of the two packages is identical.

npm Package Installation:

For use with AWS CDK v2:

yarn add --dev datadog-cdk-constructs-v2
# or
npm install datadog-cdk-constructs-v2 --save-dev

For use with AWS CDK v1:

yarn add --dev datadog-cdk-constructs
# or
npm install datadog-cdk-constructs --save-dev

PyPI Package Installation:

For use with AWS CDK v2:

pip install datadog-cdk-constructs-v2

For use with AWS CDK v1:

pip install datadog-cdk-constructs

Go Package Installation:

For use with AWS CDK v2:

go get github.com/DataDog/datadog-cdk-constructs-go/ddcdkconstruct

AWS CDK v1 is not supported.

Note:

Pay attention to the output from your package manager as the Datadog CDK Construct Library has peer dependencies.

Usage

AWS CDK

  • If you are new to AWS CDK then check out this workshop.
  • The following examples assume the use of AWS CDK v2. If you're using CDK v1, import datadog-cdk-constructs rather than datadog-cdk-constructs-v2.

Add this to your CDK stack:

TypeScript

import { Datadog } from "datadog-cdk-constructs-v2";

const datadog = new Datadog(this, "Datadog", {
  nodeLayerVersion: <LAYER_VERSION>,
  pythonLayerVersion: <LAYER_VERSION>,
  javaLayerVersion: <LAYER_VERSION>,
  dotnetLayerVersion: <LAYER_VERSION>
  addLayers: <BOOLEAN>,
  extensionLayerVersion: "<EXTENSION_VERSION>",
  forwarderArn: "<FORWARDER_ARN>",
  createForwarderPermissions: <BOOLEAN>,
  flushMetricsToLogs: <BOOLEAN>,
  site: "<SITE>",
  apiKey: "{Datadog_API_Key}",
  apiKeySecretArn: "{Secret_ARN_Datadog_API_Key}",
  apiKeySecret: <AWS_CDK_ISECRET>, // Only available in datadog-cdk-constructs-v2
  apiKmsKey: "{Encrypted_Datadog_API_Key}",
  enableDatadogTracing: <BOOLEAN>,
  enableMergeXrayTraces: <BOOLEAN>,
  enableDatadogLogs: <BOOLEAN>,
  injectLogContext: <BOOLEAN>,
  logLevel: <STRING>,
  env: <STRING>, //Optional
  service: <STRING>, //Optional
  version: <STRING>, //Optional
  tags: <STRING>, //Optional
});
datadog.addLambdaFunctions([<LAMBDA_FUNCTIONS>])
datadog.addForwarderToNonLambdaLogGroups([<LOG_GROUPS>])

Go

import (
	"github.com/DataDog/datadog-cdk-constructs-go/ddcdkconstruct"
)
datadog := ddcdkconstruct.NewDatadog(
    stack,
    jsii.String("Datadog"),
    &ddcdkconstruct.DatadogProps{
        NodeLayerVersion:      jsii.Number(<LAYER_VERSION>),
        AddLayers:             jsii.Bool(<BOOLEAN>),
        Site:                  jsii.String(<SITE>),
        ApiKey:                jsii.String(os.Getenv("DD_API_KEY")),
        // ...
    })
datadog.AddLambdaFunctions(&[]interface{}{myFunction}, nil)
datadog.AddForwarderToNonLambdaLogGroups()

Source Code Integration

Source code integration is enabled by default through automatic lambda tagging, and will work if:

  • The Datadog Github integration is installed.
  • Your datadog-cdk dependency satisfies either of the below versions:
    • datadog-cdk-constructs-v2 >= 1.4.0
    • datadog-cdk-constructs >= 0.8.5

Alternative Methods to Enable Source Code Integration

If the automatic implementation doesn't work for your case, please follow one of the two guides below.

Note: these alternate guides only work for Typescript.

datadog-cdk version satisfied, but Datadog Github integration NOT installed

If the Datadog Github integration is not installed, you need to import the datadog-ci package and manually upload your Git metadata to Datadog. For the best results, import the datadog-ci package where your CDK Stack is initialized.

const app = new cdk.App();

// Make sure to add @datadog/datadog-ci via your package manager
const datadogCi = require("@datadog/datadog-ci");
// Manually uploading Git metadata to Datadog.
datadogCi.gitMetadata.uploadGitCommitHash("{Datadog_API_Key}", "<SITE>");

const app = new cdk.App();
new ExampleStack(app, "ExampleStack", {});

app.synth();
datadog-cdk version NOT satisfied

Change your initialization function as follows (in this case, gitHash value is passed to the CDK):

async function main() {
  // Make sure to add @datadog/datadog-ci via your package manager
  const datadogCi = require("@datadog/datadog-ci");
  const [, gitHash] = await datadogCi.gitMetadata.uploadGitCommitHash("{Datadog_API_Key}", "<SITE>");

  const app = new cdk.App();
  // Pass in the hash to the ExampleStack constructor
  new ExampleStack(app, "ExampleStack", {}, gitHash);
}

Ensure you call this function to initialize your stack.

In your stack constructor, change to add an optional gitHash parameter, and call addGitCommitMetadata():

export class ExampleStack extends cdk.Stack {
  constructor(scope: cdk.App, id: string, props?: cdk.StackProps, gitHash?: string) {
    ...
    ...
    datadog.addGitCommitMetadata([<YOUR_FUNCTIONS>], gitHash)
  }
}

Configuration

To further configure your Datadog construct, use the following custom parameters:

Note: The descriptions use the npm package parameters, but they also apply to the PyPI package parameters.

npm package parameter PyPI package parameter Description
addLayers add_layers Whether to add the Lambda Layers or expect the user to bring their own. Defaults to true. When true, the Lambda Library version variables are also required. When false, you must include the Datadog Lambda library in your functions' deployment packages.
pythonLayerVersion python_layer_version Version of the Python Lambda layer to install, such as 83. Required if you are deploying at least one Lambda function written in Python and addLayers is true. Find the latest version number here.
nodeLayerVersion node_layer_version Version of the Node.js Lambda layer to install, such as 100. Required if you are deploying at least one Lambda function written in Node.js and addLayers is true. Find the latest version number from here.
javaLayerVersion java_layer_version Version of the Java layer to install, such as 8. Required if you are deploying at least one Lambda function written in Java and addLayers is true. Find the latest version number in the Serverless Java installation documentation. Note: extensionLayerVersion >= 25 and javaLayerVersion >= 5 are required for the Datadog construct to instrument your Java functions properly.
dotnetLayerVersion dotnet_layer_version Version of the .NET layer to install, such as 13. Required if you are deploying at least one Lambda function written in .NET and addLayers is true. Find the latest version number from here.
extensionLayerVersion extension_layer_version Version of the Datadog Lambda Extension layer to install, such as 5. When extensionLayerVersion is set, apiKey (or if encrypted, apiKMSKey or apiKeySecretArn) needs to be set as well. When enabled, lambda function log groups will not be subscribed by the forwarder. Learn more about the Lambda extension here.
forwarderArn forwarder_arn When set, the plugin will automatically subscribe the Datadog Forwarder to the functions' log groups. Do not set forwarderArn when extensionLayerVersion is set.
createForwarderPermissions createForwarderPermissions When set to true, creates a Lambda permission on the the Datadog Forwarder per log group. Since the Datadog Forwarder has permissions configured by default, this is unnecessary in most use cases.
flushMetricsToLogs flush_metrics_to_logs Send custom metrics using CloudWatch logs with the Datadog Forwarder Lambda function (recommended). Defaults to true . If you disable this parameter, it's required to set apiKey (or if encrypted, apiKMSKey or apiKeySecretArn).
site site Set which Datadog site to send data. This is only used when flushMetricsToLogs is false or extensionLayerVersion is set. Possible values are datadoghq.com, datadoghq.eu, us3.datadoghq.com, us5.datadoghq.com, ap1.datadoghq.com, and ddog-gov.com. The default is datadoghq.com.
apiKey api_key Datadog API Key, only needed when flushMetricsToLogs is false or extensionLayerVersion is set. For more information about getting a Datadog API key, see the API key documentation.
apiKeySecretArn api_key_secret_arn The ARN of the secret storing the Datadog API key in AWS Secrets Manager. Use this parameter in place of apiKey when flushMetricsToLogs is false or extensionLayer is set. Remember to add the secretsmanager:GetSecretValue permission to the Lambda execution role.
apiKeySecret api_key_secret An AWS CDK ISecret representing a secret storing the Datadog API key in AWS Secrets Manager. Use this parameter in place of apiKeySecretArn to automatically grant your Lambda execution roles read access to the given secret. See here for an example. Only available in datadog-cdk-constructs-v2.
apiKmsKey api_kms_key Datadog API Key encrypted using KMS. Use this parameter in place of apiKey when flushMetricsToLogs is false or extensionLayerVersion is set, and you are using KMS encryption.
enableDatadogTracing enable_datadog_tracing Enable Datadog tracing on your Lambda functions. Defaults to true.
enableMergeXrayTraces enable_merge_xray_traces Enable merging X-Ray traces on your Lambda functions. Defaults to false.
enableDatadogLogs enable_datadog_logs Send Lambda function logs to Datadog via the Datadog Lambda Extension. Defaults to true. Note: This setting has no effect on logs sent via the Datadog Forwarder.
sourceCodeIntegration source_code_integration Enable Datadog Source Code Integration, connecting your telemetry with application code in your Git repositories. This requires the Datadog Github integration to work, otherwise please follow the alternative method. Learn more here. Defaults to true.
injectLogContext inject_log_context When set, the Lambda layer will automatically patch console.log with Datadog's tracing ids. Defaults to true.
logLevel log_level When set to debug, the Datadog Lambda Library and Extension will log additional information to help troubleshoot issues.
env env When set along with extensionLayerVersion, a DD_ENV environment variable is added to all Lambda functions with the provided value. When set along with forwarderArn, an env tag is added to all Lambda functions with the provided value.
service service When set along with extensionLayerVersion, a DD_SERVICE environment variable is added to all Lambda functions with the provided value. When set along with forwarderArn, a service tag is added to all Lambda functions with the provided value.
version version When set along with extensionLayerVersion, 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 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 cdk parses the string and sets each key:value pair as a tag to all Lambda functions.
enableColdStartTracing enable_cold_start_tracing Set to false to disable Cold Start Tracing. Used in Node.js and Python. Defaults to true.
coldStartTraceMinDuration min_cold_start_trace_duration Sets the minimum duration (in milliseconds) for a module load event to be traced via Cold Start Tracing. Number. Defaults to 3.
coldStartTraceSkipLibs cold_start_trace_skip_libs 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.
enableProfiling enable_profiling Enable the Datadog Continuous Profiler with true. Supported in Beta for Node.js and Python. Defaults to false.
encodeAuthorizerContext encode_authorizer_context When set to true for Lambda authorizers, the tracing context will be encoded into the response for propagation. Supported for Node.js and Python. Defaults to true.
decodeAuthorizerContext decode_authorizer_context 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 Node.js and Python. Defaults to true.
apmFlushDeadline apm_flush_deadline 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 Node.js and Python. Defaults to 100 milliseconds.
redirectHandler redirect_handler When set to false, skip redirecting handler to the Datadog Lambda Library's handler. Useful when only instrumenting with Datadog Lambda Extension. Defaults to true.

Note: Using the parameters above may override corresponding function level DD_XXX environment variables.

Tracing

Enable X-Ray Tracing on your Lambda functions. For more information, see CDK documentation.

import * as lambda from "aws-cdk-lib/aws-lambda";

const lambda_function = new lambda.Function(this, "HelloHandler", {
  runtime: lambda.Runtime.NODEJS_14_X,
  code: lambda.Code.fromAsset("lambda"),
  handler: "hello.handler",
  tracing: lambda.Tracing.ACTIVE,
});

Nested Stacks

Add the Datadog CDK Construct to each stack you wish to instrument with Datadog. In the example below, we initialize the Datadog CDK Construct and call addLambdaFunctions() in both the RootStack and NestedStack.

import { Datadog } from "datadog-cdk-constructs-v2";
import * as cdk from "aws-cdk-lib";
import { Construct } from "constructs";

class RootStack extends cdk.Stack {
  constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
    super(scope, id, props);
    new NestedStack(this, "NestedStack");

    const datadog = new Datadog(this, "Datadog", {
      nodeLayerVersion: <LAYER_VERSION>,
      pythonLayerVersion: <LAYER_VERSION>,
      javaLayerVersion: <LAYER_VERSION>,
      dotnetLayerVersion: <LAYER-VERSION>,
      addLayers: <BOOLEAN>,
      forwarderArn: "<FORWARDER_ARN>",
      flushMetricsToLogs: <BOOLEAN>,
      site: "<SITE>",
      apiKey: "{Datadog_API_Key}",
      apiKeySecretArn: "{Secret_ARN_Datadog_API_Key}",
      apiKmsKey: "{Encrypted_Datadog_API_Key}",
      enableDatadogTracing: <BOOLEAN>,
      enableMergeXrayTraces: <BOOLEAN>,
      enableDatadogLogs: <BOOLEAN>,
      injectLogContext: <BOOLEAN>
    });
    datadog.addLambdaFunctions([<LAMBDA_FUNCTIONS>]);

  }
}

class NestedStack extends cdk.NestedStack {
  constructor(scope: Construct, id: string, props?: cdk.NestedStackProps) {
    super(scope, id, props);

    const datadog = new Datadog(this, "Datadog", {
      nodeLayerVersion: <LAYER_VERSION>,
      pythonLayerVersion: <LAYER_VERSION>,
      javaLayerVersion: <LAYER_VERSION>,
      dotnetLayerVersion: <LAYER-VERSION>,
      addLayers: <BOOLEAN>,
      forwarderArn: "<FORWARDER_ARN>",
      flushMetricsToLogs: <BOOLEAN>,
      site: "<SITE>",
      apiKey: "{Datadog_API_Key}",
      apiKeySecretArn: "{Secret_ARN_Datadog_API_Key}",
      apiKmsKey: "{Encrypted_Datadog_API_Key}",
      enableDatadogTracing: <BOOLEAN>,
      enableMergeXrayTraces: <BOOLEAN>,
      enableDatadogLogs: <BOOLEAN>,
      injectLogContext: <BOOLEAN>
    });
    datadog.addLambdaFunctions([<LAMBDA_FUNCTIONS>]);

  }
}

Tags

Add tags to your constructs. We recommend setting an env and service tag to tie Datadog telemetry together. For more information see official AWS documentation and CDK documentation.

Automatically grant AWS secret read access to Lambda execution role

Only available in datadog-cdk-constructs-v2

To automatically grant your Lambda execution roles read access to a given secret, pass in apiKeySecret in place of apiKeySecretArn when initializing the Datadog construct.

const { Secret } = require('aws-cdk-lib/aws-secretsmanager');

const secret = Secret.fromSecretPartialArn(this, 'DatadogApiKeySecret', 'arn:aws:secretsmanager:us-west-1:123:secret:DATADOG_API_KEY');

const datadog = new Datadog(this, 'Datadog', {
  ...
  apiKeySecret: secret
  ...
});

When addLambdaFunctions is called, the Datadog CDK construct grants your Lambda execution roles read access to the given AWS secret. This is done through the AWS ISecret's grantRead function.

How it works

The Datadog CDK construct takes in a list of lambda functions and installs the Datadog Lambda Library by attaching the Lambda Layers for .NET, Java, Node.js, and Python to your functions. It redirects to a replacement handler that initializes the Lambda Library without any required code changes. Additional configurations added to the Datadog CDK construct will also translate into their respective environment variables under each lambda function (if applicable / required).

While Lambda function based log groups are handled by the addLambdaFunctions method automatically, the construct has an additional function addForwarderToNonLambdaLogGroups which subscribes the forwarder to any additional log groups of your choosing.

Resources to learn about CDK

Using Projen

The Datadog CDK Construct Libraries use Projen to maintain project configuration files such as the package.json, .gitignore, .npmignore, etc. Most of the configuration files will be protected by Projen via read-only permissions. In order to change these files, edit the .projenrc.js file, then run npx projen to synthesize the new changes. Check out Projen for more details.

Opening Issues

If you encounter a bug with this package, we want to hear about it. Before opening a new issue, search the existing issues to avoid duplicates.

When opening an issue, include the Datadog CDK Construct version, Node version, and stack trace if available. In addition, 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, please feel free to open a pull request following the procedures.

Testing

If you contribute to this package you can run the tests using yarn test. This package also includes a sample application for manual testing:

  1. Open a seperate terminal.
  2. Run yarn watch, this will ensure the Typescript files in the src directory are compiled to Javascript in the lib directory.
  3. Navigate to src/sample, here you can edit index.ts to test your contributions manually.
  4. At the root directory, run npx cdk --app lib/sample/index.js <CDK Command>, replacing <CDK Command> with common CDK commands like synth, diff, or deploy.
  • Note, if you receive "... is not authorized to perform: ..." you may also need to authorize the commands with your AWS credentials.

Debug Logs

To display the debug logs for this library, set the DD_CONSTRUCT_DEBUG_LOGS env var to true when running cdk synth (use --quiet to suppress generated template output).

Example: Ensure you are at the root directory

DD_CONSTRUCT_DEBUG_LOGS=true npx cdk --app lib/sample/index.js synth --quiet

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.

datadog-cdk-constructs's People

Contributors

agocs avatar ajsaavedra avatar astuyve avatar ayylam avatar benjamin-scc avatar cgatt avatar dependabot[bot] avatar duncanista avatar duncanpharvey avatar dylanlovescoffee avatar exoego avatar ganeshkumarsv avatar hghotra avatar ivantopolcic avatar jcstorms1 avatar joeyzhao2018 avatar lizapressman avatar lym953 avatar meghna-dd avatar meghna-eng avatar mweberxyz avatar nhinsch avatar purple4reina avatar rpelliard avatar sabeslamidze avatar sfirrin avatar shanehandley-lt 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

Watchers

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

datadog-cdk-constructs's Issues

Add node 20 support

Expected Behavior

Node versions are support up to 20

Actual Behavior

Node versions are support up to 18

Steps to Reproduce the Problem

Specifications

  • Datadog Lambda Layer version:
  • Node version: 20

Forwarder Subscription Filters Should Not Create Lambda Permissions

The current implementation below uses the default behavior of creating a Lambda permission per log group on the target lambda (the forwarder) which causes a deployment failure when the number of lambdas/log groups is large enough. The specific error will be:

The final policy size ({{ size }}) is bigger than the limit (20480)

const forwarderDestination = new LambdaDestination(forwarder);

const forwarderDestination = new LambdaDestination(forwarder);

Since the forwarder already has the permission allowing all log groups in the account and region trigger it, the solution is simply to pass { addPermissions: false, }, or make this configurable.

Getting errors after trying to deploy Node.js lambdas with arm architecture

Expected Behavior

Selecting the arm architecture for a lambda should not fail the runtime.

Actual Behavior

When trying to deploy to arm architecture, I got errors about the Datadog agent no able to start well.

Steps to Reproduce the Problem

  1. Add architecture: cdk.aws_lambda.Architecture.ARM_64, to an cdk.aws_lambda_nodejs.NodejsFunction
  2. cdk deploy
  3. runtime fails with:
RequestId: b6d7748b-1ec0-42dc-8cf6-513e295003d7 Error: fork/exec /opt/extensions/datadog-agent: exec format error
Extension.LaunchError
EXTENSION	Name: datadog-agent	State: LaunchError	Events: []	Error Type: UnknownError

Deployed arns:

  • arn:aws:lambda:us-east-2:464622532012:layer:Datadog-Node14-x:76
  • arn:aws:lambda:us-east-2:464622532012:layer:Datadog-Extension-ARM:21

npm list (ran on my machine):

> npm list
├─┬ [redacted-cdk-project-name]@0.0.0 -> ./services/[redacted-cdk-project-name]
│ ├── @aws-sdk/[email protected]
│ ├── @aws-sdk/[email protected]
│ ├── @aws-sdk/[email protected]
│ ├── @aws-sdk/[email protected]
│ ├── @swc/[email protected]
│ ├── @swc/[email protected]
│ ├── @swc/[email protected]
│ ├── @types/[email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ └── [email protected]
└── [email protected] extraneous

Guess: Because I list dd-trace in my own package.json, because cdk deploy happened on an x86_64 (GitHub action), then the agent that was loaded was not arm compatible?

Thanks!

Default `sourceCodeIntegration` to false

Expected Behavior

Set sourceCodeIntegration to false by default.

Actual Behavior

Set sourceCodeIntegration to true by default if not specified when init DataDog
CDK construct.

Why

sourceCodeIntegration = true make the CDK will do full deployment every time.
This is because CDK will do build, bundle and file hash. And then compare the
hash with remote to see if any new changes. If not, CDK will output (no changes)
and skip the stack deployment. However, by default set to true breaks it.

Compatibility with cdk v2

Expected Behavior

The datadog-cdk-constructs can be used with the upcoming CDK v2 (release candidates already available)

Actual Behavior

npm ERR! code ERESOLVE
npm ERR! ERESOLVE unable to resolve dependency tree
npm ERR! 
npm ERR! While resolving: [email protected]
npm ERR! Found: [email protected]
npm ERR! node_modules/constructs
npm ERR!   constructs@"^10.0.0" from the root project
npm ERR! 
npm ERR! Could not resolve dependency:
npm ERR! peer constructs@"^3.2.27" from [email protected]
npm ERR! node_modules/datadog-cdk-constructs
npm ERR!   datadog-cdk-constructs@"*" from the root project
npm ERR! 
npm ERR! Fix the upstream dependency conflict, or retry
npm ERR! this command with --force, or --legacy-peer-deps
npm ERR! to accept an incorrect (and potentially broken) dependency resolution.

The dependencies can't be resolved when using the suggested settings for v2.

Steps to Reproduce the Problem

  1. Migrate or Setup a CDK project with v2 (https://docs.aws.amazon.com/cdk/latest/guide/work-with-cdk-v2.html)
  2. npm install datadog-cdk-constructs

Specifications

  • Datadog Lambda Layer version:
  • Node version: v12.22.2

Stacktrace

see actual behavior section

setGitCommitHashEnvironmentVariable and setDDEnvVariables both set DD_TAGS

Expected Behavior

You can easily set your own tags, git commit information, per function tags, etc. and not be concerned with how envs are merged and the order envs are applied.

Actual Behavior

The setGitCommitHashEnvironmentVariable and setDDEnvVariables both call addEnvironment on the Lambda, and therefore the one used last (e.g. if you use const datadog = new DataDog({ tags: 'foo:bar' }); datadog.setGitCommitHashEnvironmentVariable(...fns, "hash")) will 'win'.

Steps to Reproduce the Problem

  1. const datadog = new DataDog({ tags: 'foo: bar' });
  2. datadog.setGitCommitHashEnvironmentVariable(...fns, "d90adafaf8d4b2d82828d514b3ef7c6e66524d0a"))`

Results in:

Screenshot 2022-06-29 at 15 07 58

Specifications

  • Datadog Lambda Layer version: 0.8 / v2-0.3.3
  • Node version: 16

LogGroup SubscriptionFilter has a different resource name every deployment causing cloudformation failures

I am attempting to integrate datadog cdk construct v2 into my project like so:

if (props.datadog) {
      // For documentation: https://github.com/DataDog/datadog-cdk-constructs
      // NodeLayerVersion is gotten from: https://github.com/DataDog/datadog-lambda-js/releases
      const datadog = new Datadog(this, 'Datadog', {
        env: props.stackEnvironment,
        service: 'REDACTED',
        version: props.codeVersion,
        forwarderArn: Fn.importValue(props.datadog.forwarder!),
        nodeLayerVersion: props.datadog.nodeLayerVersion
      });

      datadog.addLambdaFunctions([...]);
    }

It appears that the SubscriptionFilters are being created with unique resource names every time. This causes cloudformation to try and add additional subscription to the log groups. It fails because there is a limit on subscriptions. This limit is set to 2 and cannot change according to AWS docs. https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/cloudwatch_limits_cwl.html

This resource id should not change from deploy to deploy. The offending code:

const subscriptionFilterName = generateSubscriptionFilterName(Names.uniqueId(lam), forwarderArn);

As long as the construct is scoped correctly, CDK will take care of the rest with the resource name.

How to reproduce?

  • Have datadog construct in the stack
  • Leverage forwarderArn
  • Attach to lambdas
  • Deploy 2-3 times (depends if other filters exists)
  • Observe error
12:06:30 PM | CREATE_FAILED        | AWS::Logs::SubscriptionFilter            | REDACTED...er348769153C2BF03B
Resource limit exceeded. (Service: AWSLogs; Status Code: 400; Error Code: LimitExceededException; Request ID: 85c404c8-84e0-4c7a-a379-17e3cb512271; Proxy: null)

12:06:30 PM | CREATE_FAILED        | AWS::Logs::SubscriptionFilter            | REDACTED...er3f6649f5015872C4
Resource limit exceeded. (Service: AWSLogs; Status Code: 400; Error Code: LimitExceededException; Request ID: f02d0345-31eb-4108-96e6-ed610f5eb326; Proxy: null)

12:06:31 PM | CREATE_FAILED        | AWS::Logs::SubscriptionFilter            | REDACTED...er09c33c10EA3CA0A6
Resource limit exceeded. (Service: AWSLogs; Status Code: 400; Error Code: LimitExceededException; Request ID: 35d42acb-8785-4aad-ad4a-def5b25c15b5; Proxy: null)

The stack named xxxx-sandbox-bri failed to deploy: UPDATE_ROLLBACK_COMPLETE: Resource limit exceeded. (Service: AWSLogs; Status Code: 400; Error Code: LimitExceededException; Request ID: 85c404c8-84e0-4c7a-a379-17e3cb512271; Proxy: null), Resource limit exceeded. (Service: AWSLogs; Status Code: 400; Error Code: LimitExceededException; Request ID: f02d0345-31eb-4108-96e6-ed610f5eb326; Proxy: null), Resource limit exceeded. (Service: AWSLogs; Status Code: 400; Error Code: LimitExceededException; Request ID: 35d42acb-8785-4aad-ad4a-def5b25c15b5; Proxy: null)

I'd suggest checking for other resources doing the same thing.

CDK not installing Datadog-Node16-x layer

Expected Behavior

CKD would install Datadog-Extension layer & Datadog-Node16-x layer on lambda

Actual Behavior

only the Datadog-Extension layer is being created on lambda

Steps to Reproduce the Problem

const dataDog = new Datadog(this, 'DataDogIntegration', {
      addLayers: true,
      nodeLayerVersion: 78,
      extensionLayerVersion: 22,
   ...
 })

Specifications

  • Datadog Lambda Layer version: 22
  • Node version: 78

Stacktrace

Add support for adding Java tracing layer

Please add support for the dd-java-trace layer.

Current workaround after calling add_lambda_functions is to additionally manually add a LayerVersion and add the environment variable AWS_LAMBDA_EXEC_WRAPPER, as per the Custom setup instructions.

Sort of like so:

the_lambda_function = ...

datadog.add_lambda_functions([the_lambda_function])

dd_trace_layer_version = aws_lambda.LayerVersion.from_layer_version_arn(
    self, "DatadogTraceJavaLayer", f"arn:aws:lambda:{self.region}:464622532012:layer:dd-trace-java:8"
)
the_lambda_function.add_layers(dd_trace_layer_version)
the_lambda_function.add_environment('AWS_LAMBDA_EXEC_WRAPPER', '/opt/datadog_wrapper')

Cloudwatch error after setting up our lambda function with CDK construct

Expected Behavior

We use the constructs to instrument our lambda functions. Most of our logs look like this:

START RequestId: ba4d56aa-cb23-468a-960b-5df98d09e9df Version: $LATEST
2022-01-05T10:27:51.431Z	ba4d56aa-cb23-468a-960b-5df98d09e9df	INFO	[dd.trace_id=7576945396481994720 dd.span_id=7576945396481994720] DATADOG TRACER CONFIGURATION - {
    "date": "2022-01-05T10:27:51.430Z",
    "os_name": "Linux",
    "os_version": "4.14.252-207.481.amzn2.x86_64",
    "architecture": "x64",
    "version": "1.1.2",
    "lang": "nodejs",
    "lang_version": "14.18.1",
    "enabled": true,
    "service": "...",
    "agent_url": "http://127.0.0.1:8126",
    "debug": false,
    "sample_rate": 1,
    "sampling_rules": [],
    "tags": {
        "_dd.origin": "lambda",
        "service": "..."
    },
    "log_injection_enabled": true,
    "runtime_metrics_enabled": false,
    "integrations_loaded": [
        "dns",
        "net",
        "pg",
        "http",
        "https",
        "http2"
    ]
}
2022-01-05T10:27:52.491Z	ba4d56aa-cb23-468a-960b-5df98d09e9df	INFO	[dd.trace_id=2744288801532801835 dd.span_id=2744288801532801835] Success
END RequestId: ba4d56aa-cb23-468a-960b-5df98d09e9df

And data is pushed correctly to datadog. We would expect no errors showing up.

Actual Behavior

Quite regularly we get errors in the cloudwatch logs of our newly instrumented lambda function that look like this:

LOGS	Name: datadog-agent	State: Subscribed	Types: [platform,function,extension]
2022-01-05T10:26:42.652Z	undefined	ERROR	{
    "status": "error",
    "message": "datadog:api key not configured, see https://dtdg.co/sls-node-metrics"
}
EXTENSION	Name: datadog-agent	State: Ready	Events: [INVOKE,SHUTDOWN]

We do provide API KEY, via apiKeySecretArn (see below). So not quite sure what does this error means.

Steps to Reproduce the Problem

datadog = new Datadog(scope, id, {
      addLayers: true,
      nodeLayerVersion: 66,
      extensionLayerVersion: 15,
      site: "datadoghq.com",
      enableDatadogTracing: true,
      apiKeySecretArn: ...
    });

datadog.addLambdaFunctions([<LAMBDA_FUNCTIONS>]);

Specifications

  • Datadog Lambda Layer version: 15
  • Node version: 14

Thx for your help!

Layer Dependency Management

Hey there,

I've come from using the serverless datadog plugin and was wondering if there was an equivalent way of getting updates for the datadog layer version?

We rely on renovate to update our dependencies and whilst the serverless plugin would keep our layers up to date there doesn't appear to be a similar mechanism to do so here.

How would you recommend we do that?

Cheers

S3 bucket uploader

We have an S3 bucket. We want to use the standard forwarder (https://docs.datadoghq.com/serverless/libraries_integrations/forwarder/#cloudformation)
to push the contents of this bucket to DD.

Expected Behavior

It should be pretty easy to snoop into this construct and directly manipulate the lambda.

Actual Behavior

Nope. There's no easy way to subscribe the publisher lambda in here to an S3 bucket.

Steps to Reproduce the Problem

Specifications

  • Datadog Lambda Layer version:
  • Node version:

Stacktrace

Paste here

Property enableMergeXrayTraces missing ?

Expected Behavior

The documentation indicates that the enableMergeXrayTraces property exists for the Datadog construct.

Actual Behavior

The property enableMergeXrayTraces is not found.

Steps to Reproduce the Problem

  1. Install the latest version of the construct (v2)
  2. Create a new Datadog and try to set enableMergeXrayTraces
  3. Synthesize the stack.

Specifications

  • Datadog Lambda Layer version: 35
  • Node version: v16.15.1

Stacktrace

TSError: ⨯ Unable to compile TypeScript:
ApiGatewaySpecRestApiPerMicroserviceStack.ts:194:7 - error TS2345: Argument of type '{ apiKeySecretArn: string; captureLambdaPayload: false; env: string; enableDatadogLogs: false; enableMergeXrayTraces: boolean; extensionLayerVersion: number; pythonLayerVersion: number; service: string; site: string; version: string; }' is not assignable to parameter of type 'DatadogProps'.
Object literal may only specify known properties, and 'enableMergeXrayTraces' does not exist in type 'DatadogProps'.

Does not support CDK tokens properly

Expected Behavior

This should work, but it doesn't.

const datadogSite = ssm.StringParameter.fromStringParameterName(this, `${prefix}-datadog-site`, "/datadog/site");
const datadog = new Datadog(this, datadogName, {
      site: "us5.datadoghq.com", //datadogSite.stringValue, // Site is required for the sender extension layer set by extensionLayerVersion
      apiKeySecretArn: datadogAPIKey.secretArn,
      extensionLayerVersion: 25, // This is the datadog agent in lambda form. This is what sends stuff async to DD
      env: props.environmentName, // This sets the environment name for the lambda
      service: prefix, // This is the service name in DD
      version: packageVersion, // This is the version of the code we are running. This lets DD know about deployments.
      nodeLayerVersion: 81,
});

Actual Behavior

image

Since the CDK passes this to a token at synth time, the checks do not recognize it and mark it as invalid.

Datadog Site Value: ${Token[TOKEN.532]}

Specifications

  • Datadog Lambda Layer version: NA
  • Node version: v16.15.1
  • datadog-cdk-constructs-vs: 0.3.4 - just installed today

Stacktrace

/Users/.../node_modules/datadog-cdk-constructs-v2/src/common/datadogSharedLogic.ts:25
  throw new Error(
        ^
Error: Warning: Invalid site URL. Must be either datadoghq.com, datadoghq.eu, us3.datadoghq.com, us5.datadoghq.com, or ddog-gov.com.
  at Object.validateProps (/Users/dmurawsky/projects/croissant-services/node_modules/datadog-cdk-constructs-v2/src/common/datadogSharedLogic.ts:25:11)
  at new Datadog (/Users/dmurawsky/projects/croissant-services/node_modules/datadog-cdk-constructs-v2/src/datadog.ts:45:5)
  at new RetailerServicesStack (/Users/dmurawsky/projects/croissant-services/lib/retailer-services/retailer-services-stack.ts:432:21)
  at Object.<anonymous> (/Users/dmurawsky/projects/croissant-services/bin/croissant-services.ts:72:31)
  at Module._compile (node:internal/modules/cjs/loader:1105:14)
  at Module.m._compile (/Users/dmurawsky/projects/croissant-services/node_modules/ts-node/src/index.ts:1618:23)
  at Module._extensions..js (node:internal/modules/cjs/loader:1159:10)
  at Object.require.extensions.<computed> [as .ts] (/Users/dmurawsky/projects/croissant-services/node_modules/ts-node/src/index.ts:1621:12)
  at Module.load (node:internal/modules/cjs/loader:981:32)
  at Function.Module._load (node:internal/modules/cjs/loader:822:12)

Subprocess exited with error 1

Cannot apply addLambdaFunctions via aspect: "We detected an Aspect was added via another Aspect, and will not be applied"

Expected Behavior

I attempted to write an aspect that would automatically set up tracing for my nodeJS lambdas. I expected this would result in full instrumentation of these functions without multiple source file edits.

Actual Behavior

Aspect fails to apply with an error "We detected an Aspect was added via another Aspect, and will not be applied".

Steps to Reproduce the Problem

Example aspect for datadog:

abstract class TraceAgentBase implements IAspect {

    protected readonly props: DatadogProps;
    protected readonly ddtrace: Datadog;
    // protected readonly scope: IConstruct;

    protected constructor(ddtrace: Datadog, props: DatadogProps) {
        this.props = props;
        this.ddtrace = ddtrace
    }

    public visit(node: IConstruct): void {
        if (node instanceof NodejsFunction) {
            this.applyNodeTracingToLambda(node)
        }
    }
    protected abstract applyNodeTracingToLambda(resource: NodejsFunction): void;
}
`
export class TraceAgent extends TraceAgentBase  {
    constructor(ddtrace: Datadog, props: DatadogProps) {
        super(ddtrace, props);
    }
    protected applyNodeTracingToLambda(resource: NodejsFunction) {
        this.ddtrace.addLambdaFunctions([resource])
        resource.addEnvironment('DD_MERGE_XRAY_TRACES', 'true');
        const cfnFunc = resource.node.defaultChild as CfnFunction;
        cfnFunc.tracingConfig = {mode: Tracing.ACTIVE};
    }
}

apply to stack with something like this:

        Aspects.of(runner).add(new TraceAgent(ddtrace, {
            apiKey: DatadogAPISecret.secretValue.toString(),
            nodeLayerVersion: 78,
            extensionLayerVersion: 23,
            env: 'dev',
            service: serviceName,
            version: '0.1.2-datadog',
            captureLambdaPayload: true,
        }));

Specifications

  • Datadog Lambda Layer version: 23
  • Node version: 78

Stacktrace

None available

After much debugging, I've tracked this down to the use of Tags.of() in addCdkConstructVersionTag and setTags() calls starting here - Tags.of() is an aspect as well.

Has anybody else hit this, and did you work around it successfully? Has there been any thought or exploration into how to make the datadog construct aspect-compatible?

Although not ideal, I believe this can be solved by using something like construct.tags.setTag(key, value, 100, true) to set tags directly, rather than calling the aspect to do the same. There won't be much (any?) cascading of tags to child objects in this case, so really not much is lost.

Happy to make a PR if there is no objection.

Publish Java package to Maven

Due to this being a JSII library, we could expect packages to be provided for languages other than javascript and python.

Could you please enable publishing to a public Maven repository?

Until a package is published for Java, any downstream library depending on datadog-cdk-constructs-v2 is also blocked from packaging for Java

feature request: add NodeJsFunction construct support

Request

It would be great to see support for NodeJsFunction constructs in the datadog CDK. These functions make it considerably easier to manage dependencies and are the more modern way to write NodeJs functions in lambda.

Bump @aws-cdk/aws-lambda-python-alpha version to latest #298

Expected Behavior

Whenever we install the datadog construct with the latest aws-lambda-python-alpha package, it should not fail with a dependency error

Actual Behavior

Fails with dependency error

Steps to Reproduce the Problem

  1. install the latest @aws-cdk/aws-lambda-python-alpha package
  2. install the datadog-cdk-constructs-v2 package

Specifications

  • Datadog Lambda Layer version: n/a
  • Python version: n/a

Stacktrace

npm ERR! code ERESOLVE
npm ERR! ERESOLVE unable to resolve dependency tree
npm ERR! 
npm ERR! While resolving: [email protected]
npm ERR! Found: @aws-cdk/[email protected]
npm ERR! node_modules/@aws-cdk/aws-lambda-python-alpha
npm ERR!   @aws-cdk/aws-lambda-python-alpha@"^2.59.0-alpha.0" from the root project
npm ERR! 
npm ERR! Could not resolve dependency:
npm ERR! peer @aws-cdk/aws-lambda-python-alpha@"^2.24.0-alpha.0" from [email protected]
npm ERR! node_modules/datadog-cdk-constructs-v2
npm ERR!   dev datadog-cdk-constructs-v2@"*" from the root project
npm ERR! 
npm ERR! Fix the upstream dependency conflict, or retry
npm ERR! this command with --force, or --legacy-peer-deps
npm ERR! to accept an incorrect (and potentially broken) dependency resolution.

Publish C# package to NuGet

Due to this being a JSII library, we could expect packages to be provided for languages other than javascript and python.

Could you please enable publishing to a public NuGet repository?

Until a package is published for C#, any downstream library depending on datadog-cdk-constructs-v2 is also blocked from packaging for C#

Automatically grantRead for `apiKeySecretArn`

Currently, the documentation mentions that you have to remember to manually grant GetSecretValue when passing the API key as an ARN:

| `apiKeySecretArn` | `api_key_secret_arn` | The ARN of the secret storing the Datadog API key in AWS Secrets Manager. Use this parameter in place of `apiKey` when `flushMetricsToLogs` is `false` or `extensionLayer` is set. Remember to add the `secretsmanager:GetSecretValue` permission to the Lambda execution role. |

It would be nice if this construct did it for you.

Instead of passing a secret arn string:

new Datadog(scope, 'Datadog', {
  apiKeySecretArn: 'arn:aws:secretsmanager:us-west-2:12345678910:secret:DATADOG_API_KEY'
});

If the user could pass an ISecret:

const secret = Secret.fromSecretPartialArn(this, 'DatadogApiKeySecret', 'arn:aws:secretsmanager:us-west-2:12345678910:secret:DATADOG_API_KEY');
new Datadog(scope, 'Datadog', {
  apiKeySecret: secret
});

Then, in the construct, you could grantRead for us:

apiKeySecret.grantRead(lambda)

Possibility to override runtime version with CDK V1

Hello there 🖐

Using CDK V1 to deploy lambda functions with the NodeJS runtime, we came across a problem recently when upgrading our runtimes to Node 18.
CDK V1 doesn't officially support NodeJS 18 runtimes (since it is on maintenance, they don't add new features to it, cf aws/aws-cdk#23639 (comment)).

Some of our projects are still using CDK V1 and we use the trick mentioned in the above thread to manually override the runtime version. Here's what it looks like :

    this.func = new NodejsFunction(this, 'Api', {
      functionName: stack.stackName,
      entry: './dist/main.js',
      runtime: Runtime.NODEJS_14_X,
     ...
    });

    (this.func.node.defaultChild as CfnFunction).addPropertyOverride(
      'Runtime',
      'nodejs18.x',
    );

Looking at the source code of this construct, it relies on the func.runtime.name (

const runtime: string = lam.runtime.name;
) to know which runtime is used, and our override is not taken into account.

Would it be possible to introduce an override mechanism, or to rely directly on the runtime property to take possible overrides into account ?

Right now we are using the arn:aws:lambda:us-east-1:464622532012:layer:Datadog-Node14-x:91 layer even with the Node18 runtime and it seems to work, but we would prefer to prevent future issues with this version mismatch.

Thanks!
Romain

Extension layer should always be added regardless of addLayers prop

As far as I can tell from the docs, there's no way to add the contents of the extension via a package; it must always be a layer. That means even if I opt out of layers because I instrument my function myself with the library packages, it won't work without the extension.

This has caused me to need to use getExtensionLayerArn() and add the layer myself, which feels unnecessary. I'm willing to make the PR if you agree on what correct behavior is here.

Cannot read properties of undefined (reading 'dockerPlatform')

Expected Behavior

Deploy AWS stack via CDK properly.

Actual Behavior

Can't deploy AWS cdk stack as it fails on reading architecture props of lambda

Steps to Reproduce the Problem

  1. install datadog-cdk-constructs-v2
  2. add Datadog to stack
  3. call addLambdaFunctions with handlers
  4. deploy aws cdk cdk deploy

Specifications

  • cdk version: 2.54.0 (build 9f41881)
  • Datadog Lambda Layer version: 1.6.0
  • Node version: 16.15.1

Usage

const datadog = new Datadog(this, 'Datadog', {
      nodeLayerVersion: 54,
      addLayers: true,
      extensionLayerVersion: 8,
      site: 'datadoghq.eu',
      apiKeySecretArn:
        'arn:aws:secretsmanager:eu-west-1:xxx',
      env: 'test',
      version: '1.0.0',
      tags: 'xx:xx-yyyy',
    });

  const policyHandler = this.createPolicyHandler(api);
  datadog.addLambdaFunctions([policyHandler]);

Stacktrace

  lambdas.forEach((lam) => {
        ^
TypeError: Cannot read properties of undefined (reading 'dockerPlatform')
  at node_modules/datadog-cdk-constructs-v2/src/layer.ts:39:36
  at Array.forEach (<anonymous>)
  at Object.applyLayers (node_modules/datadog-cdk-constructs-v2/src/layer.ts:36:11)
  at Datadog.addLambdaFunctions (node_modules/datadog-cdk-constructs-v2/src/datadog.ts:67:9)


Can't add env and service values to a Docker Lambda

Expected Behavior

When setting up the datadog construct for a lambda the env and service are added with the extension layer and add environment variables to the lambda

Actual Behavior

Adding extension layer is being reject because it is a packaged lambda. Deploying without the extension is working as expected but don't create the environment variables

Steps to Reproduce the Problem

  1. Create a CDK script
  2. Add to it function from a docker file
  3. Create a datadog component and include extensionLayerVersion key

Specifications

  • Datadog Lambda Layer version: 43
  • Node version:

Stacktrace

"Please don't provide Handler or Runtime or Layer when the intended function PackageType is Image. (Service: Lambda, Status Code: 400, Request ID: 0db9418c-418f-4c5b-b6a3-f89ec1d9f873)" (RequestToken: 75a65225-d578-b731-7070-0558c4690f9a, HandlerErrorCode: InvalidRequest)
  at FullCloudFormationDeployment.monitorDeployment (/usr/local/lib/node_modules/aws-cdk/lib/index.js:380:10236)
  at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
  at async deployStack2 (/usr/local/lib/node_modules/aws-cdk/lib/index.js:383:145458)
  at async /usr/local/lib/node_modules/aws-cdk/lib/index.js:383:128776
  at async run (/usr/local/lib/node_modules/aws-cdk/lib/index.js:383:126782)

Missing `@aws-cdk/aws-lambda-python-alpha` type declaration prevents TypeScript compilation

Expected Behavior

TypeScript CDK project importing datadog-cdk-constructs-v2 can be compiled.

Actual Behavior

TypeScript compilation fails due to imported @aws-cdk/aws-lambda-python-alpha package missing type declarations.

Steps to Reproduce the Problem

  1. npm install datadog-cdk-constructs-v2
  2. import * as datadog from "datadog-cdk-constructs-v2"
  3. tsc

Specifications

  • Datadog version: ^0.3.3

Stacktrace

node_modules/datadog-cdk-constructs-v2/lib/datadog.d.ts:1:31 - error TS2307: Cannot find module '@aws-cdk/aws-lambda-python-alpha' or its corresponding type declarations.

1 import * as lambdaPython from "@aws-cdk/aws-lambda-python-alpha";
                              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


Found 1 error in node_modules/datadog-cdk-constructs-v2/lib/datadog.d.ts:1

Lambda tags not being picked up for serverless

Expected Behavior

  1. Tags are provided in the cdk stack
  2. Tags are available in AWS
  3. Tags are available in DD

Actual Behavior

  1. Tags are provided in the cdk stack
  2. Tags are available in AWS
  3. Tags are NOT available in DD

Steps to Reproduce the Problem

  1. Use the new CDK 2 bindings. Not sure if related
  2. Define tags on the cdk stack
    private prepareInstrumentation(scope, id) {
        Tags.of(this).add("service", id);
        Tags.of(this).add("env", scope.stage);
        Tags.of(this).add("version", process.env.SEED_BUILD_SERVICE_SHA);

        const apiKey = "...";
        const site = "datadoghq.eu";

        const datadog = new Datadog(this, "Datadog", {
            nodeLayerVersion: 67,
            extensionLayerVersion: 18,
            apiKey,
            site,
        });

        datadog.addLambdaFunctions(this.getAllFunctions());
    }
  1. Tags are available in AWS, for the cloudformation stack and all children
    Screenshot 2022-02-07 at 18 11 23

  2. Tags are not available in Datadog
    Screenshot 2022-02-07 at 18 12 59

Specifications

  • Datadog Lambda Layer version: 18
  • Node version: 67

aws-lambda-python-alpha is outdated

Hi,
Currently aws-lambda-python-alpha version is still on 2.63.0-alpha.0, which is quite outdated, since the newest version is already 2.92.0-alpha.0. I ran into the issue since yesterday, my workaround is downgrading aws-lambda-python-alpha to 2.63.0-alpha.0 for my project (or using the flag --force or --legacy-peer-deps as suggested in the error report). Is it possible to bump the version from your library?

Expected Behavior

npm install runs successfully

Actual Behavior

npm install failed with error ERESOLVE

Steps to Reproduce the Problem

  1. Declare aws-cdk as part of the dependencies in package.json (In my case I have:
"devDependencies": {
...
   "@types/node": "20.5.1",
   "aws-cdk": "^2.92.0",
   "datadog-cdk-constructs-v2": "^1.7.4",
...
   "ts-jest": "^29.1.1",
   "ts-node": "^10.9.1",
   "typescript": "~5.1.6"
 },
 "dependencies": {
   "@aws-cdk/aws-glue-alpha": "^2.92.0-alpha.0",
   "@aws-cdk/aws-lambda-python-alpha": "^2.92.0-alpha.0",
   "aws-cdk-lib": "2.92.0",
...
  1. Run npm install

Specifications

  • Datadog Lambda Layer version: v47
  • Node version: v18.16.0

Stacktrace

npm ERR! code ERESOLVE
npm ERR! ERESOLVE could not resolve
npm ERR! 
npm ERR! While resolving: [email protected]
npm ERR! Found: @aws-cdk/[email protected]
npm ERR! node_modules/@aws-cdk/aws-lambda-python-alpha
npm ERR!   @aws-cdk/aws-lambda-python-alpha@"^2.64.0-alpha.0" from the root project
npm ERR! 
npm ERR! Could not resolve dependency:
npm ERR! peer @aws-cdk/aws-lambda-python-alpha@"^2.63.0-alpha.0" from [email protected]
npm ERR! node_modules/datadog-cdk-constructs-v2
npm ERR!   dev datadog-cdk-constructs-v2@"^1.7.4" from the root project
npm ERR! 
npm ERR! Conflicting peer dependency: @aws-cdk/[email protected]
npm ERR! node_modules/@aws-cdk/aws-lambda-python-alpha
npm ERR!   peer @aws-cdk/aws-lambda-python-alpha@"^2.63.0-alpha.0" from [email protected]
npm ERR!   node_modules/datadog-cdk-constructs-v2
npm ERR!     dev datadog-cdk-constructs-v2@"^1.7.4" from the root project
npm ERR! 
npm ERR! Fix the upstream dependency conflict, or retry
npm ERR! this command with --force or --legacy-peer-deps
npm ERR! to accept an incorrect (and potentially broken) dependency resolution.

Lambda requires DD_API_KEY envar even though Datadog is already provided with apiKeySecret

Expected Behavior

I expected that when I initialise the Datadog construct with an apiKeySecret it should use this to populate any envars related to the api key and set permissions to read the secret.

Actual Behavior

I get errors in the lambda cloudwatch logs:
DD_EXTENSION | ERROR | Unable to load trace agent config: you must specify an API Key, either via a configuration file or the DD_API_KEY env var

Steps to Reproduce the Problem

  1. Create the datadog construct
      const datadogApiKeySecret = Secret.fromSecretPartialArn(
        this,
        'datadogApiKeySecret',
        props.envConfig.datadogApiSecretArn,
      );
      // add datadog integration - this is passed to the constructs so they can add the datadog layer to the lambdas
      this.datadog = new Datadog(this, "Datadog", {
        nodeLayerVersion: 99,
        extensionLayerVersion: 49,
        site: 'datadoghq.com',
        apiKeySecret: datadogApiKeySecret,
        env: `${props.envConfig.envName}`,
        version: props.deployName,
        captureLambdaPayload: true,
      });
  1. Create a lambda function
// Create a lambda function to create a transaction when triggered by an IoT rules
    this.myLambdaFunction = new NodejsFunction(this, 'myLambdaFunction', {
      entry: 'resources/lambda/handler.ts',
      handler: 'myHandler',
      vpc: props.vpc,
      securityGroups: [lambdaSecurityGroup],
      environment: {
        DD_SERVICE: 'myLambdaFunction',
        env: props.envConfig.envName,
      },
      logRetention: logs.RetentionDays.ONE_WEEK,
      timeout: cdk.Duration.minutes(1),
      tracing: lambda.Tracing.ACTIVE,
    });
    this.datadog.addLambdaFunctions([ this.myLambdaFunction ]);
  1. The logs show the error describe
  2. Add the DD_API_KEY envvar and it starts working
    ...
    environment: {
        DD_SERVICE: 'myLambdaFunction',
        DD_API_KEY: this.datadog.props.apiKeySecret?.secretValue.unsafeUnwrap() || '',
        env: props.envConfig.envName,
      },
    ...

Specifications

Datadog Lambda Extension does not respect Tags

Expected Behavior

env, service and version tagged appropriately in Datadog

Actual Behavior

env === none
service === aws.lambda

Steps to Reproduce the Problem

import { Runtime } from "@aws-cdk/aws-lambda";
import { PythonFunction } from "@aws-cdk/aws-lambda-python";
import * as cdk from "@aws-cdk/core";
import { Tags } from "@aws-cdk/core";
import { Datadog } from "datadog-cdk-constructs";

export class DdtestStack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    Tags.of(this).add("env", "my-test-env");
    Tags.of(this).add("service", "my-test-service");

    const dd = new Datadog(this, "Datadog", {
      pythonLayerVersion: 38,
      // forwarderArn: this.formatArn({
      //   service: "lambda",
      //   resource: "function",
      //   resourceName: "datadog-forwarder",
      //   sep: ":",
      // }),
      extensionLayerVersion: 8,
      apiKey: process.env.DD_API_KEY!,
    });

    const fn = new PythonFunction(this, "Function", {
      entry: "./lib/handler",
      runtime: Runtime.PYTHON_3_8,
    });

    dd.addLambdaFunctions([fn]);
  }
}

The handler

from ddtrace import tracer


@tracer.wrap()
def another():
    return "another"


@tracer.wrap("MyHandler")
def handler(event, context):
    print(another())
    return "hi"

Specifications

  • Datadog Lambda Layer version: 8
  • Node version: v14.15.4

Screenshots

image

The top trace is using the forwarder.
The second trace is using the extension.

Using addGitCommitMetadata overwrites any DD_TAGS already set

Expected Behavior

It appends git.comiit.sha tag to pre-existing tags within DD_TAGS when using the prop tags

Actual Behavior

Overwrites DD_TAGS

Steps to Reproduce the Problem

const myFunction = new Fucntion(...)


const dd = new Datadog({
...
tags: 'foo:bar'
})

dd.addLambdaFunctions([myFuction])
dd.addGitCommitMetadata([myFunction]) // this removes DD_TAGS=foo:bar

Specifications

  • Datadog Lambda Layer version: v0.3.3
  • Node version: 16

Using Datadog layers and lambda alias causes an error on redeploy

Expected Behavior

I can redeploy a CDK stack containing lambdas using the Datadog CDK layers without causing an error

Actual Behavior

When redeploying my stack the layer hash changes even if there is no code difference. This results in the CDK trying to create a new version, and causes a Version already exists error and a rollback.

Steps to Reproduce the Problem

  1. Create a simple CDK stack
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import {Alias, Code, Function, Runtime} from "aws-cdk-lib/aws-lambda";
import {Datadog} from "datadog-cdk-constructs-v2";
import {Secret} from "aws-cdk-lib/aws-secretsmanager";

export class ReproStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);
      const lambda = new Function(
          this,
          "dd-repro",
          {
              functionName: "dd-repro",
              runtime: Runtime.NODEJS_18_X,
              handler: 'index.handler',
              code: Code.fromInline("exports.handler = async (event) => { return 'hello world'; }")
          },
      );

      new Alias(this, `dd-repro-alias`, {
          aliasName: `alias`,
          version: lambda.currentVersion,
          provisionedConcurrentExecutions: 1,
      });

      const ddApiKeySecret = Secret.fromSecretPartialArn(
          this,
          'DatadogApiKeySecret',
          `arn:aws:secretsmanager:${this.region}:${this.account}:secret:YOUR_DATADOG_SECRET_NAME`,
      );

      const dd = new Datadog(this, 'Datadog', {
          nodeLayerVersion: 99,
          extensionLayerVersion: 49,
          addLayers: true,
          site: 'datadoghq.eu',
          apiKeySecret: ddApiKeySecret,
          enableDatadogTracing: true,
          captureLambdaPayload: true,
          enableMergeXrayTraces: true,
          enableDatadogLogs: true,
          injectLogContext: true,
          env: "dev",
          service: 'repro',
          tags: `stage:dev`,
      });

      dd.addLambdaFunctions([lambda])
  }
}
  1. Deploy your function.
  2. Eventually (I've had to wait a minute or two before) when running cdk diff for your stack will show a new version being made
cdk diff --profile=dev
Stack ReproStack
Resources
[-] AWS::Lambda::Version dd-repro/CurrentVersion ddreproCurrentVersionC5369628d780c301499b40a4b6eef2f7624b39f1 destroy
[+] AWS::Lambda::Version dd-repro/CurrentVersion ddreproCurrentVersionC53696280e70249a63c9be974c8c296a11a167aa
[~] AWS::Lambda::Alias dd-repro-alias ddreproalias187071F3
 └─ [~] FunctionVersion
     └─ [~] .Fn::GetAtt:
         └─ @@ -1,4 +1,4 @@
            [ ] [
            [-]   "ddreproCurrentVersionC5369628d780c301499b40a4b6eef2f7624b39f1",
            [+]   "ddreproCurrentVersionC53696280e70249a63c9be974c8c296a11a167aa",
            [ ]   "Version"
            [ ] ]


✨  Number of stacks with differences: 1

Any subsequent deploys will now fail with this error

Resource handler returned message: "Version already exists: [[...]dd-repro:3]. Please modify the function to create a new vers
ion."

I've found that if you disable the @aws-cdk/aws-lambda:recognizeLayerVersion feature flag then the layer hash becomes consistent and further deploys are totally fine, but ideally we'd be able to leave that bug fix flag on!

The description of the flag makes it sound like one of the properties of the datadog layers is non deterministic?

Specifications

  • Datadog Lambda Layer version: 49
  • Node version: 99
  • CDK version: 2.109.0
  • DD construct version: 1.9.0 but I've seen it in 1.8.2 as well.

Add DD_MERGE_XRAY_TRACES to Datadog Construct

Expected Behavior

DD_MERGE_XRAY_TRACES is a settable parameter on the Datadog construct to allow for serverless trace merging per this documentation: https://docs.datadoghq.com/serverless/distributed_tracing/serverless_trace_merging/

Actual Behavior

There is no way to set this variable for all lambdas in my stack. As such, there is no way to merge the traces from Datadog and X-Ray for my AWS step functionsw.

Steps to Reproduce the Problem

  1. Create new Datadog CDK construct
  2. No ability to add DD_MERGE_XRAY_TRACES

Specifications

  • Datadog Lambda Layer version: 76
  • Node version: 14

Stacktrace

const datadog = new Datadog(this, "Datadog" + branch, {
        nodeLayerVersion: 76,
        extensionLayerVersion: 21,
        apiKey: datadogAPIKey.secretValueFromJson('DatadogAPIKey').toString(),
        captureLambdaPayload: true,
      })

Default `injectLogContext` to `false` when using the Extension

Expected Behavior

From the documentation, it seems like you don't need to muddy up the logs with trace IDs if you're using the extension.

If you are using the Lambda extension to collect traces and logs, Datadog automatically adds the AWS Lambda request ID to the aws.lambda span under the request_id tag. Additionally, Lambda logs for the same request are added under the lambda.request_id attribute. The Datadog trace and log views are connected using the AWS Lambda request ID.

If you are using the Forwarder Lambda function to collect traces and logs, dd.trace_id is automatically injected into logs (enabled by the environment variable DD_LOGS_INJECTION). The Datadog trace and log views are connected using the Datadog trace ID. This feature is supported for most applications using a popular runtime and logger (see the support by runtime).

To me, this means "if you're not using the forwarder (e.g., you're using the extension), you don't need to inject traces to the logs".

Actual Behavior

If injectLogContext is not provided, it always defaults to true.

Steps to Reproduce the Problem

const lambda = new Function(this, 'TestDatadogLayer', {
  runtime: Runtime.NODEJS_18_X,
  handler: 'index.handler',
  code: Code.fromInline('exports.handler = function(event, ctx, cb) { console.info("info log"); return cb(null, "hi"); }')
})

const datadogApiKeySecret = Secret.fromSecretCompleteArn(this, 'DatadogApiKeySecret', cdk.Fn.importValue("Datadog-ApiKeySecretArn"))
datadogApiKeySecret.grantRead(lambda)
const datadog = new Datadog(this, 'Datadog', {
  nodeLayerVersion: 90, // https://github.com/DataDog/datadog-lambda-js/releases
  pythonLayerVersion: 71, // https://github.com/DataDog/datadog-lambda-python/releases
  extensionLayerVersion: 42, // https://github.com/DataDog/datadog-lambda-extension/releases
  apiKeySecretArn: datadogApiKeySecret.secretArn,
  service: 'test-datadog-layer',
  env: 'dev',
})
datadog.addLambdaFunctions([lambda])

With this simple example, the lambda has DD_LOGS_INJECTION set to true. However, because we're using the extension (because extensionLayerVersion is set), I don't think we need this.

Specifications

  • Datadog Lambda Layer version: 42
  • Node version: 18.x LTS

Stacktrace

N/A

SingletonFunction is not supported for the addLambdaFunctions method.

I have a SingletonFunction in my cdk codebase to handle migrations. The typing for the addLambdaFunctions method as it is now does not support this construct because it does not inherit from the plain lambda.Function, it implements the lambda.IFunction interface.

It would be good if addLambdaFunctions could support it with:

public addLambdaFunctions(
   lambdaFunctions: (lambda.Function | lambdaNodejs.NodejsFunction | lambdaPython.PythonFunction | lambda.SingletonFunction)[],
 )

or some similar implementation.

What do you guys think?

TEST ISSUE, please delete

Expected Behavior

TEST ISSUE, please delete me!

Actual Behavior

Steps to Reproduce the Problem

Specifications

  • Datadog Lambda Layer version:
  • Node version:

Stacktrace

Paste here

aws-lambda-python-alpha is outdated

Hi,
Currently aws-lambda-python-alpha version is on 2.93.0-alpha.0, since the newest version is already 2.98.0-alpha.0. I ran into the issue, my workaround is downgrading aws-lambda-python-alpha to 2.93.0-alpha.0 for my project (or using the flag --force or --legacy-peer-deps as suggested in the error report). Is it possible to bump the version from your library?

Expected Behavior

npm install runs successfully

Actual Behavior

npm install failed with error ERESOLVE

Steps to Reproduce the Problem

Declare aws-cdk as part of the dependencies in package.json (In my case I have:
"devDependencies": {
...
"@types/node": "20.5.1",
"aws-cdk": "^2.98.0",
"datadog-cdk-constructs-v2": "^1.8.1",
...
"ts-jest": "^29.1.1",
"ts-node": "^10.9.1",
"typescript": "~5.1.6"
},
"dependencies": {
"@aws-cdk/aws-glue-alpha": "^2.98.0-alpha.0",
"@aws-cdk/aws-lambda-python-alpha": "^2.98.0-alpha.0",
"aws-cdk-lib": "2.98.0",
...
Run npm install
Specifications

Node version: v18.16.0

Support ECS Tasks

It’d be great if this construct could fully configure ECS tasks for DataDog including:

  • Adding a Fluentbit router container
  • Adding the DD agent container
  • Configuring Docker labels for tags
  • Configuring the Firelens log driver
  • Creating a CloudWatch Logs Group for the Fluentbit container

I have code for this in Python if you’re interested

another test delete me

Expected Behavior

Actual Behavior

Steps to Reproduce the Problem

Specifications

  • Datadog Lambda Layer version:
  • Node version:

Stacktrace

Paste here

The Datadog class is missing from 1.7.0 in the Python cdk-v2 library

Expected Behavior

from datadog_cdk_constructs_v2 import Datadog works.

Actual Behavior

from datadog_cdk_constructs_v2 import Datadog throws an import error.

Stacktrace

Traceback (most recent call last):
File "/home/runner/work/xxxx/xxxx/app.py", line 7, in <module>
  from infra import common
File "/home/runner/work/xxxx/xxxx/infra/common.py", line 11, in <module>
  from xxx.cdk.datadog import Monitoring as DatadogMonitoring
File "/opt/hostedtoolcache/Python/3.9.16/x64/lib/python3.9/site-packages/xxx/cdk/datadog.py", line 14, in <module>
  from datadog_cdk_constructs_v2 import Datadog
ImportError: cannot import name 'Datadog' from 'datadog_cdk_constructs_v2' (/opt/hostedtoolcache/Python/3.9.16/x64/lib/python3.9/site-packages/datadog_cdk_constructs_v2/__init__.py)  ```

layer.ts silent errors

Expected Behavior

If addLayers is true but nodeLayerVersion is missing. No error is returned and datadog silently fails to add the constructs

Actual Behavior

Datadog silently fails and layers are missing

Expected Behavior

Datadog should fail with errors so the user can debug and fix their code faster

Steps to Reproduce the Problem

  1. const datadog = new Datadog(this, "DatadogLogging", {
        extensionLayerVersion: 21,
        apiKeySecretArn: `arn:aws:secretsmanager:${this.region}:${this.account}:secret:${datadogApiKeySecretArnFragment}`,
    })
    datadog.addLambdaFunctions([lambdaFunction])
    datadog.addGitCommitMetadata([lambdaFunction], gitHash)
    
  2. cdk synth (no error shows up)

Notes

Problem code:

if (pythonLayerVersion === undefined) {
errors.push(getMissingLayerVersionErrorMsg(lam.node.id, "Python", "python"));
return;
}

There are 3 spots where it silently returns without the errors. the v2 layer.ts file contains the same logic.

Unable to use construct with Datadog Extension on ARM functions

Expected Behavior

I should be able to update my Lambda functions to ARM and the Extension should work.

Looking at this issue, it appears the -ARM prefix is not being applied properly to the Datadog-Extension's ARN.

Initial glance at the source code didn't raise any red flags unless maybe the isARM value is always evaluating to false?

Below is my function's config after deploying with this construct.

Screen Shot 2022-01-03 at 1 23 35 PM

Any help or insight you can provide would be greatly appreciated. 🙏

Actual Behavior

I'm receiving errors in my Lambda Cloudwatch logs that appear to be related to the Datadog extension loading...it appears to be attempting to load an X_86 executable.

Manually updating the extension layer to ARN arn:aws:lambda:us-east-1:464622532012:layer:Datadog-Extension-ARM:16 in the Lambda console got the error to go away, though I noticed when I redeployed that the layer goes back to the non arm version.

Steps to Reproduce the Problem

  1. Updated my Lambda functions to ARM
  2. Deployed
  3. Got errors (see below) in my CloudWatch logs
  4. Updated datadog-cdk-constructions to version 0.5.0 => same issue

Specifications

  • Datadog Lambda Layer version: nodeLayerVersion 67
  • Node version: 12
  • extensionLayerVersion: 16

I'm initializing Datadog via

const datadog = new Datadog(scope, `${stageName}-Datadog`, {
  nodeLayerVersion: 67,
  extensionLayerVersion: 16,
  apiKey: globalSecrets.datadogApiKey,
  logLevel: 'debug'
});

datadog.addLambdaFunctions(arrayOfLambdaFunctionsHere);

Stacktrace

This is from my updated Lambda ARM function's CloudWatch logs.

2022-01-03T13:20:22.007-08:00 | EXTENSION Name: datadog-agent State: LaunchError Events: [] Error Type: UnknownError
-- | --
  | 2022-01-03T13:20:22.124-08:00 | START RequestId: bed92060-8704-4d2a-9313-118aa28d1415 Version: $LATEST
  | 2022-01-03T13:20:22.128-08:00 | EXTENSION Name: datadog-agent State: LaunchError Events: [] Error Type: UnknownError
  | 2022-01-03T13:20:22.128-08:00 | END RequestId: bed92060-8704-4d2a-9313-118aa28d1415
  | 2022-01-03T13:20:22.128-08:00 | REPORT RequestId: bed92060-8704-4d2a-9313-118aa28d1415 Duration: 3.39 ms Billed Duration: 4 ms Memory Size: 1024 MB Max Memory Used: 3 MB
  | 2022-01-03T13:20:22.128-08:00 | RequestId: bed92060-8704-4d2a-9313-118aa28d1415 Error: fork/exec /opt/extensions/datadog-agent: exec format error Extension.LaunchError

v0.4.0 Now requires (2) additional dependencies "@aws-cdk/aws-lambda-nodejs" and "@aws-cdk/aws-lambda-python"

Expected Behavior

Clean build after upgrading to v0.4.0

Actual Behavior

Migrating from v0.3.0 to v0.4.0 results in a breaking change. Previously, my project did not require "@aws-cdk/aws-lambda-nodejs" and "@aws-cdk/aws-lambda-python" (which I do not use anyway), but after upgrading to v0.4.0, I get:

node_modules/datadog-cdk-constructs/lib/datadog.d.ts(2,31): error TS2307: Cannot find module '@aws-cdk/aws-lambda-nodejs' or its corresponding type declarations. node_modules/datadog-cdk-constructs/lib/datadog.d.ts(3,31): error TS2307: Cannot find module '@aws-cdk/aws-lambda-python' or its corresponding type declarations.

Steps to Reproduce the Problem

  1. Starting with a project with v0.3.0 and without the mentioned dependencies, upgrade to v0.4.0 and perform a new build

Specifications

  • Datadog Lambda Layer version: 9
  • Node version: 62

Stacktrace

`node_modules/datadog-cdk-constructs/lib/datadog.d.ts(2,31): error TS2307: Cannot find module '@aws-cdk/aws-lambda-nodejs' or its corresponding type declarations.
node_modules/datadog-cdk-constructs/lib/datadog.d.ts(3,31): error TS2307: Cannot find module '@aws-cdk/aws-lambda-python' or its corresponding type declarations.`

Error when trying to install 1.1.0

Expected Behavior

Installs correctly

Actual Behavior

Error on npm install

npm ERR! code 1
npm ERR! path /Users/martin/projects/es-cdk-constructs/node_modules/datadog-cdk-constructs-v2
npm ERR! command failed
npm ERR! command sh -c -- npx projen preinstall
npm ERR! Unknown command: preinstall

Steps to Reproduce the Problem

  1. Change package.json to "datadog-cdk-constructs-v2": "^1.1.0",
  2. Run npm install
  3. Get error

Specifications

  • Datadog Lambda Layer version: N/A
  • Node version: 18.12.1

Stacktrace

npm ERR! path /Users/martin/projects/es-cdk-constructs/node_modules/datadog-cdk-constructs-v2
npm ERR! command failed
npm ERR! command sh -c -- npx projen preinstall
npm ERR! Unknown command: preinstall

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.