import Service from "serverless/classes/Service" ; import { FunctionInfo , runtimeLookup , RuntimeType } from "./layer" ; export interface Configuration { enabled ? : boolean ; addLayers : boolean ; apiKey ? : string ; appKey ? : string ; monitorsApiKey ? : string ; monitorsAppKey ? : string ; apiKeySecretArn ? : string ; apiKMSKey ? : string ; captureLambdaPayload ? : boolean ; site : string ; logLevel : string | undefined ; flushMetricsToLogs : boolean ; enableXrayTracing : boolean ; enableDDTracing : boolean ; enableDDLogs : boolean ; addExtension : boolean ; forwarderArn ? : string ; forwarder ? : string ; integrationTesting ? : boolean ; enableTags : boolean ; injectLogContext : boolean ; enableSourceCodeIntegration : boolean ; exclude : string [ ] ; monitors ? : { [ id ] : { [ key ] : any ; } ; } [ ] ; subscribeToAccessLogs : boolean ; subscribeToExecutionLogs : boolean ; customHandler ? : string ; } const webpackPluginName = "serverless-webpack" ; const apiKeyEnvVar = "DD_API_KEY" ; const apiKeyKMSEnvVar = "DD_KMS_API_KEY" ; const apiKeySecretArnEnvVar = "DD_API_KEY_SECRET_ARN" ; const siteURLEnvVar = "DD_SITE" ; const logLevelEnvVar = "DD_LOG_LEVEL" ; const logForwardingEnvVar = "DD_FLUSH_TO_LOG" ; const ddTracingEnabledEnvVar = "DD_TRACE_ENABLED" ; const logInjectionEnvVar = "DD_LOGS_INJECTION" ; const ddLogsEnabledEnvVar = "DD_SERVERLESS_LOGS_ENABLED" ; const ddCaptureLambdaPayloadEnvVar = "DD_CAPTURE_LAMBDA_PAYLOAD" ; export const ddTagsEnvVar = "DD_TAGS" ; export const defaultConfiguration = { addLayers : true , flushMetricsToLogs : true , logLevel : undefined , site : "datadoghq.com" , enableXrayTracing : false , enableDDTracing : true , addExtension : false , enableTags : true , injectLogContext : true , enableSourceCodeIntegration : true , exclude : [ ] , integrationTesting : false , subscribeToAccessLogs : true , subscribeToExecutionLogs : false , enableDDLogs : true , captureLambdaPayload : false , } ; export function setEnvConfiguration ( config , handlers ) { handlers . forEach ( ( { handler } ) => { handler . environment ??= { } ; const environment = handler . environment as any ; if ( process . env . DATADOG_API_KEY !== undefined && environment [ apiKeyEnvVar ] === undefined && config . apiKMSKey === undefined && config . apiKey === undefined && config . apiKeySecretArn === undefined ) { environment [ apiKeyEnvVar ] = process . env . DATADOG_API_KEY ; } if ( config . apiKey !== undefined && environment [ apiKeyEnvVar ] === undefined ) { environment [ apiKeyEnvVar ] = config . apiKey ; } if ( config . apiKMSKey !== undefined && environment [ apiKeyKMSEnvVar ] === undefined ) { environment [ apiKeyKMSEnvVar ] = config . apiKMSKey ; } if ( config . apiKeySecretArn !== undefined && environment [ apiKeySecretArnEnvVar ] === undefined ) { const isNode = runtimeLookup [ handler . runtime ! ] === RuntimeType . NODE ; const isSendingSynchronousMetrics = ! config . addExtension && ! config . flushMetricsToLogs ; if ( isSendingSynchronousMetrics && isNode ) { throw new Error ( "`apiKeySecretArn` is not supported for Node runtimes when using Synchronous Metrics. Set DATADOG_API_KEY in your environment, or use `apiKmsKey` in the configuration." ) ; } environment [ apiKeySecretArnEnvVar ] = config . apiKeySecretArn ; } if ( environment [ siteURLEnvVar ] === undefined ) { environment [ siteURLEnvVar ] = config . site ; } if ( environment [ logLevelEnvVar ] === undefined ) { environment [ logLevelEnvVar ] = config . logLevel ; } if ( environment [ logForwardingEnvVar ] === undefined && config . addExtension === false ) { environment [ logForwardingEnvVar ] = config . flushMetricsToLogs ; } if ( config . enableDDTracing !== undefined && environment [ ddTracingEnabledEnvVar ] === undefined ) { environment [ ddTracingEnabledEnvVar ] = config . enableDDTracing ; } if ( config . injectLogContext !== undefined && environment [ logInjectionEnvVar ] === undefined ) { environment [ logInjectionEnvVar ] = config . injectLogContext ; } if ( config . enableDDLogs !== undefined && environment [ ddLogsEnabledEnvVar ] === undefined ) { environment [ ddLogsEnabledEnvVar ] = config . enableDDLogs ; } if ( environment [ ddCaptureLambdaPayloadEnvVar ] === undefined ) { environment [ ddCaptureLambdaPayloadEnvVar ] = config . captureLambdaPayload ; } } ) ; } export function getConfig ( service ) { let custom = service . custom as any ; if ( custom === undefined ) { custom = { } ; } let datadog = custom . datadog as Partial < Configuration > | undefined ; if ( datadog === undefined ) { datadog = { } ; } if ( custom ?. datadog ?. monitorsApiKey ) { datadog . apiKey = custom ?. datadog ?. monitorsApiKey ?? datadog . apiKey ; } if ( custom ?. datadog ?. monitorsAppKey ) { datadog . appKey = custom ?. datadog ?. monitorsAppKey ?? datadog . appKey ; } const config = { ... defaultConfiguration , ... datadog , } ; return config ; } export function forceExcludeDepsFromWebpack ( service ) { const includeModules = getPropertyFromPath ( service , [ "custom" , "webpack" , "includeModules" ] ) ; if ( includeModules === undefined ) { return ; } let forceExclude = includeModules . forceExclude as string [ ] | undefined ; if ( forceExclude === undefined ) { forceExclude = [ ] ; includeModules . forceExclude = forceExclude ; } if ( ! forceExclude . includes ( "datadog-lambda-js" ) ) { forceExclude . push ( "datadog-lambda-js" ) ; } if ( ! forceExclude . includes ( "dd-trace" ) ) { forceExclude . push ( "dd-trace" ) ; } } function getPropertyFromPath ( obj , path ) { for ( const part of path ) { let prop = obj [ part ] ; if ( prop === undefined || prop === true ) { prop = { } ; obj [ part ] = prop ; } if ( prop === false ) { return ; } obj = prop ; } return obj ; } export function hasWebpackPlugin ( service ) { const plugins = ( service as any ) . plugins ; if ( plugins === undefined ) { return false ; } if ( Array . isArray ( plugins ) ) { return plugins . find ( ( plugin ) => plugin === webpackPluginName ) !== undefined ; } const modules = ( service as any ) . plugins . modules ; if ( modules === undefined ) { return false ; } return modules . find ( ( plugin ) => plugin === webpackPluginName ) !== undefined ; }