|
| 1 | +'use strict'; |
| 2 | + |
| 3 | +const ADOTSupportedTraceReporters = ['datadog']; |
| 4 | +const ADOTSupportedMetricReporters = []; |
| 5 | + |
| 6 | +// Getting the relevant reporter configurations from full publish-metrics configuration |
| 7 | + |
| 8 | +function getADOTRelevantReporterConfigs(publishMetricsConfig) { |
| 9 | + const configs = publishMetricsConfig.filter( |
| 10 | + (reporterConfig) => |
| 11 | + (ADOTSupportedTraceReporters.includes(reporterConfig.type) && |
| 12 | + reporterConfig.traces) || |
| 13 | + (ADOTSupportedMetricReporters.includes(reporterConfig.type) && |
| 14 | + reporterConfig.metrics) |
| 15 | + ); |
| 16 | + |
| 17 | + return configs; |
| 18 | +} |
| 19 | + |
| 20 | +// Resolve the configuration settings for ADOT |
| 21 | + |
| 22 | +function resolveADOTConfigSettings(options) { |
| 23 | + try { |
| 24 | + const adotConfig = getADOTConfig(options.configList); // options.configList ( array of those reporter configurations from publish-metrics config that require ADOT ) |
| 25 | + const adotEnvVars = getADOTEnvVars(options.configList, options.dotenv); // options.dotenv (object with environment variables from user provided dotenv file) |
| 26 | + return { adotConfig, adotEnvVars }; |
| 27 | + } catch (err) { |
| 28 | + throw new Error(err); |
| 29 | + } |
| 30 | +} |
| 31 | + |
| 32 | +// Assembling the configuration for ADOT (in OTel Collector format) |
| 33 | + |
| 34 | +function getADOTConfig(adotRelevantConfigs) { |
| 35 | + const translatedVendorConfigs = adotRelevantConfigs.map((config) => |
| 36 | + vendorToCollectorConfigTranslators[config.type](config) |
| 37 | + ); |
| 38 | + |
| 39 | + // Different vendors can be used for metrics and tracing so we need to merge configs from each vendor into one collector config |
| 40 | + const finalADOTConfig = JSON.parse(JSON.stringify(collectorConfigTemplate)); |
| 41 | + |
| 42 | + translatedVendorConfigs.forEach((config) => { |
| 43 | + finalADOTConfig.processors = Object.assign( |
| 44 | + finalADOTConfig.processors, |
| 45 | + config.processors |
| 46 | + ); |
| 47 | + finalADOTConfig.exporters = Object.assign( |
| 48 | + finalADOTConfig.exporters, |
| 49 | + config.exporters |
| 50 | + ); |
| 51 | + finalADOTConfig.service.pipelines = Object.assign( |
| 52 | + finalADOTConfig.service.pipelines, |
| 53 | + config.service.pipelines |
| 54 | + ); |
| 55 | + }); |
| 56 | + return finalADOTConfig; |
| 57 | +} |
| 58 | + |
| 59 | +const collectorConfigTemplate = { |
| 60 | + receivers: { |
| 61 | + otlp: { |
| 62 | + protocols: { |
| 63 | + http: { |
| 64 | + endpoint: '0.0.0.0:4318' |
| 65 | + }, |
| 66 | + grpc: { |
| 67 | + endpoint: '0.0.0.0:4317' |
| 68 | + } |
| 69 | + } |
| 70 | + } |
| 71 | + }, |
| 72 | + processors: {}, |
| 73 | + exporters: {}, |
| 74 | + service: { |
| 75 | + pipelines: {} |
| 76 | + } |
| 77 | +}; |
| 78 | + |
| 79 | +// Map of functions that translate vendor-specific configuration to OpenTelemetry Collector configuration to be used by ADOT |
| 80 | +const vendorToCollectorConfigTranslators = { |
| 81 | + datadog: (config) => { |
| 82 | + const collectorConfig = JSON.parse(JSON.stringify(collectorConfigTemplate)); |
| 83 | + if (config.traces) { |
| 84 | + collectorConfig.processors['batch/trace'] = { |
| 85 | + timeout: '10s', |
| 86 | + send_batch_max_size: 1024, |
| 87 | + send_batch_size: 200 |
| 88 | + }; |
| 89 | + collectorConfig.exporters['datadog/api'] = { |
| 90 | + traces: { |
| 91 | + trace_buffer: 100 |
| 92 | + }, |
| 93 | + api: { |
| 94 | + key: '${env:DD_API_KEY}' |
| 95 | + } |
| 96 | + }; |
| 97 | + collectorConfig.service.pipelines.traces = { |
| 98 | + receivers: ['otlp'], |
| 99 | + processors: ['batch/trace'], |
| 100 | + exporters: ['datadog/api'] |
| 101 | + }; |
| 102 | + } |
| 103 | + return collectorConfig; |
| 104 | + } |
| 105 | +}; |
| 106 | + |
| 107 | +// Handling vendor specific environment variables needed for ADOT configuration (e.g. Authentication keys/tokens that can be provided in the script ) |
| 108 | + |
| 109 | +function getADOTEnvVars(adotRelevantconfigs, dotenv) { |
| 110 | + const envVars = {}; |
| 111 | + try { |
| 112 | + adotRelevantconfigs.forEach((config) => { |
| 113 | + const vendorVars = vendorSpecificEnvVarsForCollector[config.type]( |
| 114 | + config, |
| 115 | + dotenv |
| 116 | + ); |
| 117 | + Object.assign(envVars, vendorVars); |
| 118 | + }); |
| 119 | + } catch (err) { |
| 120 | + // We warn here instead of throwing because in the future we will support providing these variables through secrets |
| 121 | + console.warn(err.message); |
| 122 | + } |
| 123 | + return envVars; |
| 124 | +} |
| 125 | + |
| 126 | +const vendorSpecificEnvVarsForCollector = { |
| 127 | + datadog: (config, dotenv) => { |
| 128 | + const apiKey = config.apiKey || dotenv?.DD_API_KEY; |
| 129 | + // We validate API key here for Datadog (for now) because it is only required if Datadog tracing is set with test running on Fargate. (for local runs user configures their own agent, and for metrics if apiKey is not provided the reporter defaults to sending data to agent) |
| 130 | + if (!apiKey) { |
| 131 | + throw new Error( |
| 132 | + "Datadog reporter Error: Missing Datadog API key. Provide it under 'apiKey' setting in your script or under 'DD_API_KEY' environment variable set in your dotenv file." |
| 133 | + ); |
| 134 | + } |
| 135 | + return { DD_API_KEY: apiKey }; |
| 136 | + } |
| 137 | +}; |
| 138 | + |
| 139 | +module.exports = { |
| 140 | + getADOTRelevantReporterConfigs, |
| 141 | + resolveADOTConfigSettings, |
| 142 | + // All func and vars below exported for testing purposes |
| 143 | + getADOTEnvVars, |
| 144 | + vendorSpecificEnvVarsForCollector, |
| 145 | + getADOTConfig, |
| 146 | + vendorToCollectorConfigTranslators, |
| 147 | + ADOTSupportedTraceReporters, |
| 148 | + ADOTSupportedMetricReporters, |
| 149 | + collectorConfigTemplate |
| 150 | +}; |
0 commit comments