dd-trace 2.24.0 → 2.25.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE-3rdparty.csv +1 -0
- package/index.d.ts +16 -0
- package/package.json +6 -4
- package/packages/datadog-instrumentations/src/helpers/register.js +7 -0
- package/packages/datadog-instrumentations/src/mocha.js +33 -8
- package/packages/datadog-instrumentations/src/pg.js +6 -1
- package/packages/datadog-plugin-http/src/client.js +1 -1
- package/packages/datadog-plugin-jest/src/index.js +2 -2
- package/packages/datadog-plugin-mocha/src/index.js +2 -2
- package/packages/datadog-plugin-pg/src/index.js +1 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/vulnerability-analyzer.js +6 -6
- package/packages/dd-trace/src/appsec/iast/index.js +8 -3
- package/packages/dd-trace/src/appsec/iast/overhead-controller.js +20 -1
- package/packages/dd-trace/src/appsec/iast/taint-tracking/csi-methods.js +6 -1
- package/packages/dd-trace/src/appsec/iast/taint-tracking/taint-tracking-impl.js +24 -6
- package/packages/dd-trace/src/appsec/iast/vulnerability-reporter.js +63 -41
- package/packages/dd-trace/src/appsec/recommended.json +75 -8
- package/packages/dd-trace/src/appsec/remote_config/manager.js +2 -2
- package/packages/dd-trace/src/config.js +24 -5
- package/packages/dd-trace/src/exporters/common/request.js +33 -1
- package/packages/dd-trace/src/format.js +5 -1
- package/packages/dd-trace/src/lambda/handler.js +72 -0
- package/packages/dd-trace/src/lambda/index.js +5 -0
- package/packages/dd-trace/src/lambda/runtime/errors.js +20 -0
- package/packages/dd-trace/src/lambda/runtime/patch.js +74 -0
- package/packages/dd-trace/src/lambda/runtime/ritm.js +143 -0
- package/packages/dd-trace/src/plugin_manager.js +4 -0
- package/packages/dd-trace/src/plugins/ci_plugin.js +6 -0
- package/packages/dd-trace/src/plugins/database.js +4 -4
- package/packages/dd-trace/src/plugins/log_plugin.js +2 -2
- package/packages/dd-trace/src/plugins/util/ci.js +5 -2
- package/packages/dd-trace/src/plugins/util/test.js +2 -2
- package/packages/dd-trace/src/plugins/util/user-provided-git.js +14 -1
- package/packages/dd-trace/src/priority_sampler.js +6 -2
- package/packages/dd-trace/src/proxy.js +4 -3
- package/packages/dd-trace/src/ritm.js +7 -1
- package/packages/dd-trace/src/span_processor.js +13 -0
- package/packages/dd-trace/src/span_sampler.js +1 -4
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": "2.2",
|
|
3
3
|
"metadata": {
|
|
4
|
-
"rules_version": "1.4.
|
|
4
|
+
"rules_version": "1.4.3"
|
|
5
5
|
},
|
|
6
6
|
"rules": [
|
|
7
7
|
{
|
|
@@ -1802,7 +1802,7 @@
|
|
|
1802
1802
|
"address": "server.request.path_params"
|
|
1803
1803
|
}
|
|
1804
1804
|
],
|
|
1805
|
-
"regex": "^(?i:file|ftps?|
|
|
1805
|
+
"regex": "^(?i:file|ftps?|http)://.*?\\?+$",
|
|
1806
1806
|
"options": {
|
|
1807
1807
|
"case_sensitive": true,
|
|
1808
1808
|
"min_length": 4
|
|
@@ -2694,8 +2694,9 @@
|
|
|
2694
2694
|
"address": "grpc.server.request.message"
|
|
2695
2695
|
}
|
|
2696
2696
|
],
|
|
2697
|
-
"regex": "\\b(?:s(?:e(?:t(?:_(?:e(?:xception|rror)_handler|magic_quotes_runtime|include_path)|defaultstub)|ssion_s(?:et_save_handler|tart))|qlite_(?:(?:(?:unbuffered|single|array)_)?query|create_(?:aggregate|function)|p?open|exec)|tr(?:eam_(?:context_create|socket_client)|ipc?slashes|rev)|implexml_load_(?:string|file)|ocket_c(?:onnect|reate)|h(?:ow_sourc|a1_fil)e|pl_autoload_register|ystem)|p(?:r(?:eg_(?:replace(?:_callback(?:_array)?)?|match(?:_all)?|split)|oc_(?:(?:terminat|clos|nic)e|get_status|open)|int_r)|o(?:six_(?:get(?:(?:e[gu]|g)id|login|pwnam)|mk(?:fifo|nod)|ttyname|kill)|pen)|hp(?:_(?:strip_whitespac|unam)e|version|info)|g_(?:(?:execut|prepar)e|connect|query)|a(?:rse_(?:ini_file|str)|ssthru)|utenv)|r(?:unkit_(?:function_(?:re(?:defin|nam)e|copy|add)|method_(?:re(?:defin|nam)e|copy|add)|constant_(?:redefine|add))|e(?:(?:gister_(?:shutdown|tick)|name)_function|ad(?:(?:gz)?file|_exif_data|dir))|awurl(?:de|en)code)|i(?:mage(?:createfrom(?:(?:jpe|pn)g|x[bp]m|wbmp|gif)|(?:jpe|pn)g|g(?:d2?|if)|2?wbmp|xbm)|s_(?:(?:(?:execut|write?|read)ab|fi)le|dir)|ni_(?:get(?:_all)?|set)|terator_apply|ptcembed)|g(?:et(?:_(?:c(?:urrent_use|fg_va)r|meta_tags)|my(?:[gpu]id|inode)|(?:lastmo|cw)d|imagesize|env)|z(?:(?:(?:defla|wri)t|encod|fil)e|compress|open|read)|lob)|a(?:rray_(?:u(?:intersect(?:_u?assoc)?|diff(?:_u?assoc)?)|intersect_u(?:assoc|key)|diff_u(?:assoc|key)|filter|reduce|map)|ssert(?:_options)?|lert|tob)|h(?:tml(?:specialchars(?:_decode)?|_entity_decode|entities)|(?:ash(?:_(?:update|hmac))?|ighlight)_file|e(?:ader_register_callback|x2bin))|f(?:i(?:le(?:(?:[acm]tim|inod)e|(?:_exist|perm)s|group)?|nfo_open)|tp_(?:nb_(?:ge|pu)|connec|ge|pu)t|(?:unction_exis|pu)ts|write|open)|o(?:b_(?:get_(?:c(?:ontents|lean)|flush)|end_(?:clean|flush)|clean|flush|start)|dbc_(?:result(?:_all)?|exec(?:ute)?|connect)|pendir)|m(?:b_(?:ereg(?:_(?:replace(?:_callback)?|match)|i(?:_replace)?)?|parse_str)|(?:ove_uploaded|d5)_file|ethod_exists|ysql_query|kdir)|e(?:x(?:if_(?:t(?:humbnail|agname)|imagetype|read_data)|ec)|scapeshell(?:arg|cmd)|rror_reporting|val)|c(?:url_(?:file_create|exec|init)|onvert_uuencode|reate_function|hr)|u(?:n(?:serialize|pack)|rl(?:de|en)code|[ak]?sort)|b(?:(?:son_(?:de|en)|ase64_en)code|zopen|toa)|(?:json_(?:de|en)cod|debug_backtrac|tmpfil)e|var_dump)(?:\\s|/\\*.*\\*/|//.*|#.*|\\\")*\\(.*\\)",
|
|
2697
|
+
"regex": "\\b(?:s(?:e(?:t(?:_(?:e(?:xception|rror)_handler|magic_quotes_runtime|include_path)|defaultstub)|ssion_s(?:et_save_handler|tart))|qlite_(?:(?:(?:unbuffered|single|array)_)?query|create_(?:aggregate|function)|p?open|exec)|tr(?:eam_(?:context_create|socket_client)|ipc?slashes|rev)|implexml_load_(?:string|file)|ocket_c(?:onnect|reate)|h(?:ow_sourc|a1_fil)e|pl_autoload_register|ystem)|p(?:r(?:eg_(?:replace(?:_callback(?:_array)?)?|match(?:_all)?|split)|oc_(?:(?:terminat|clos|nic)e|get_status|open)|int_r)|o(?:six_(?:get(?:(?:e[gu]|g)id|login|pwnam)|mk(?:fifo|nod)|ttyname|kill)|pen)|hp(?:_(?:strip_whitespac|unam)e|version|info)|g_(?:(?:execut|prepar)e|connect|query)|a(?:rse_(?:ini_file|str)|ssthru)|utenv)|r(?:unkit_(?:function_(?:re(?:defin|nam)e|copy|add)|method_(?:re(?:defin|nam)e|copy|add)|constant_(?:redefine|add))|e(?:(?:gister_(?:shutdown|tick)|name)_function|ad(?:(?:gz)?file|_exif_data|dir))|awurl(?:de|en)code)|i(?:mage(?:createfrom(?:(?:jpe|pn)g|x[bp]m|wbmp|gif)|(?:jpe|pn)g|g(?:d2?|if)|2?wbmp|xbm)|s_(?:(?:(?:execut|write?|read)ab|fi)le|dir)|ni_(?:get(?:_all)?|set)|terator_apply|ptcembed)|g(?:et(?:_(?:c(?:urrent_use|fg_va)r|meta_tags)|my(?:[gpu]id|inode)|(?:lastmo|cw)d|imagesize|env)|z(?:(?:(?:defla|wri)t|encod|fil)e|compress|open|read)|lob)|a(?:rray_(?:u(?:intersect(?:_u?assoc)?|diff(?:_u?assoc)?)|intersect_u(?:assoc|key)|diff_u(?:assoc|key)|filter|reduce|map)|ssert(?:_options)?|lert|tob)|h(?:tml(?:specialchars(?:_decode)?|_entity_decode|entities)|(?:ash(?:_(?:update|hmac))?|ighlight)_file|e(?:ader_register_callback|x2bin))|f(?:i(?:le(?:(?:[acm]tim|inod)e|(?:_exist|perm)s|group)?|nfo_open)|tp_(?:nb_(?:ge|pu)|connec|ge|pu)t|(?:unction_exis|pu)ts|write|open)|o(?:b_(?:get_(?:c(?:ontents|lean)|flush)|end_(?:clean|flush)|clean|flush|start)|dbc_(?:result(?:_all)?|exec(?:ute)?|connect)|pendir)|m(?:b_(?:ereg(?:_(?:replace(?:_callback)?|match)|i(?:_replace)?)?|parse_str)|(?:ove_uploaded|d5)_file|ethod_exists|ysql_query|kdir)|e(?:x(?:if_(?:t(?:humbnail|agname)|imagetype|read_data)|ec)|scapeshell(?:arg|cmd)|rror_reporting|val)|c(?:url_(?:file_create|exec|init)|onvert_uuencode|reate_function|hr)|u(?:n(?:serialize|pack)|rl(?:de|en)code|[ak]?sort)|b(?:(?:son_(?:de|en)|ase64_en)code|zopen|toa)|(?:json_(?:de|en)cod|debug_backtrac|tmpfil)e|var_dump)(?:\\s|/\\*.*\\*/|//.*|#.*|\\\"|')*\\((?:(?:\\s|/\\*.*\\*/|//.*|#.*)*(?:\\$\\w+|[A-Z\\d]\\w*|\\w+\\(.*\\)|\\\\?\"(?:[^\"]|\\\\\"|\"\"|\"\\+\")*\\\\?\"|\\\\?'(?:[^']|''|'\\+')*\\\\?')(?:\\s|/\\*.*\\*/|//.*|#.*)*(?:(?:::|\\.|->)(?:\\s|/\\*.*\\*/|//.*|#.*)*\\w+(?:\\(.*\\))?)?,)*(?:(?:\\s|/\\*.*\\*/|//.*|#.*)*(?:\\$\\w+|[A-Z\\d]\\w*|\\w+\\(.*\\)|\\\\?\"(?:[^\"]|\\\\\"|\"\"|\"\\+\")*\\\\?\"|\\\\?'(?:[^']|''|'\\+')*\\\\?')(?:\\s|/\\*.*\\*/|//.*|#.*)*(?:(?:::|\\.|->)(?:\\s|/\\*.*\\*/|//.*|#.*)*\\w+(?:\\(.*\\))?)?)?\\)",
|
|
2698
2698
|
"options": {
|
|
2699
|
+
"case_sensitive": true,
|
|
2699
2700
|
"min_length": 5
|
|
2700
2701
|
}
|
|
2701
2702
|
},
|
|
@@ -3524,7 +3525,7 @@
|
|
|
3524
3525
|
"address": "grpc.server.request.message"
|
|
3525
3526
|
}
|
|
3526
3527
|
],
|
|
3527
|
-
"regex": "\\b(?i:eval|settimeout|setinterval|new\\s+Function)\\s*\\(",
|
|
3528
|
+
"regex": "\\b(?i:eval|settimeout|setinterval|new\\s+Function|alert|prompt)\\s*\\([^\\)]",
|
|
3528
3529
|
"options": {
|
|
3529
3530
|
"case_sensitive": true,
|
|
3530
3531
|
"min_length": 5
|
|
@@ -3770,7 +3771,7 @@
|
|
|
3770
3771
|
"address": "grpc.server.request.message"
|
|
3771
3772
|
}
|
|
3772
3773
|
],
|
|
3773
|
-
"regex": "(?i:(?:\\[?\\$(?:(?:s(?:lic|iz)|wher)e|e(?:lemMatch|xists|q)|n(?:o[rt]|in?|e)|l(?:ike|te?)|t(?:ext|ype)|a(?:ll|nd)|jsonSchema|between|regex|x?or|div|mod)\\]?))",
|
|
3774
|
+
"regex": "(?i:(?:\\[?\\$(?:(?:s(?:lic|iz)|wher)e|e(?:lemMatch|xists|q)|n(?:o[rt]|in?|e)|l(?:ike|te?)|t(?:ext|ype)|a(?:ll|nd)|jsonSchema|between|regex|x?or|div|mod)\\]?)\\b)",
|
|
3774
3775
|
"options": {
|
|
3775
3776
|
"case_sensitive": true,
|
|
3776
3777
|
"min_length": 3
|
|
@@ -3808,7 +3809,7 @@
|
|
|
3808
3809
|
"address": "grpc.server.request.message"
|
|
3809
3810
|
}
|
|
3810
3811
|
],
|
|
3811
|
-
"regex": "(?:^[\\W\\d]+\\s*?(?:alter\\s*(?:a(?:(?:pplication\\s*rol|ggregat)e|s(?:ymmetric\\s*ke|sembl)y|u(?:thorization|dit)|vailability\\s*group)|c(?:r(?:yptographic\\s*provider|edential)|o(?:l(?:latio|um)|nversio)n|ertificate|luster)|s(?:e(?:rv(?:ice|er)|curity|quence|ssion|arch)|y(?:mmetric\\s*key|nonym)|togroup|chema)|m(?:a(?:s(?:ter\\s*key|k)|terialized)|e(?:ssage\\s*type|thod)|odule)|l(?:o(?:g(?:file\\s*group|in)|ckdown)|a(?:ngua|r)ge|ibrary)|t(?:(?:abl(?:espac)?|yp)e|r(?:igger|usted)|hreshold|ext)|p(?:a(?:rtition|ckage)|ro(?:cedur|fil)e|ermission)|d(?:i(?:mension|skgroup)|atabase|efault|omain)|r(?:o(?:l(?:lback|e)|ute)|e(?:sourc|mot)e)|f(?:u(?:lltext|nction)|lashback|oreign)|e(?:xte(?:nsion|rnal)|(?:ndpoi|ve)nt)|in(?:dex(?:type)?|memory|stance)|b(?:roker\\s*priority|ufferpool)|x(?:ml\\s*schema|srobject)|w(?:ork(?:load)?|rapper)|hi(?:erarchy|stogram)|o(?:perator|utline)|(?:nicknam|queu)e|us(?:age|er)|group|java|view)
|
|
3812
|
+
"regex": "(?:^[\\W\\d]+\\s*?(?:alter\\s*(?:a(?:(?:pplication\\s*rol|ggregat)e|s(?:ymmetric\\s*ke|sembl)y|u(?:thorization|dit)|vailability\\s*group)|c(?:r(?:yptographic\\s*provider|edential)|o(?:l(?:latio|um)|nversio)n|ertificate|luster)|s(?:e(?:rv(?:ice|er)|curity|quence|ssion|arch)|y(?:mmetric\\s*key|nonym)|togroup|chema)|m(?:a(?:s(?:ter\\s*key|k)|terialized)|e(?:ssage\\s*type|thod)|odule)|l(?:o(?:g(?:file\\s*group|in)|ckdown)|a(?:ngua|r)ge|ibrary)|t(?:(?:abl(?:espac)?|yp)e|r(?:igger|usted)|hreshold|ext)|p(?:a(?:rtition|ckage)|ro(?:cedur|fil)e|ermission)|d(?:i(?:mension|skgroup)|atabase|efault|omain)|r(?:o(?:l(?:lback|e)|ute)|e(?:sourc|mot)e)|f(?:u(?:lltext|nction)|lashback|oreign)|e(?:xte(?:nsion|rnal)|(?:ndpoi|ve)nt)|in(?:dex(?:type)?|memory|stance)|b(?:roker\\s*priority|ufferpool)|x(?:ml\\s*schema|srobject)|w(?:ork(?:load)?|rapper)|hi(?:erarchy|stogram)|o(?:perator|utline)|(?:nicknam|queu)e|us(?:age|er)|group|java|view)|union\\s*(?:(?:distin|sele)ct|all))\\b|\\b(?:(?:(?:trunc|cre|upd)at|renam)e|(?:inser|selec)t|de(?:lete|sc)|alter|load)\\s+(?:group_concat|load_file|char)\\b\\s*\\(?|[\\s(]load_file\\s*?\\(|[\\\"'`]\\s+regexp\\W)",
|
|
3812
3813
|
"options": {
|
|
3813
3814
|
"min_length": 5
|
|
3814
3815
|
}
|
|
@@ -4177,7 +4178,7 @@
|
|
|
4177
4178
|
"address": "grpc.server.request.message"
|
|
4178
4179
|
}
|
|
4179
4180
|
],
|
|
4180
|
-
"regex": "[#%$]{[^}]+[^\\w\\s][^}]+}",
|
|
4181
|
+
"regex": "[#%$]{(?:[^}]+[^\\w\\s}\\-_][^}]+|\\d+-\\d+)}",
|
|
4181
4182
|
"options": {
|
|
4182
4183
|
"case_sensitive": true
|
|
4183
4184
|
}
|
|
@@ -4352,6 +4353,38 @@
|
|
|
4352
4353
|
],
|
|
4353
4354
|
"transformers": []
|
|
4354
4355
|
},
|
|
4356
|
+
{
|
|
4357
|
+
"id": "dog-931-001",
|
|
4358
|
+
"name": "RFI: URL Payload to well known RFI target",
|
|
4359
|
+
"tags": {
|
|
4360
|
+
"type": "rfi",
|
|
4361
|
+
"category": "attack_attempt"
|
|
4362
|
+
},
|
|
4363
|
+
"conditions": [
|
|
4364
|
+
{
|
|
4365
|
+
"parameters": {
|
|
4366
|
+
"inputs": [
|
|
4367
|
+
{
|
|
4368
|
+
"address": "server.request.query"
|
|
4369
|
+
},
|
|
4370
|
+
{
|
|
4371
|
+
"address": "server.request.body"
|
|
4372
|
+
},
|
|
4373
|
+
{
|
|
4374
|
+
"address": "server.request.path_params"
|
|
4375
|
+
}
|
|
4376
|
+
],
|
|
4377
|
+
"regex": "^(?i:file|ftps?|https?).*/rfiinc\\.txt\\?+$",
|
|
4378
|
+
"options": {
|
|
4379
|
+
"case_sensitive": true,
|
|
4380
|
+
"min_length": 17
|
|
4381
|
+
}
|
|
4382
|
+
},
|
|
4383
|
+
"operator": "match_regex"
|
|
4384
|
+
}
|
|
4385
|
+
],
|
|
4386
|
+
"transformers": []
|
|
4387
|
+
},
|
|
4355
4388
|
{
|
|
4356
4389
|
"id": "nfd-000-001",
|
|
4357
4390
|
"name": "Detect common directory discovery scans",
|
|
@@ -5160,7 +5193,7 @@
|
|
|
5160
5193
|
"address": "grpc.server.request.message"
|
|
5161
5194
|
}
|
|
5162
5195
|
],
|
|
5163
|
-
"regex": "^(jar:)?(http|https):\\/\\/([0-9oq]{1,5}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}|[0-9]{1,10}
|
|
5196
|
+
"regex": "^(jar:)?(http|https):\\/\\/([0-9oq]{1,5}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}|[0-9]{1,10})(:[0-9]{1,5})?(\\/.*|)$"
|
|
5164
5197
|
},
|
|
5165
5198
|
"operator": "match_regex"
|
|
5166
5199
|
}
|
|
@@ -6417,6 +6450,40 @@
|
|
|
6417
6450
|
],
|
|
6418
6451
|
"transformers": []
|
|
6419
6452
|
},
|
|
6453
|
+
{
|
|
6454
|
+
"id": "ua0-600-56x",
|
|
6455
|
+
"name": "Datadog test scanner - blocking version: user-agent",
|
|
6456
|
+
"tags": {
|
|
6457
|
+
"type": "security_scanner",
|
|
6458
|
+
"category": "attack_attempt"
|
|
6459
|
+
},
|
|
6460
|
+
"conditions": [
|
|
6461
|
+
{
|
|
6462
|
+
"parameters": {
|
|
6463
|
+
"inputs": [
|
|
6464
|
+
{
|
|
6465
|
+
"address": "server.request.headers.no_cookies",
|
|
6466
|
+
"key_path": [
|
|
6467
|
+
"user-agent"
|
|
6468
|
+
]
|
|
6469
|
+
},
|
|
6470
|
+
{
|
|
6471
|
+
"address": "grpc.server.request.metadata",
|
|
6472
|
+
"key_path": [
|
|
6473
|
+
"dd-canary"
|
|
6474
|
+
]
|
|
6475
|
+
}
|
|
6476
|
+
],
|
|
6477
|
+
"regex": "^dd-test-scanner-log-block$"
|
|
6478
|
+
},
|
|
6479
|
+
"operator": "match_regex"
|
|
6480
|
+
}
|
|
6481
|
+
],
|
|
6482
|
+
"transformers": [],
|
|
6483
|
+
"on_match": [
|
|
6484
|
+
"block"
|
|
6485
|
+
]
|
|
6486
|
+
},
|
|
6420
6487
|
{
|
|
6421
6488
|
"id": "ua0-600-5xx",
|
|
6422
6489
|
"name": "Blind SQL Injection Brute Forcer",
|
|
@@ -9,7 +9,6 @@ const log = require('../../log')
|
|
|
9
9
|
|
|
10
10
|
const clientId = uuid()
|
|
11
11
|
|
|
12
|
-
const POLL_INTERVAL = 5e3
|
|
13
12
|
const DEFAULT_CAPABILITY = Buffer.alloc(1).toString('base64') // 0x00
|
|
14
13
|
|
|
15
14
|
// There MUST NOT exist separate instances of RC clients in a tracer making separate ClientGetConfigsRequest
|
|
@@ -18,7 +17,8 @@ class RemoteConfigManager extends EventEmitter {
|
|
|
18
17
|
constructor (config) {
|
|
19
18
|
super()
|
|
20
19
|
|
|
21
|
-
|
|
20
|
+
const pollInterval = config.remoteConfig.pollInterval * 1000
|
|
21
|
+
this.scheduler = new Scheduler((cb) => this.poll(cb), pollInterval)
|
|
22
22
|
|
|
23
23
|
this.requestOptions = {
|
|
24
24
|
url: config.url,
|
|
@@ -142,7 +142,12 @@ class Config {
|
|
|
142
142
|
process.env.AWS_LAMBDA_FUNCTION_NAME ||
|
|
143
143
|
pkg.name ||
|
|
144
144
|
'node'
|
|
145
|
-
const DD_SERVICE_MAPPING =
|
|
145
|
+
const DD_SERVICE_MAPPING = coalesce(
|
|
146
|
+
options.serviceMapping,
|
|
147
|
+
process.env.DD_SERVICE_MAPPING ? fromEntries(
|
|
148
|
+
process.env.DD_SERVICE_MAPPING.split(',').map(x => x.trim().split(':'))
|
|
149
|
+
) : {}
|
|
150
|
+
)
|
|
146
151
|
const DD_ENV = coalesce(
|
|
147
152
|
options.env,
|
|
148
153
|
process.env.DD_ENV,
|
|
@@ -271,6 +276,19 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
|
|
|
271
276
|
path.join(__dirname, 'appsec', 'templates', 'blocked.json')
|
|
272
277
|
)
|
|
273
278
|
|
|
279
|
+
const inAWSLambda = process.env.AWS_LAMBDA_FUNCTION_NAME !== undefined
|
|
280
|
+
|
|
281
|
+
const remoteConfigOptions = options.remoteConfig || {}
|
|
282
|
+
const DD_REMOTE_CONFIGURATION_ENABLED = coalesce(
|
|
283
|
+
process.env.DD_REMOTE_CONFIGURATION_ENABLED && isTrue(process.env.DD_REMOTE_CONFIGURATION_ENABLED),
|
|
284
|
+
!inAWSLambda
|
|
285
|
+
)
|
|
286
|
+
const DD_REMOTE_CONFIG_POLL_INTERVAL_SECONDS = coalesce(
|
|
287
|
+
parseInt(remoteConfigOptions.pollInterval),
|
|
288
|
+
parseInt(process.env.DD_REMOTE_CONFIG_POLL_INTERVAL_SECONDS),
|
|
289
|
+
5 // seconds
|
|
290
|
+
)
|
|
291
|
+
|
|
274
292
|
const iastOptions = options.experimental && options.experimental.iast
|
|
275
293
|
const DD_IAST_ENABLED = coalesce(
|
|
276
294
|
iastOptions &&
|
|
@@ -336,7 +354,6 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
|
|
|
336
354
|
})
|
|
337
355
|
}
|
|
338
356
|
|
|
339
|
-
const inAWSLambda = process.env.AWS_LAMBDA_FUNCTION_NAME !== undefined
|
|
340
357
|
const defaultFlushInterval = inAWSLambda ? 0 : 2000
|
|
341
358
|
|
|
342
359
|
this.tracing = !isFalse(DD_TRACING_ENABLED)
|
|
@@ -355,9 +372,7 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
|
|
|
355
372
|
this.clientIpHeader = DD_TRACE_CLIENT_IP_HEADER
|
|
356
373
|
this.plugins = !!coalesce(options.plugins, true)
|
|
357
374
|
this.service = DD_SERVICE
|
|
358
|
-
this.serviceMapping = DD_SERVICE_MAPPING
|
|
359
|
-
DD_SERVICE_MAPPING.split(',').map(x => x.trim().split(':'))
|
|
360
|
-
) : {}
|
|
375
|
+
this.serviceMapping = DD_SERVICE_MAPPING
|
|
361
376
|
this.version = DD_VERSION
|
|
362
377
|
this.dogstatsd = {
|
|
363
378
|
hostname: coalesce(dogstatsd.hostname, process.env.DD_DOGSTATSD_HOSTNAME, this.hostname),
|
|
@@ -395,6 +410,10 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
|
|
|
395
410
|
blockedTemplateHtml: DD_APPSEC_HTTP_BLOCKED_TEMPLATE_HTML,
|
|
396
411
|
blockedTemplateJson: DD_APPSEC_HTTP_BLOCKED_TEMPLATE_JSON
|
|
397
412
|
}
|
|
413
|
+
this.remoteConfig = {
|
|
414
|
+
enabled: DD_REMOTE_CONFIGURATION_ENABLED,
|
|
415
|
+
pollInterval: DD_REMOTE_CONFIG_POLL_INTERVAL_SECONDS
|
|
416
|
+
}
|
|
398
417
|
this.iast = {
|
|
399
418
|
enabled: isTrue(DD_IAST_ENABLED),
|
|
400
419
|
requestSampling: DD_IAST_REQUEST_SAMPLING,
|
|
@@ -20,16 +20,48 @@ const containerId = docker.id()
|
|
|
20
20
|
|
|
21
21
|
let activeRequests = 0
|
|
22
22
|
|
|
23
|
+
// TODO: Replace with `url.urlToHttpOptions` when supported by all versions
|
|
24
|
+
function urlToOptions (url) {
|
|
25
|
+
const agent = url.agent || http.globalAgent
|
|
26
|
+
const options = {
|
|
27
|
+
protocol: url.protocol || agent.protocol,
|
|
28
|
+
hostname: typeof url.hostname === 'string' && url.hostname.startsWith('[')
|
|
29
|
+
? url.hostname.slice(1, -1)
|
|
30
|
+
: url.hostname ||
|
|
31
|
+
url.host ||
|
|
32
|
+
'localhost',
|
|
33
|
+
hash: url.hash,
|
|
34
|
+
search: url.search,
|
|
35
|
+
pathname: url.pathname,
|
|
36
|
+
path: `${url.pathname || ''}${url.search || ''}`,
|
|
37
|
+
href: url.href
|
|
38
|
+
}
|
|
39
|
+
if (url.port !== '') {
|
|
40
|
+
options.port = Number(url.port)
|
|
41
|
+
}
|
|
42
|
+
if (url.username || url.password) {
|
|
43
|
+
options.auth = `${url.username}:${url.password}`
|
|
44
|
+
}
|
|
45
|
+
return options
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function fromUrlString (url) {
|
|
49
|
+
return typeof urlToHttpOptions === 'function'
|
|
50
|
+
? urlToOptions(new URL(url))
|
|
51
|
+
: urlParse(url)
|
|
52
|
+
}
|
|
53
|
+
|
|
23
54
|
function request (data, options, callback) {
|
|
24
55
|
if (!options.headers) {
|
|
25
56
|
options.headers = {}
|
|
26
57
|
}
|
|
27
58
|
|
|
28
59
|
if (options.url) {
|
|
29
|
-
const url = typeof options.url === 'object' ? options.url :
|
|
60
|
+
const url = typeof options.url === 'object' ? options.url : fromUrlString(options.url)
|
|
30
61
|
if (url.protocol === 'unix:') {
|
|
31
62
|
options.socketPath = url.pathname
|
|
32
63
|
} else {
|
|
64
|
+
if (!options.path) options.path = url.path
|
|
33
65
|
options.protocol = url.protocol
|
|
34
66
|
options.hostname = url.hostname
|
|
35
67
|
options.port = url.port
|
|
@@ -175,7 +175,7 @@ function addTag (meta, metrics, key, value, nested) {
|
|
|
175
175
|
metrics[key] = value.toString()
|
|
176
176
|
} else if (!Array.isArray(value) && !nested) {
|
|
177
177
|
for (const prop in value) {
|
|
178
|
-
if (!value
|
|
178
|
+
if (!hasOwn(value, prop)) continue
|
|
179
179
|
|
|
180
180
|
addTag(meta, metrics, `${key}.${prop}`, value[prop], true)
|
|
181
181
|
}
|
|
@@ -185,6 +185,10 @@ function addTag (meta, metrics, key, value, nested) {
|
|
|
185
185
|
}
|
|
186
186
|
}
|
|
187
187
|
|
|
188
|
+
function hasOwn (object, prop) {
|
|
189
|
+
return Object.prototype.hasOwnProperty.call(object, prop)
|
|
190
|
+
}
|
|
191
|
+
|
|
188
192
|
function isNodeBuffer (obj) {
|
|
189
193
|
return obj.constructor && obj.constructor.name === 'Buffer' &&
|
|
190
194
|
typeof obj.readInt8 === 'function' &&
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { channel } = require('../../../datadog-instrumentations/src/helpers/instrument')
|
|
4
|
+
const { ERROR_MESSAGE, ERROR_TYPE } = require('../constants')
|
|
5
|
+
const { ImpendingTimeout } = require('./runtime/errors')
|
|
6
|
+
|
|
7
|
+
const globalTracer = global._ddtrace
|
|
8
|
+
const tracer = globalTracer._tracer
|
|
9
|
+
const timeoutChannel = channel('apm:aws:lambda:timeout')
|
|
10
|
+
// Always crash the flushes when a message is received
|
|
11
|
+
// from this channel.
|
|
12
|
+
timeoutChannel.subscribe(_ => {
|
|
13
|
+
crashFlush()
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
let __lambdaTimeout
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Publishes to the `apm:aws:lambda:timeout` channel when
|
|
20
|
+
* the AWS Lambda run time is about to end.
|
|
21
|
+
*
|
|
22
|
+
* @param {*} context AWS Lambda context object.
|
|
23
|
+
*/
|
|
24
|
+
function checkTimeout (context) {
|
|
25
|
+
let remainingTimeInMillis = context.getRemainingTimeInMillis()
|
|
26
|
+
const apmFlushDeadline = parseInt(process.env.DD_APM_FLUSH_DEADLINE)
|
|
27
|
+
if (apmFlushDeadline && apmFlushDeadline <= remainingTimeInMillis) {
|
|
28
|
+
remainingTimeInMillis = apmFlushDeadline
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
__lambdaTimeout = setTimeout(() => {
|
|
32
|
+
timeoutChannel.publish(undefined)
|
|
33
|
+
}, remainingTimeInMillis - 50)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Grabs the current span, adds an error for an impending timeout.
|
|
38
|
+
*
|
|
39
|
+
* After that, it calls `killAll` on the tracer processor
|
|
40
|
+
* in order to kill remaining unfinished spans.
|
|
41
|
+
*
|
|
42
|
+
* Once that is done, it finishes the last span.
|
|
43
|
+
*/
|
|
44
|
+
function crashFlush () {
|
|
45
|
+
const activeSpan = tracer.scope().active()
|
|
46
|
+
const error = new ImpendingTimeout('Datadog detected an impending timeout')
|
|
47
|
+
activeSpan.addTags({
|
|
48
|
+
[ERROR_MESSAGE]: error.message,
|
|
49
|
+
[ERROR_TYPE]: error.name
|
|
50
|
+
})
|
|
51
|
+
tracer._processor.killAll()
|
|
52
|
+
activeSpan.finish()
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Patches your AWS Lambda handler function to add some tracing support.
|
|
57
|
+
*
|
|
58
|
+
* @param {*} lambdaHandler a Lambda handler function.
|
|
59
|
+
*/
|
|
60
|
+
exports.datadog = function datadog (lambdaHandler) {
|
|
61
|
+
return (...args) => {
|
|
62
|
+
const context = args[1]
|
|
63
|
+
const patched = lambdaHandler.apply(this, args)
|
|
64
|
+
checkTimeout(context)
|
|
65
|
+
|
|
66
|
+
if (patched) {
|
|
67
|
+
// clear the timeout as soon as a result is returned
|
|
68
|
+
patched.then(_ => clearTimeout(__lambdaTimeout))
|
|
69
|
+
}
|
|
70
|
+
return patched
|
|
71
|
+
}
|
|
72
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
3
|
+
*
|
|
4
|
+
* Defines custom error types throwable by the runtime.
|
|
5
|
+
*/
|
|
6
|
+
'use strict'
|
|
7
|
+
|
|
8
|
+
class ExtendedError extends Error {
|
|
9
|
+
constructor (reason) {
|
|
10
|
+
super(reason)
|
|
11
|
+
Object.setPrototypeOf(this, new.target.prototype)
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
class ImpendingTimeout extends ExtendedError {}
|
|
16
|
+
ImpendingTimeout.prototype.name = 'Impending Timeout'
|
|
17
|
+
|
|
18
|
+
module.exports = {
|
|
19
|
+
ImpendingTimeout
|
|
20
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const path = require('path')
|
|
4
|
+
|
|
5
|
+
const { _extractModuleNameAndHandlerPath, _extractModuleRootAndHandler, _getLambdaFilePath } = require('./ritm')
|
|
6
|
+
const { datadog } = require('../handler')
|
|
7
|
+
const { addHook } = require('../../../../datadog-instrumentations/src/helpers/instrument')
|
|
8
|
+
const shimmer = require('../../../../datadog-shimmer')
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Patches a Datadog Lambda module by calling `patchDatadogLambdaHandler`
|
|
12
|
+
* with the handler name `datadog`.
|
|
13
|
+
*
|
|
14
|
+
* @param {*} datadogLambdaModule node module to be patched.
|
|
15
|
+
* @returns a Datadog Lambda module with the `datadog` function from
|
|
16
|
+
* `datadog-lambda-js` patched.
|
|
17
|
+
*/
|
|
18
|
+
const patchDatadogLambdaModule = (datadogLambdaModule) => {
|
|
19
|
+
shimmer.wrap(datadogLambdaModule, 'datadog', patchDatadogLambdaHandler)
|
|
20
|
+
|
|
21
|
+
return datadogLambdaModule
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Patches a Datadog Lambda handler in order to do
|
|
26
|
+
* Datadog instrumentation by getting the Lambda handler from its
|
|
27
|
+
* arguments.
|
|
28
|
+
*
|
|
29
|
+
* @param {*} datadogHandler the Datadog Lambda handler to destructure.
|
|
30
|
+
* @returns the datadogHandler with its arguments patched.
|
|
31
|
+
*/
|
|
32
|
+
function patchDatadogLambdaHandler (datadogHandler) {
|
|
33
|
+
return (userHandler) => {
|
|
34
|
+
return datadogHandler(datadog(userHandler))
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Patches a Lambda module on the given handler path.
|
|
40
|
+
*
|
|
41
|
+
* @param {string} handlerPath path of the handler to be patched.
|
|
42
|
+
* @returns a module with the given handler path patched.
|
|
43
|
+
*/
|
|
44
|
+
const patchLambdaModule = (handlerPath) => (lambdaModule) => {
|
|
45
|
+
shimmer.wrap(lambdaModule, handlerPath, patchLambdaHandler)
|
|
46
|
+
|
|
47
|
+
return lambdaModule
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Patches a Lambda handler in order to do Datadog instrumentation.
|
|
52
|
+
*
|
|
53
|
+
* @param {*} lambdaHandler the Lambda handler to be patched.
|
|
54
|
+
* @returns a function which patches the given Lambda handler.
|
|
55
|
+
*/
|
|
56
|
+
function patchLambdaHandler (lambdaHandler) {
|
|
57
|
+
return datadog(lambdaHandler)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const lambdaTaskRoot = process.env.LAMBDA_TASK_ROOT
|
|
61
|
+
const originalLambdaHandler = process.env.DD_LAMBDA_HANDLER
|
|
62
|
+
|
|
63
|
+
if (originalLambdaHandler !== undefined) {
|
|
64
|
+
const [moduleRoot, moduleAndHandler] = _extractModuleRootAndHandler(originalLambdaHandler)
|
|
65
|
+
const [_module, handlerPath] = _extractModuleNameAndHandlerPath(moduleAndHandler)
|
|
66
|
+
|
|
67
|
+
const lambdaStylePath = path.resolve(lambdaTaskRoot, moduleRoot, _module)
|
|
68
|
+
const lambdaFilePath = _getLambdaFilePath(lambdaStylePath)
|
|
69
|
+
|
|
70
|
+
addHook({ name: lambdaFilePath }, patchLambdaModule(handlerPath))
|
|
71
|
+
} else {
|
|
72
|
+
// Instrumentation is done manually.
|
|
73
|
+
addHook({ name: 'datadog-lambda-js', versions: ['>=6.85.0'] }, patchDatadogLambdaModule)
|
|
74
|
+
}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
3
|
+
* Modifications copyright 2022 Datadog, Inc.
|
|
4
|
+
*
|
|
5
|
+
* Some functions are part of aws-lambda-nodejs-runtime-interface-client
|
|
6
|
+
* https://github.com/aws/aws-lambda-nodejs-runtime-interface-client/blob/main/src/utils/UserFunction.ts
|
|
7
|
+
*/
|
|
8
|
+
'use strict'
|
|
9
|
+
|
|
10
|
+
const fs = require('fs')
|
|
11
|
+
const path = require('path')
|
|
12
|
+
|
|
13
|
+
const log = require('../../log')
|
|
14
|
+
const Hook = require('../../../../datadog-instrumentations/src/helpers/hook')
|
|
15
|
+
const instrumentations = require('../../../../datadog-instrumentations/src/helpers/instrumentations')
|
|
16
|
+
const {
|
|
17
|
+
filename,
|
|
18
|
+
getVersion,
|
|
19
|
+
matchVersion,
|
|
20
|
+
pathSepExpr
|
|
21
|
+
} = require('../../../../datadog-instrumentations/src/helpers/register')
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Breaks the full handler string into two pieces: the module root
|
|
25
|
+
* and the actual handler string.
|
|
26
|
+
*
|
|
27
|
+
* @param {string} fullHandler user's lambda handler, commonly stored in `DD_LAMBDA_HANDLER`.
|
|
28
|
+
* @returns {string[]} an array containing the module root and the handler string.
|
|
29
|
+
*
|
|
30
|
+
* ```js
|
|
31
|
+
* _extractModuleRootAndHandler('./api/src/index.nested.handler')
|
|
32
|
+
* // => ['./api/src', 'index.nested.handler']
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
function _extractModuleRootAndHandler (fullHandler) {
|
|
36
|
+
const handlerString = path.basename(fullHandler)
|
|
37
|
+
const moduleRoot = fullHandler.substring(0, fullHandler.indexOf(handlerString))
|
|
38
|
+
|
|
39
|
+
return [moduleRoot, handlerString]
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Splits the handler string into two pieces: the module name
|
|
44
|
+
* and the path to the handler function.
|
|
45
|
+
*
|
|
46
|
+
* @param {string} handler a handler string containing the module and the handler path.
|
|
47
|
+
* @returns {string[]} an array containing the module name and the handler path.
|
|
48
|
+
*
|
|
49
|
+
* ```js
|
|
50
|
+
* _extractModuleNameAndHandlerPath('index.nested.handler')
|
|
51
|
+
* // => ['index', 'nested.handler']
|
|
52
|
+
* ```
|
|
53
|
+
*/
|
|
54
|
+
function _extractModuleNameAndHandlerPath (handler) {
|
|
55
|
+
const FUNCTION_EXPR = /^([^.]*)\.(.*)$/
|
|
56
|
+
const match = handler.match(FUNCTION_EXPR)
|
|
57
|
+
if (!match || match.length !== 3) {
|
|
58
|
+
// Malformed Handler Name
|
|
59
|
+
return // TODO: throw error
|
|
60
|
+
}
|
|
61
|
+
return [match[1], match[2]] // [module, handler-path]
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Returns the correct path of the file to be patched
|
|
66
|
+
* when required.
|
|
67
|
+
*
|
|
68
|
+
* @param {*} lambdaStylePath the path comprised of the `LAMBDA_TASK_ROOT`,
|
|
69
|
+
* the root of the module of the Lambda handler, and the module name.
|
|
70
|
+
* @returns the lambdaStylePath with the appropiate extension for the hook.
|
|
71
|
+
*/
|
|
72
|
+
function _getLambdaFilePath (lambdaStylePath) {
|
|
73
|
+
let lambdaFilePath = lambdaStylePath
|
|
74
|
+
if (fs.existsSync(lambdaStylePath + '.js')) {
|
|
75
|
+
lambdaFilePath += '.js'
|
|
76
|
+
} else if (fs.existsSync(lambdaStylePath + '.mjs')) {
|
|
77
|
+
lambdaFilePath += '.mjs'
|
|
78
|
+
} else if (fs.existsSync(lambdaStylePath + '.cjs')) {
|
|
79
|
+
lambdaFilePath += '.cjs'
|
|
80
|
+
}
|
|
81
|
+
return lambdaFilePath
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Register a hook for the Lambda handler to be executed when
|
|
86
|
+
* the file is required.
|
|
87
|
+
*/
|
|
88
|
+
const registerLambdaHook = () => {
|
|
89
|
+
const lambdaTaskRoot = process.env.LAMBDA_TASK_ROOT
|
|
90
|
+
const originalLambdaHandler = process.env.DD_LAMBDA_HANDLER
|
|
91
|
+
|
|
92
|
+
if (originalLambdaHandler !== undefined) {
|
|
93
|
+
const [moduleRoot, moduleAndHandler] = _extractModuleRootAndHandler(originalLambdaHandler)
|
|
94
|
+
const [_module] = _extractModuleNameAndHandlerPath(moduleAndHandler)
|
|
95
|
+
|
|
96
|
+
const lambdaStylePath = path.resolve(lambdaTaskRoot, moduleRoot, _module)
|
|
97
|
+
const lambdaFilePath = _getLambdaFilePath(lambdaStylePath)
|
|
98
|
+
|
|
99
|
+
Hook([lambdaFilePath], (moduleExports) => {
|
|
100
|
+
require('./patch')
|
|
101
|
+
|
|
102
|
+
for (const { hook } of instrumentations[lambdaFilePath]) {
|
|
103
|
+
try {
|
|
104
|
+
moduleExports = hook(moduleExports)
|
|
105
|
+
} catch (e) {
|
|
106
|
+
log.error(e)
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return moduleExports
|
|
111
|
+
})
|
|
112
|
+
} else {
|
|
113
|
+
const moduleToPatch = 'datadog-lambda-js'
|
|
114
|
+
Hook([moduleToPatch], (moduleExports, moduleName, moduleBaseDir) => {
|
|
115
|
+
moduleName = moduleName.replace(pathSepExpr, '/')
|
|
116
|
+
|
|
117
|
+
require('./patch')
|
|
118
|
+
|
|
119
|
+
for (const { name, file, versions, hook } of instrumentations[moduleToPatch]) {
|
|
120
|
+
const fullFilename = filename(name, file)
|
|
121
|
+
if (moduleName === fullFilename) {
|
|
122
|
+
const version = getVersion(moduleBaseDir)
|
|
123
|
+
if (matchVersion(version, versions)) {
|
|
124
|
+
try {
|
|
125
|
+
moduleExports = hook(moduleExports)
|
|
126
|
+
} catch (e) {
|
|
127
|
+
log.error(e)
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
return moduleExports
|
|
134
|
+
})
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
module.exports = {
|
|
139
|
+
_extractModuleRootAndHandler,
|
|
140
|
+
_extractModuleNameAndHandlerPath,
|
|
141
|
+
_getLambdaFilePath,
|
|
142
|
+
registerLambdaHook
|
|
143
|
+
}
|
|
@@ -9,6 +9,10 @@ const loadChannel = channel('dd-trace:instrumentation:load')
|
|
|
9
9
|
|
|
10
10
|
// instrument everything that needs Plugin System V2 instrumentation
|
|
11
11
|
require('../../datadog-instrumentations')
|
|
12
|
+
if (process.env.AWS_LAMBDA_FUNCTION_NAME !== undefined) {
|
|
13
|
+
// instrument lambda environment
|
|
14
|
+
require('./lambda')
|
|
15
|
+
}
|
|
12
16
|
|
|
13
17
|
const { DD_TRACE_DISABLED_PLUGINS } = process.env
|
|
14
18
|
|
|
@@ -16,6 +16,9 @@ module.exports = class CiPlugin extends Plugin {
|
|
|
16
16
|
super(...args)
|
|
17
17
|
|
|
18
18
|
this.addSub(`ci:${this.constructor.name}:itr-configuration`, ({ onDone }) => {
|
|
19
|
+
if (!this.tracer._exporter || !this.tracer._exporter.getItrConfiguration) {
|
|
20
|
+
return onDone({ err: new Error('CI Visibility was not initialized correctly') })
|
|
21
|
+
}
|
|
19
22
|
this.tracer._exporter.getItrConfiguration(this.testConfiguration, (err, itrConfig) => {
|
|
20
23
|
if (!err) {
|
|
21
24
|
this.itrConfig = itrConfig
|
|
@@ -25,6 +28,9 @@ module.exports = class CiPlugin extends Plugin {
|
|
|
25
28
|
})
|
|
26
29
|
|
|
27
30
|
this.addSub(`ci:${this.constructor.name}:test-suite:skippable`, ({ onDone }) => {
|
|
31
|
+
if (!this.tracer._exporter || !this.tracer._exporter.getSkippableSuites) {
|
|
32
|
+
return onDone({ err: new Error('CI Visibility was not initialized correctly') })
|
|
33
|
+
}
|
|
28
34
|
this.tracer._exporter.getSkippableSuites(this.testConfiguration, (err, skippableSuites) => {
|
|
29
35
|
onDone({ err, skippableSuites })
|
|
30
36
|
})
|