Skip to content

Commit

Permalink
wip supporting java, dotnet, and universal instrumentation
Browse files Browse the repository at this point in the history
  • Loading branch information
astuyve committed Dec 7, 2023
1 parent 9b10690 commit 4e866c5
Show file tree
Hide file tree
Showing 4 changed files with 151 additions and 4 deletions.
7 changes: 7 additions & 0 deletions serverless/src/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,9 @@ const ddProfilingEnabledEnvVar = "DD_PROFILING_ENABLED";
const ddEncodeAuthorizerContextEnvVar = "DD_ENCODE_AUTHORIZER_CONTEXT";
const ddDecodeAuthorizerContextEnvVar = "DD_DECODE_AUTHORIZER_CONTEXT";
const ddApmFlushDeadlineMillisecondsEnvVar = "DD_APM_FLUSH_DEADLINE_MILLISECONDS";
const lambdaExecWrapperEnvVar = "AWS_LAMBDA_EXEC_WRAPPER";

const AWS_LAMBDA_EXEC_WRAPPER = "/opt/datadog_wrapper";

export const defaultConfiguration: Configuration = {
addLayers: true,
Expand Down Expand Up @@ -293,6 +296,10 @@ export function setEnvConfiguration(config: Configuration, lambdas: LambdaFuncti
envVariables[apiKeySecretArnEnvVar] = config.apiKeySecretArn;
}

if (config.extensionLayerVersion && [RuntimeType.JAVA, RuntimeType.DOTNET].includes(runtimeLookup[lambda.runtime])) {
envVariables[lambdaExecWrapperEnvVar] = AWS_LAMBDA_EXEC_WRAPPER;
}

if (config.apiKMSKey !== undefined && envVariables[apiKeyKMSEnvVar] === undefined) {
envVariables[apiKeyKMSEnvVar] = config.apiKMSKey;
}
Expand Down
30 changes: 26 additions & 4 deletions serverless/src/layer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ export const DD_GOV_ACCOUNT_ID = "002406178527";
export enum RuntimeType {
NODE,
PYTHON,
JAVA,
DOTNET,
UNSUPPORTED,
}

Expand Down Expand Up @@ -49,9 +51,13 @@ export const runtimeLookup: { [key: string]: RuntimeType } = {
"python3.9": RuntimeType.PYTHON,
"python3.10": RuntimeType.PYTHON,
"python3.11": RuntimeType.PYTHON,
"dotnet6": RuntimeType.DOTNET,
"java11": RuntimeType.JAVA,
"java17": RuntimeType.JAVA,
"java21": RuntimeType.JAVA,
};

function runtimeToLayerName(runtime: string, architecture: string): string {
function runtimeToLayerName(runtime: string, architecture: string): string | undefined {
const nodeLookup: { [key: string]: string } = {
"nodejs12.x": "Datadog-Node12-x",
"nodejs14.x": "Datadog-Node14-x",
Expand All @@ -75,16 +81,32 @@ function runtimeToLayerName(runtime: string, architecture: string): string {
"python3.10": "Datadog-Python310-ARM",
"python3.11": "Datadog-Python311-ARM",
};


if (runtimeLookup[runtime] === RuntimeType.NODE) {
return nodeLookup[runtime];
}

if (runtimeLookup[runtime] === RuntimeType.PYTHON && architectureLookup[architecture] === ArchitectureType.ARM64) {
return pythonArmLookup[runtime];
if (runtimeLookup[runtime] === RuntimeType.PYTHON) {
if (architectureLookup[architecture] === ArchitectureType.ARM64) {
return pythonArmLookup[runtime];
} else {
return pythonLookup[runtime];
}
}

if (runtimeLookup[runtime] === RuntimeType.JAVA) {
return "dd-trace-java"
}

if (runtimeLookup[runtime] === RuntimeType.DOTNET) {
if (architectureLookup[architecture] === ArchitectureType.ARM64) {
return "dd-trace-dotnet-ARM"
} else {
return "dd-trace-dotnet"
}
}

return pythonLookup[runtime];
}

/**
Expand Down
82 changes: 82 additions & 0 deletions serverless/test/env.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -542,6 +542,88 @@ describe("setEnvConfiguration", () => {
`\`apiKeySecretArn\` is not supported for Node runtimes (${lambda.properties.FunctionName}) when using Synchronous Metrics. Use either \`apiKey\` or \`apiKmsKey\`.`,
);
});

it("sets java vars with simple config and extension", () => {
const lambda: LambdaFunction = {
properties: {
Handler: "com.lambda_handler.Handler",
Runtime: "java21",
Role: "role-arn",
Code: {},
},
key: "FunctionKey",
runtimeType: RuntimeType.JAVA,
runtime: "java21",
architecture: "x86_64",
architectureType: ArchitectureType.x86_64,
};
const config = {
apiKey: "1234",
extensionLayerVersion: 13,
service: "my-service",
env: "test",
version: "1",
tags: "team:avengers,project:marvel",
};
setEnvConfiguration({ ...defaultConfiguration, ...config }, [lambda]);

expect(lambda.properties.Environment).toEqual({
Variables: {
DD_API_KEY: "1234",
DD_CAPTURE_LAMBDA_PAYLOAD: false,
DD_ENHANCED_METRICS: true,
DD_FLUSH_TO_LOG: true,
DD_SITE: "datadoghq.com",
DD_ENV: "test",
DD_SERVICE: "my-service",
DD_VERSION: "1",
DD_TAGS: "team:avengers,project:marvel",
DD_SERVERLESS_LOGS_ENABLED: true,
AWS_LAMBDA_EXEC_WRAPPER: "/opt/datadog_wrapper",
},
});
});

it("sets dotnet vars with simple config and extension", () => {
const lambda: LambdaFunction = {
properties: {
Handler: "Lambda::Lambda.Function::Handler",
Runtime: "dotnet6",
Role: "role-arn",
Code: {},
},
key: "FunctionKey",
runtimeType: RuntimeType.DOTNET,
runtime: "dotnet6",
architecture: "x86_64",
architectureType: ArchitectureType.x86_64,
};
const config = {
apiKey: "1234",
extensionLayerVersion: 13,
service: "my-service",
env: "test",
version: "1",
tags: "team:avengers,project:marvel",
};
setEnvConfiguration({ ...defaultConfiguration, ...config }, [lambda]);

expect(lambda.properties.Environment).toEqual({
Variables: {
DD_API_KEY: "1234",
DD_CAPTURE_LAMBDA_PAYLOAD: false,
DD_ENHANCED_METRICS: true,
DD_FLUSH_TO_LOG: true,
DD_SITE: "datadoghq.com",
DD_ENV: "test",
DD_SERVICE: "my-service",
DD_VERSION: "1",
DD_TAGS: "team:avengers,project:marvel",
DD_SERVERLESS_LOGS_ENABLED: true,
AWS_LAMBDA_EXEC_WRAPPER: "/opt/datadog_wrapper",
},
});
})
});

describe("validateParameters", () => {
Expand Down
36 changes: 36 additions & 0 deletions serverless/test/layer.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ describe("findLambdas", () => {
Python310Function: mockFunctionResource("python3.10", ["x86_64"]),
Python311Function: mockFunctionResource("python3.11", ["x86_64"]),
GoFunction: mockFunctionResource("go1.10", ["x86_64"]),
Java11Function: mockFunctionResource("java11", ["x86_64"]),
Java17Function: mockFunctionResource("java17", ["x86_64"]),
Java21Function: mockFunctionResource("java21", ["x86_64"]),
Dotnet6Function: mockFunctionResource("dotnet6", ["x86_64"]),
RefFunction: mockFunctionResource({ Ref: "ValueRef" }, ["arm64"]),
};
const lambdas = findLambdas(resources, { ValueRef: "nodejs14.x" });
Expand All @@ -78,6 +82,10 @@ describe("findLambdas", () => {
mockLambdaFunction("Python39Function", "python3.9", RuntimeType.PYTHON, "x86_64", ArchitectureType.x86_64),
mockLambdaFunction("Python310Function", "python3.10", RuntimeType.PYTHON, "x86_64", ArchitectureType.x86_64),
mockLambdaFunction("Python311Function", "python3.11", RuntimeType.PYTHON, "x86_64", ArchitectureType.x86_64),
mockLambdaFunction("Java11Function", "java11", RuntimeType.JAVA, "x86_64", ArchitectureType.x86_64),
mockLambdaFunction("Java17Function", "java17", RuntimeType.JAVA, "x86_64", ArchitectureType.x86_64),
mockLambdaFunction("Java21Function", "java21", RuntimeType.JAVA, "x86_64", ArchitectureType.x86_64),
mockLambdaFunction("Dotnet6Function", "dotnet6", RuntimeType.DOTNET, "x86_64", ArchitectureType.x86_64),
mockLambdaFunction("GoFunction", "go1.10", RuntimeType.UNSUPPORTED, "x86_64", ArchitectureType.x86_64),
mockLambdaFunction("RefFunction", "nodejs14.x", RuntimeType.NODE, "arm64", ArchitectureType.ARM64, {
Ref: "ValueRef",
Expand Down Expand Up @@ -202,6 +210,34 @@ describe("applyLayers", () => {
`arn:aws:lambda:${region}:${DD_ACCOUNT_ID}:layer:Datadog-Extension-ARM:${extensionLayerVersion}`,
]);
});

it("applies the java and extension lambda layers", () => {
const lambda = mockLambdaFunction("FunctionKey", "java21", RuntimeType.JAVA, "x86_64");
const region = "us-east-1";
const javaLayerVersion = 8;
const extensionLayerVersion = 49;
const errors = applyLayers(region, [lambda], undefined, javaLayerVersion, extensionLayerVersion);

expect(errors.length).toEqual(0);
expect(lambda.properties.Layers).toEqual([
`arn:aws:lambda:${region}:${DD_ACCOUNT_ID}:layer:dd-trace-java:${javaLayerVersion}`,
`arn:aws:lambda:${region}:${DD_ACCOUNT_ID}:layer:Datadog-Extension:${extensionLayerVersion}`,
]);
});

it("applies the dotnet and extension lambda layers for arm", () => {
const lambda = mockLambdaFunction("FunctionKey", "dotnet6", RuntimeType.DOTNET, "arm64", ArchitectureType.ARM64);
const region = "us-east-1";
const dotnetLayerVersion = 6;
const extensionLayerVersion = 6;
const errors = applyLayers(region, [lambda], undefined, dotnetLayerVersion, extensionLayerVersion);

expect(errors.length).toEqual(0);
expect(lambda.properties.Layers).toEqual([
`arn:aws:lambda:${region}:${DD_ACCOUNT_ID}:layer:dd-trace-dotnet-ARM:${dotnetLayerVersion}`,
`arn:aws:lambda:${region}:${DD_ACCOUNT_ID}:layer:Datadog-Extension-ARM:${extensionLayerVersion}`,
]);
});
});

describe("getNewLayers", () => {
Expand Down

0 comments on commit 4e866c5

Please sign in to comment.