diff --git a/load-test/.env b/load-test/.env new file mode 100644 index 0000000000..4e2bdb9191 --- /dev/null +++ b/load-test/.env @@ -0,0 +1,24 @@ +# overwrite any of these by defining them in the environment outside the Node.js process. +# DO NOT MODIFY THIS FILE FOR TEST PERMUTATIONS! + +# App +APP_PORT=7681 +APP_WORKERS=1 + +# Sensors +AGENT_PORT=42699 +SENSOR_ENABLED=true +TRACING_ENABLED=true +STACK_TRACE_LENGTH=20 + +# Databases +MONGODB=127.0.0.1:27017 +ELASTICSEARCH=127.0.0.1:9200 +ZOOKEEPER=127.0.0.1:2181 +KAFKA=127.0.0.1:9092 +REDIS=127.0.0.1:6379 +MYSQL_HOST=127.0.0.1 +MYSQL_PORT=3306 +MYSQL_USER=root +MYSQL_PW=nodepw +MYSQL_DB=nodedb diff --git a/load-test/.eslintrc b/load-test/.eslintrc new file mode 100644 index 0000000000..f43f07812f --- /dev/null +++ b/load-test/.eslintrc @@ -0,0 +1,3 @@ +--- + rules: + no-console: 0 diff --git a/load-test/.gitignore b/load-test/.gitignore new file mode 100644 index 0000000000..7ab615a9f1 --- /dev/null +++ b/load-test/.gitignore @@ -0,0 +1,4 @@ +result +jmeter.log +temp +heapdump* diff --git a/load-test/README.md b/load-test/README.md index 64629b5530..f42e201748 100644 --- a/load-test/README.md +++ b/load-test/README.md @@ -1,27 +1,26 @@ # Load Tests -This server provides a base to load test the Instana Node.js sensor. -## Configuration -Application specific configuration options can be found in `./src/config.js`. The most relevant one is `sensorEnabled` which controls whether or not the Node.js sensor is loaded. -## Execution +## Starting the App +The app can be started via `./runApps.bash`. It is configured via environment variables. The default values for the +environment variables can be seen in `.env`. The defaults can be easily overwritten like this `AGENT_PORT=3210 ./runApps.bash`. -### Starting required databases, messaging systems… -Start the required databases and middleware as described in the [contribution docs](https://github.com/instana/nodejs-sensor/blob/master/CONTRIBUTING.md). +### With Dummy Agent +The agent doesn't play a relevant role in the majority of load tests. For this reason, it is possible to execute the +load tests without the real agent. It can be done in the following way -### Starting the instrumented test application - -``` -cd load-test -npm run start ``` +# start the agent stub +cd nodejs-sensor +DROP_DATA=true npm run agent-stub -### Starting the load test -[JMeter](https://jmeter.apache.org/) is being used to generate the load. - -``` -./jmeter/run.sh +# start the app (in a separate terminal) +cd nodejs-sensor/load +AGENT_PORT=3210 ./runApps.bash ``` -## Results -The results of the load test can be found in `./jmeter/result/testresult`. +## Executing Load Tests + +1. [Download JMeter](https://jmeter.apache.org/download_jmeter.cgi) and extract it. Put the `bin/` directory on your path. +2. Execute a load test: `TEST=httpCallSequence ./runLoadTest.bash`. +3. Check the results: `open result/testresult/index.html`. diff --git a/load-test/jmeter/JMeter.jmx b/load-test/jmeter/JMeter.jmx deleted file mode 100644 index ede0e9f1ca..0000000000 --- a/load-test/jmeter/JMeter.jmx +++ /dev/null @@ -1,301 +0,0 @@ - - - - - - false - false - - - - - - - - continue - - false - -1 - - 150 - 10 - 1373789594000 - 1373789594000 - true - 180 - 3 - - - - - - - 127.0.0.1 - 3333 - http - - - 4 - 5000 - 30000 - - - - - - User-Agent - Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:48.0) Gecko/20100101 Firefox/48.0 - - - - - - - - - - - - - / - GET - true - false - true - false - - - - - - - - 200 - - Assertion.response_code - false - 16 - Instana Load Test - - - - - - - - - - - - /mongo - GET - true - false - true - false - - - - - - - - 200 - - Assertion.response_code - false - 16 - Instana Load Test - - - - - - - - - - - - /json - GET - true - false - true - false - - - - - - - - 200 - - Assertion.response_code - false - 16 - Instana Load Test - - - - - - - - - - - - /mysql - GET - true - false - true - false - - - - - - - - 200 - - Assertion.response_code - false - 16 - Instana Load Test - - - - - - - - - - - - /redis - GET - true - false - true - false - - - - - - - - 200 - - Assertion.response_code - false - 16 - Instana Load Test - - - - - - - - - - - - /multi - GET - true - false - true - false - - - - - - - - 200 - - Assertion.response_code - false - 16 - Instana Load Test - - - - - - - - - - - - /httpForward - GET - true - false - true - false - - - - - - - - 200 - - Assertion.response_code - false - 16 - Instana Load Test - - - - - - false - - saveConfig - - - true - true - true - - true - true - true - true - false - true - true - false - false - false - true - false - false - false - true - 0 - true - true - true - true - true - - - - - - - - diff --git a/load-test/jmeter/run.sh b/load-test/jmeter/run.sh deleted file mode 100755 index 64eb0cf687..0000000000 --- a/load-test/jmeter/run.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash -rm -rf ./result -rm ./jmeter.log -mkdir result -JVM_ARGS="-Xms1024m -Xmx2048m -XX:NewSize=512m -XX:MaxNewSize=1024m" && export JVM_ARGS && jmeter -n -t JMeter.jmx -l result/result.log -e -o result/testresult diff --git a/load-test/jmeter/user.properties b/load-test/jmeter/user.properties deleted file mode 100644 index 1a4535a5ce..0000000000 --- a/load-test/jmeter/user.properties +++ /dev/null @@ -1,7 +0,0 @@ -jmeter.reportgenerator.report_title=Instana NodeJS Load Test Results - -#Granularity of over time graphs. -jmeter.reportgenerator.overall_granularity=100 - -#Granularity of Response time distribution -jmeter.reportgenerator.graph.responseTimeDistribution.property.set_granularity=500 diff --git a/load-test/package-lock.json b/load-test/package-lock.json new file mode 100644 index 0000000000..ec32e54541 --- /dev/null +++ b/load-test/package-lock.json @@ -0,0 +1,1414 @@ +{ + "name": "load", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@risingstack/node-pre-gyp": { + "version": "0.6.35", + "resolved": "https://registry.npmjs.org/@risingstack/node-pre-gyp/-/node-pre-gyp-0.6.35.tgz", + "integrity": "sha1-o+CIg5cdzFNo2Cc0GBin92P5wLo=", + "optional": true, + "requires": { + "mkdirp": "0.5.1", + "nopt": "4.0.1", + "npmlog": "4.1.2", + "rc": "1.2.6", + "request": "2.85.0", + "rimraf": "2.6.2", + "semver": "5.4.1", + "tar": "2.2.1", + "tar-pack": "3.4.1" + } + }, + "@risingstack/v8-profiler": { + "version": "5.7.11", + "resolved": "https://registry.npmjs.org/@risingstack/v8-profiler/-/v8-profiler-5.7.11.tgz", + "integrity": "sha1-29BG3YAIS/Iy0irScIOD3t84MSI=", + "optional": true, + "requires": { + "@risingstack/node-pre-gyp": "0.6.35", + "nan": "2.10.0" + } + }, + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "optional": true + }, + "accepts": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz", + "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=", + "requires": { + "mime-types": "2.1.18", + "negotiator": "0.6.1" + } + }, + "ajv": { + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", + "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", + "requires": { + "co": "4.6.0", + "fast-deep-equal": "1.1.0", + "fast-json-stable-stringify": "2.0.0", + "json-schema-traverse": "0.3.1" + } + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8=" + }, + "aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "optional": true + }, + "are-we-there-yet": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.4.tgz", + "integrity": "sha1-u13KOCu5TwXhUZQ3PRb9O6HKEQ0=", + "optional": true, + "requires": { + "delegates": "1.0.0", + "readable-stream": "2.3.6" + } + }, + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" + }, + "asn1": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", + "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=" + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + }, + "async-hook-jl": { + "version": "1.7.6", + "resolved": "https://registry.npmjs.org/async-hook-jl/-/async-hook-jl-1.7.6.tgz", + "integrity": "sha512-gFaHkFfSxTjvoxDMYqDuGHlcRyUuamF8s+ZTtJdDzqjws4mCt7v0vuV79/E2Wr2/riMQgtG4/yUtXWs1gZ7JMg==", + "requires": { + "stack-chain": "1.3.7" + } + }, + "async-listener": { + "version": "0.6.9", + "resolved": "https://registry.npmjs.org/async-listener/-/async-listener-0.6.9.tgz", + "integrity": "sha512-E7Z2/QMs0EPt/o9wpYO/J3hmMCDdr1aVDS3ttlur5D5JlZtxhfuOwi4e7S8zbYIxA5qOOYdxfqGj97XAfdNvkQ==", + "requires": { + "semver": "5.4.1", + "shimmer": "1.1.0" + } + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" + }, + "aws4": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.7.0.tgz", + "integrity": "sha512-32NDda82rhwD9/JBCCkB+MRYDp0oSvlo2IL6rQWA10PQi7tDUM3eqMSltXmY+Oyl/7N3P3qNtAlv7X0d9bI28w==" + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "bcrypt-pbkdf": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz", + "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=", + "optional": true, + "requires": { + "tweetnacl": "0.14.5" + } + }, + "block-stream": { + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", + "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=", + "requires": { + "inherits": "2.0.3" + } + }, + "bluebird": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", + "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==" + }, + "body-parser": { + "version": "1.18.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz", + "integrity": "sha1-h2eKGdhLR9hZuDGZvVm84iKxBFQ=", + "requires": { + "bytes": "3.0.0", + "content-type": "1.0.4", + "debug": "2.6.9", + "depd": "1.1.2", + "http-errors": "1.6.3", + "iconv-lite": "0.4.19", + "on-finished": "2.3.0", + "qs": "6.5.1", + "raw-body": "2.3.2", + "type-is": "1.6.16" + } + }, + "boom": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz", + "integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=", + "requires": { + "hoek": "4.2.1" + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "1.0.0", + "concat-map": "0.0.1" + } + }, + "bunyan": { + "version": "1.8.12", + "resolved": "https://registry.npmjs.org/bunyan/-/bunyan-1.8.12.tgz", + "integrity": "sha1-8VDw9nSKvdcq6uhPBEA74u8RN5c=", + "requires": { + "dtrace-provider": "0.8.6", + "moment": "2.22.1", + "mv": "2.1.1", + "safe-json-stringify": "1.1.0" + } + }, + "bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=" + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + }, + "cls-bluebird": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cls-bluebird/-/cls-bluebird-2.1.0.tgz", + "integrity": "sha1-N+8eCAqP+1XC9BZPU28ZGeeWiu4=", + "requires": { + "is-bluebird": "1.0.2", + "shimmer": "1.1.0" + } + }, + "cls-hooked": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/cls-hooked/-/cls-hooked-4.2.2.tgz", + "integrity": "sha512-J4Xj5f5wq/4jAvcdgoGsL3G103BtWpZrMo8NEinRltN+xpTZdI+M38pyQqhuFU/P792xkMFvnKSf+Lm81U1bxw==", + "requires": { + "async-hook-jl": "1.7.6", + "emitter-listener": "1.1.1", + "semver": "5.4.1" + } + }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" + }, + "combined-stream": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz", + "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=", + "requires": { + "delayed-stream": "1.0.0" + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" + }, + "content-disposition": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", + "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=" + }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" + }, + "continuation-local-storage": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/continuation-local-storage/-/continuation-local-storage-3.2.1.tgz", + "integrity": "sha512-jx44cconVqkCEEyLSKWwkvUXwO561jXMa3LPjTPsm5QR22PA0/mhe33FT4Xb5y74JDvt/Cq+5lm8S8rskLv9ZA==", + "requires": { + "async-listener": "0.6.9", + "emitter-listener": "1.1.1" + } + }, + "cookie": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", + "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "cryptiles": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.2.tgz", + "integrity": "sha1-qJ+7Ig9c4l7FboxKqKT9e1sNKf4=", + "requires": { + "boom": "5.2.0" + }, + "dependencies": { + "boom": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz", + "integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==", + "requires": { + "hoek": "4.2.1" + } + } + } + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "requires": { + "assert-plus": "1.0.0" + } + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "deep-extend": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.4.2.tgz", + "integrity": "sha1-SLaZwn4zS/ifEIkr5DL25MfTSn8=", + "optional": true + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + }, + "delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", + "optional": true + }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" + }, + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" + }, + "dotenv": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-5.0.1.tgz", + "integrity": "sha512-4As8uPrjfwb7VXC+WnLCbXK7y+Ueb2B3zgNCePYfhxS1PYeaO1YTeplffTEcbfLhvFNGLAz90VvJs9yomG7bow==" + }, + "dtrace-provider": { + "version": "0.8.6", + "resolved": "https://registry.npmjs.org/dtrace-provider/-/dtrace-provider-0.8.6.tgz", + "integrity": "sha1-QooiOv4DQl0s1tY0f99AxmkDVj0=", + "optional": true, + "requires": { + "nan": "2.10.0" + } + }, + "ecc-jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", + "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=", + "optional": true, + "requires": { + "jsbn": "0.1.1" + } + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + }, + "emitter-listener": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/emitter-listener/-/emitter-listener-1.1.1.tgz", + "integrity": "sha1-6Lu+gkS8jg0LTvcc0UKUx/JBx+w=", + "requires": { + "shimmer": "1.2.0" + }, + "dependencies": { + "shimmer": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.0.tgz", + "integrity": "sha512-xTCx2vohXC2EWWDqY/zb4+5Mu28D+HYNSOuFzsyRDRvI/e1ICb69afwaUwfjr+25ZXldbOLyp+iDUZHq8UnTag==" + } + } + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" + }, + "event-loop-lag": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/event-loop-lag/-/event-loop-lag-1.3.0.tgz", + "integrity": "sha512-iudLtOrNdoWg/g+blNKypy+k0jtCSxrHUqQAqsmEYX9Cjt6sstJ2UMpXch5KI/OMcC+14WDFka5YQoL7tqzozA==", + "requires": { + "debug": "2.6.9" + } + }, + "event-loop-stats": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/event-loop-stats/-/event-loop-stats-1.0.0.tgz", + "integrity": "sha1-7GF3fqte+axXNC2cXTZtAc+Hnxk=", + "optional": true, + "requires": { + "nan": "2.10.0" + } + }, + "express": { + "version": "4.16.3", + "resolved": "https://registry.npmjs.org/express/-/express-4.16.3.tgz", + "integrity": "sha1-avilAjUNsyRuzEvs9rWjTSL37VM=", + "requires": { + "accepts": "1.3.5", + "array-flatten": "1.1.1", + "body-parser": "1.18.2", + "content-disposition": "0.5.2", + "content-type": "1.0.4", + "cookie": "0.3.1", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "1.1.2", + "encodeurl": "1.0.2", + "escape-html": "1.0.3", + "etag": "1.8.1", + "finalhandler": "1.1.1", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "1.1.2", + "on-finished": "2.3.0", + "parseurl": "1.3.2", + "path-to-regexp": "0.1.7", + "proxy-addr": "2.0.3", + "qs": "6.5.1", + "range-parser": "1.2.0", + "safe-buffer": "5.1.1", + "send": "0.16.2", + "serve-static": "1.13.2", + "setprototypeof": "1.1.0", + "statuses": "1.4.0", + "type-is": "1.6.16", + "utils-merge": "1.0.1", + "vary": "1.1.2" + } + }, + "extend": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", + "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=" + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" + }, + "fast-deep-equal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", + "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=" + }, + "fast-json-stable-stringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" + }, + "finalhandler": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz", + "integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==", + "requires": { + "debug": "2.6.9", + "encodeurl": "1.0.2", + "escape-html": "1.0.3", + "on-finished": "2.3.0", + "parseurl": "1.3.2", + "statuses": "1.4.0", + "unpipe": "1.0.0" + } + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" + }, + "form-data": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz", + "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=", + "requires": { + "asynckit": "0.4.0", + "combined-stream": "1.0.6", + "mime-types": "2.1.18" + } + }, + "forwarded": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", + "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "fstream": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz", + "integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=", + "requires": { + "graceful-fs": "4.1.11", + "inherits": "2.0.3", + "mkdirp": "0.5.1", + "rimraf": "2.6.2" + } + }, + "fstream-ignore": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/fstream-ignore/-/fstream-ignore-1.0.5.tgz", + "integrity": "sha1-nDHa40dnAY/h0kmyTa2mfQktoQU=", + "optional": true, + "requires": { + "fstream": "1.0.11", + "inherits": "2.0.3", + "minimatch": "3.0.4" + } + }, + "gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "optional": true, + "requires": { + "aproba": "1.2.0", + "console-control-strings": "1.1.0", + "has-unicode": "2.0.1", + "object-assign": "4.1.1", + "signal-exit": "3.0.2", + "string-width": "1.0.2", + "strip-ansi": "3.0.1", + "wide-align": "1.1.2" + } + }, + "gcstats.js": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/gcstats.js/-/gcstats.js-1.0.0.tgz", + "integrity": "sha1-hdGcqXvz5EIU6jR0wLYh5LehAJA=", + "optional": true, + "requires": { + "nan": "2.10.0" + } + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "requires": { + "assert-plus": "1.0.0" + } + }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" + }, + "har-validator": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz", + "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=", + "requires": { + "ajv": "5.5.2", + "har-schema": "2.0.0" + } + }, + "has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", + "optional": true + }, + "hawk": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz", + "integrity": "sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ==", + "requires": { + "boom": "4.3.1", + "cryptiles": "3.1.2", + "hoek": "4.2.1", + "sntp": "2.1.0" + } + }, + "heapdump": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/heapdump/-/heapdump-0.3.9.tgz", + "integrity": "sha1-A8dOsN9dZ74Jgug0KbqcnSs7f3g=" + }, + "hoek": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.1.tgz", + "integrity": "sha512-QLg82fGkfnJ/4iy1xZ81/9SIJiq1NGFUMGs6ParyjBZr6jW2Ufj/snDqTHixNlHdPNwN2RLVD0Pi3igeK9+JfA==" + }, + "http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", + "requires": { + "depd": "1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": "1.4.0" + } + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "requires": { + "assert-plus": "1.0.0", + "jsprim": "1.4.1", + "sshpk": "1.14.1" + } + }, + "iconv-lite": { + "version": "0.4.19", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", + "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==" + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "1.4.0", + "wrappy": "1.0.2" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "ini": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "optional": true + }, + "instana-nodejs-sensor": { + "version": "1.37.2", + "resolved": "https://registry.npmjs.org/instana-nodejs-sensor/-/instana-nodejs-sensor-1.37.2.tgz", + "integrity": "sha512-rrJt5FwOqaZ9I0dMaVdj53TGeP0DggCUividP+VPqwBK3z2YLPNltghHQQFLRE+X3yWqFQ+rbTVcmxTNxDCiwQ==", + "requires": { + "@risingstack/v8-profiler": "5.7.11", + "bunyan": "1.8.12", + "cls-bluebird": "2.1.0", + "cls-hooked": "4.2.2", + "event-loop-lag": "1.3.0", + "event-loop-stats": "1.0.0", + "gcstats.js": "1.0.0", + "opentracing": "0.14.3", + "redis-commands": "1.3.5", + "semver": "5.4.1", + "shimmer": "1.1.0" + } + }, + "ipaddr.js": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.6.0.tgz", + "integrity": "sha1-4/o1e3c9phnybpXwSdBVxyeW+Gs=" + }, + "is-bluebird": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-bluebird/-/is-bluebird-1.0.2.tgz", + "integrity": "sha1-CWQ5Bg9KpBGr7hkUOoTWpVNG1uI=" + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "requires": { + "number-is-nan": "1.0.1" + } + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "optional": true + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" + }, + "json-schema-traverse": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", + "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=" + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "lodash": { + "version": "4.17.5", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.5.tgz", + "integrity": "sha512-svL3uiZf1RwhH+cWrfZn3A4+U58wbP0tGVTLQPbjplZxZ8ROD9VLuNgsRniTlLe7OlSqR79RUehXgpBW/s0IQw==" + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" + }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" + }, + "mime": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", + "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==" + }, + "mime-db": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", + "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==" + }, + "mime-types": { + "version": "2.1.18", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", + "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", + "requires": { + "mime-db": "1.33.0" + } + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "1.1.11" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "requires": { + "minimist": "0.0.8" + } + }, + "moment": { + "version": "2.22.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.22.1.tgz", + "integrity": "sha512-shJkRTSebXvsVqk56I+lkb2latjBs8I+pc2TzWc545y2iFnSjm7Wg0QMh+ZWcdSLQyGEau5jI8ocnmkyTgr9YQ==", + "optional": true + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "mv": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz", + "integrity": "sha1-rmzg1vbV4KT32JN5jQPB6pVZtqI=", + "optional": true, + "requires": { + "mkdirp": "0.5.1", + "ncp": "2.0.0", + "rimraf": "2.4.5" + }, + "dependencies": { + "glob": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", + "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", + "optional": true, + "requires": { + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "rimraf": { + "version": "2.4.5", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz", + "integrity": "sha1-7nEM5dk6j9uFb7Xqj/Di11k0sto=", + "optional": true, + "requires": { + "glob": "6.0.4" + } + } + } + }, + "nan": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz", + "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==", + "optional": true + }, + "ncp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", + "integrity": "sha1-GVoh1sRuNh0vsSgbo4uR6d9727M=", + "optional": true + }, + "negotiator": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", + "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=" + }, + "nopt": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz", + "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=", + "optional": true, + "requires": { + "abbrev": "1.1.1", + "osenv": "0.1.5" + } + }, + "npmlog": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "optional": true, + "requires": { + "are-we-there-yet": "1.1.4", + "console-control-strings": "1.1.0", + "gauge": "2.7.4", + "set-blocking": "2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" + }, + "oauth-sign": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", + "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=" + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "optional": true + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "requires": { + "ee-first": "1.1.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1.0.2" + } + }, + "opentracing": { + "version": "0.14.3", + "resolved": "https://registry.npmjs.org/opentracing/-/opentracing-0.14.3.tgz", + "integrity": "sha1-I+OtAp+mamU5Jq2+V+g0Rp+FUKo=" + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "optional": true + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "optional": true + }, + "osenv": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", + "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "optional": true, + "requires": { + "os-homedir": "1.0.2", + "os-tmpdir": "1.0.2" + } + }, + "parseurl": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", + "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=" + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" + }, + "process-nextick-args": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" + }, + "proxy-addr": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.3.tgz", + "integrity": "sha512-jQTChiCJteusULxjBp8+jftSQE5Obdl3k4cnmLA6WXtK6XFuWRnvVL7aCiBqaLPM8c4ph0S4tKna8XvmIwEnXQ==", + "requires": { + "forwarded": "0.1.2", + "ipaddr.js": "1.6.0" + } + }, + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" + }, + "qs": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", + "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==" + }, + "range-parser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", + "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=" + }, + "raw-body": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz", + "integrity": "sha1-vNYMd9Prk83gBQKVw/N5OJvIj4k=", + "requires": { + "bytes": "3.0.0", + "http-errors": "1.6.2", + "iconv-lite": "0.4.19", + "unpipe": "1.0.0" + }, + "dependencies": { + "depd": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz", + "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=" + }, + "http-errors": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz", + "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=", + "requires": { + "depd": "1.1.1", + "inherits": "2.0.3", + "setprototypeof": "1.0.3", + "statuses": "1.4.0" + } + }, + "setprototypeof": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz", + "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=" + } + } + }, + "rc": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.6.tgz", + "integrity": "sha1-6xiYnG1PTxYsOZ953dKfODVWgJI=", + "optional": true, + "requires": { + "deep-extend": "0.4.2", + "ini": "1.3.5", + "minimist": "1.2.0", + "strip-json-comments": "2.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "optional": true + } + } + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "2.0.0", + "safe-buffer": "5.1.1", + "string_decoder": "1.1.1", + "util-deprecate": "1.0.2" + } + }, + "redis-commands": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/redis-commands/-/redis-commands-1.3.5.tgz", + "integrity": "sha512-foGF8u6MXGFF++1TZVC6icGXuMYPftKXt1FBT2vrfU9ZATNtZJ8duRC5d1lEfE8hyVe3jhelHGB91oB7I6qLsA==" + }, + "request": { + "version": "2.85.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.85.0.tgz", + "integrity": "sha512-8H7Ehijd4js+s6wuVPLjwORxD4zeuyjYugprdOXlPSqaApmL/QOy+EB/beICHVCHkGMKNh5rvihb5ov+IDw4mg==", + "requires": { + "aws-sign2": "0.7.0", + "aws4": "1.7.0", + "caseless": "0.12.0", + "combined-stream": "1.0.6", + "extend": "3.0.1", + "forever-agent": "0.6.1", + "form-data": "2.3.2", + "har-validator": "5.0.3", + "hawk": "6.0.2", + "http-signature": "1.2.0", + "is-typedarray": "1.0.0", + "isstream": "0.1.2", + "json-stringify-safe": "5.0.1", + "mime-types": "2.1.18", + "oauth-sign": "0.8.2", + "performance-now": "2.1.0", + "qs": "6.5.1", + "safe-buffer": "5.1.1", + "stringstream": "0.0.5", + "tough-cookie": "2.3.4", + "tunnel-agent": "0.6.0", + "uuid": "3.2.1" + } + }, + "request-promise-any": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/request-promise-any/-/request-promise-any-1.0.5.tgz", + "integrity": "sha1-84XE+NcVu2sBCxuZHs/UXj4v1D8=", + "requires": { + "any-promise": "1.3.0", + "request-promise-core": "1.1.1", + "stealthy-require": "1.1.1", + "tough-cookie": "2.3.4" + } + }, + "request-promise-core": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.1.tgz", + "integrity": "sha1-Pu4AssWqgyOc+wTFcA2jb4HNCLY=", + "requires": { + "lodash": "4.17.5" + } + }, + "rimraf": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", + "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", + "requires": { + "glob": "7.1.2" + } + }, + "safe-buffer": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" + }, + "safe-json-stringify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-json-stringify/-/safe-json-stringify-1.1.0.tgz", + "integrity": "sha512-EzBtUaFH9bHYPc69wqjp0efJI/DPNHdFbGE3uIMn4sVbO0zx8vZ8cG4WKxQfOpUOKsQyGBiT2mTqnCw+6nLswA==", + "optional": true + }, + "semver": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", + "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==" + }, + "send": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz", + "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==", + "requires": { + "debug": "2.6.9", + "depd": "1.1.2", + "destroy": "1.0.4", + "encodeurl": "1.0.2", + "escape-html": "1.0.3", + "etag": "1.8.1", + "fresh": "0.5.2", + "http-errors": "1.6.3", + "mime": "1.4.1", + "ms": "2.0.0", + "on-finished": "2.3.0", + "range-parser": "1.2.0", + "statuses": "1.4.0" + } + }, + "serve-static": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz", + "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==", + "requires": { + "encodeurl": "1.0.2", + "escape-html": "1.0.3", + "parseurl": "1.3.2", + "send": "0.16.2" + } + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "optional": true + }, + "setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" + }, + "shimmer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.1.0.tgz", + "integrity": "sha1-l9c3cTf/u6tCVSLkKf4KqJpIizU=" + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "optional": true + }, + "sntp": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/sntp/-/sntp-2.1.0.tgz", + "integrity": "sha512-FL1b58BDrqS3A11lJ0zEdnJ3UOKqVxawAkF3k7F0CVN7VQ34aZrV+G8BZ1WC9ZL7NyrwsW0oviwsWDgRuVYtJg==", + "requires": { + "hoek": "4.2.1" + } + }, + "sshpk": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.14.1.tgz", + "integrity": "sha1-Ew9Zde3a2WPx1W+SuaxsUfqfg+s=", + "requires": { + "asn1": "0.2.3", + "assert-plus": "1.0.0", + "bcrypt-pbkdf": "1.0.1", + "dashdash": "1.14.1", + "ecc-jsbn": "0.1.1", + "getpass": "0.1.7", + "jsbn": "0.1.1", + "tweetnacl": "0.14.5" + } + }, + "stack-chain": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/stack-chain/-/stack-chain-1.3.7.tgz", + "integrity": "sha1-0ZLJ/06moiyUxN1FkXHj8AzqEoU=" + }, + "statuses": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", + "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==" + }, + "stealthy-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", + "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=" + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "5.1.1" + } + }, + "stringstream": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", + "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=" + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "2.1.1" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "optional": true + }, + "tar": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz", + "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=", + "requires": { + "block-stream": "0.0.9", + "fstream": "1.0.11", + "inherits": "2.0.3" + } + }, + "tar-pack": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/tar-pack/-/tar-pack-3.4.1.tgz", + "integrity": "sha512-PPRybI9+jM5tjtCbN2cxmmRU7YmqT3Zv/UDy48tAh2XRkLa9bAORtSWLkVc13+GJF+cdTh1yEnHEk3cpTaL5Kg==", + "optional": true, + "requires": { + "debug": "2.6.9", + "fstream": "1.0.11", + "fstream-ignore": "1.0.5", + "once": "1.4.0", + "readable-stream": "2.3.6", + "rimraf": "2.6.2", + "tar": "2.2.1", + "uid-number": "0.0.6" + } + }, + "tough-cookie": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz", + "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==", + "requires": { + "punycode": "1.4.1" + } + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "requires": { + "safe-buffer": "5.1.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "optional": true + }, + "type-is": { + "version": "1.6.16", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz", + "integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==", + "requires": { + "media-typer": "0.3.0", + "mime-types": "2.1.18" + } + }, + "uid-number": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/uid-number/-/uid-number-0.0.6.tgz", + "integrity": "sha1-DqEOgDXo61uOREnwbaHHMGY7qoE=", + "optional": true + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" + }, + "uuid": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.2.1.tgz", + "integrity": "sha512-jZnMwlb9Iku/O3smGWvZhauCf6cvvpKi4BKRiliS3cxnI+Gz9j5MEpTz2UFuXiKPJocb7gnsLHwiS05ige5BEA==" + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "requires": { + "assert-plus": "1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "1.3.0" + } + }, + "wide-align": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.2.tgz", + "integrity": "sha512-ijDLlyQ7s6x1JgCLur53osjm/UXUYD9+0PbYKrBsYisYXzCxN+HC3mYDNy/dWdmf3AwqwU3CXwDCvsNgGK1S0w==", + "optional": true, + "requires": { + "string-width": "1.0.2" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + } + } +} diff --git a/load-test/package.json b/load-test/package.json index 30a9735be7..1beaea155b 100644 --- a/load-test/package.json +++ b/load-test/package.json @@ -1,16 +1,19 @@ { - "name": "instana-nodejs-load-test", + "name": "load", "version": "1.0.0", - "description": "Instana NodeJS Load Test", "main": "src/index.js", "scripts": { "start": "node src/index.js" }, - "devDependencies": { - "glob": "^7.1.2", - "ioredis": "^3.2.2", - "mongoose": "^5.0.11", - "mysql2": "^1.5.3", - "instana-nodejs-sensor": "^1.36.1" + "dependencies": { + "any-promise": "^1.3.0", + "bluebird": "^3.5.1", + "continuation-local-storage": "^3.2.1", + "dotenv": "^5.0.1", + "express": "^4.16.3", + "heapdump": "^0.3.9", + "instana-nodejs-sensor": "^1.37.2", + "request": "^2.85.0", + "request-promise-any": "^1.0.5" } } diff --git a/load-test/runApps.bash b/load-test/runApps.bash new file mode 100755 index 0000000000..af7825ef30 --- /dev/null +++ b/load-test/runApps.bash @@ -0,0 +1,8 @@ +#!/bin/bash + +set -eo pipefail + +APP_PORT=7681 DOWNSTREAM_PORT=7682 APP_WORKERS=1 npm start & +trap "kill $!" EXIT SIGINT SIGTERM + +APP_PORT=7682 APP_WORKERS=1 npm start diff --git a/load-test/runLoadTest.bash b/load-test/runLoadTest.bash new file mode 100755 index 0000000000..90349d51fe --- /dev/null +++ b/load-test/runLoadTest.bash @@ -0,0 +1,14 @@ +#!/bin/bash + +set -eo pipefail + +rm -rf ./result ./jmeter.log +mkdir result +export JVM_ARGS="-Xms2048m -Xmx2048m" +jmeter -n \ + -t "test/$TEST.jmx" \ + -l result/result.log \ + -e \ + -o result/testresult \ + -Jjmeter.reportgenerator.report_title="Instana Node.js Load Test" \ + -Jjmeter.reportgenerator.overall_granularity=1000 diff --git a/load-test/src/app.js b/load-test/src/app.js new file mode 100644 index 0000000000..0bba43b484 --- /dev/null +++ b/load-test/src/app.js @@ -0,0 +1,22 @@ +'use strict'; + +var express = require('express'); +var config = require('./config'); + +exports.init = function init(cb) { + require('any-promise/register/bluebird'); + + var app = express(); + + app.get('/', function(req, res) { + res.send('OK'); + }); + + app.use(require('./routes/httpCallSequence')); + + app.listen({ + host: 'localhost', + port: config.app.httpPort, + backlog: 8192 + }, cb); +}; diff --git a/load-test/src/config.js b/load-test/src/config.js index 840d5b0a56..494c6d6839 100644 --- a/load-test/src/config.js +++ b/load-test/src/config.js @@ -1,25 +1,29 @@ 'use strict'; -module.exports = { - instana: { - sensorEnabled: true, - agentPort: process.env.AGENT_PORT || null + +require('dotenv').config(); + +module.exports = exports = { + app: { + workers: getInt('APP_WORKERS'), + httpPort: getInt('APP_PORT'), + downstreamHttpPort: getInt('DOWNSTREAM_PORT') }, - server: { - port: process.env.APP_PORT || 3333 - }, - services: { - mongo: { - host: process.env.MONGODB || '127.0.0.1:27017' - }, - mysql: { - host: process.env.MYSQL_HOST || '127.0.0.1', - user: process.env.MYSQL_USER || 'root', - password: process.env.MYSQL_PW || 'nodepw', - database: process.env.MYSQL_DB || 'nodedb', - table: 'loadtest' - }, - redis: { - host: process.env.REDIS || '127.0.0.1:6379' - } + sensor: { + agentPort: getInt('AGENT_PORT'), + enabled: getBool('SENSOR_ENABLED'), + tracing: getBool('TRACING_ENABLED'), + stackTraceLength: getInt('STACK_TRACE_LENGTH') } }; + +function getInt(varName) { + var val = parseInt(process.env[varName], 10); + if (isNaN(val)) { + return null; + } + return val; +} + +function getBool(varName) { + return process.env[varName] !== 'false'; +} diff --git a/load-test/src/index.js b/load-test/src/index.js index 27d2739f7d..6a38b18b66 100644 --- a/load-test/src/index.js +++ b/load-test/src/index.js @@ -1,64 +1,48 @@ /* eslint-disable no-console */ + 'use strict'; + var config = require('./config'); +var cluster = require('cluster'); -// init instana sensor if needed for load test -if (config.instana.sensorEnabled) { - try { - require('instana-nodejs-sensor')({ - agentPort: config.instana.agentPort, - level: 'info' - }); - } catch (e) { - console.error('Sensor could not be instantiated.', e); - } + +if (config.sensor.enabled) { + require('instana-nodejs-sensor')({ + level: 'info', + agentPort: config.sensor.agentPort, + tracing: { + enabled: config.sensor.tracing, + stackTraceLength: config.sensor.stackTraceLength + } + }); +} + +require('heapdump'); + +if (cluster.isMaster && config.app.workers > 1) { + initMaster(); +} else { + initWorker(); } -var glob = require('glob'); -var path = require('path'); -var http = require('http'); -var url = require('url'); -var routes = []; -glob.sync('./src/routes/*.js').forEach(function(file) { - routes.push(require(path.resolve(file))); -}); +function initMaster() { + console.log('Master ' + process.pid + ' is running'); -var serverRoutes = routes.map(function(route) { - return { - path: route.path, - router: route.router - }; -}); + for (var i = 0; i < config.app.workers; i++) { + cluster.fork(); + } -// connect to all necessary services -Promise.all(routes.map(function(route) { - return route.connect(); -})) - // init all necessary services - .then(function() { - return Promise.all(routes.map(function(route) { - return route.init(); - })); - }) - .then(startServer) - .catch(function(error) { - console.error('Could not start load test ', error); + cluster.on('exit', function(worker) { + console.log('worker ' + worker.process.pid + ' died'); }); +} -function startServer() { - http.createServer(function(req, res) { - var parsedUrl = url.parse(req.url, true); - var route = serverRoutes.filter(function(r) { - return r.path === parsedUrl.pathname; - }); - if (route.length === 0) { - res.writeHead(200, {'Content-Type': 'text/plain'}); - res.end('Route not found.'); - } else { - route[0].router(res); - } - }).listen(config.server.port); - console.info('Load Server running => http://127.0.0.1:' + config.server.port); +function initWorker() { + console.log('Starting worker ' + process.pid); + + require('./app').init(function() { + console.log('Worker ' + process.pid + ' started'); + }); } diff --git a/load-test/src/routes/httpCallSequence.js b/load-test/src/routes/httpCallSequence.js new file mode 100644 index 0000000000..c3f8ad9eed --- /dev/null +++ b/load-test/src/routes/httpCallSequence.js @@ -0,0 +1,50 @@ +'use strict'; + +var router = module.exports = exports = require('express').Router(); +var request = require('request-promise-any'); +var Promise = require('bluebird'); +var config = require('../config'); +var http = require('http'); + +var keepAliveAgent = new http.Agent({ + keepAlive: true, + keepAliveMsecs: 5000, + // deliberately leaking sockets in the load test! + maxSockets: Infinity, + maxFreeSockets: 256 +}); + +router.get('/httpCallSequence', function(req, res) { + if (config.app.downstreamHttpPort == null) { + res.send('OK'); + return; + } + + executeDownstreamCall() + .then(function() { + return Promise.delay(100); + }) + .then(function() { + return Promise.all([ + executeDownstreamCall(), + executeDownstreamCall(), + Promise.delay(20) + ]); + }) + .then(function() { + res.sendStatus(200); + }) + .catch(function(err) { + console.log('Failed to execute call sequence:', err.message); + res.sendStatus(500); + }); +}); + +function executeDownstreamCall() { + return request({ + uri: 'http://127.0.0.1:' + config.app.downstreamHttpPort + '/httpCallSequence', + resolveWithFullResponse: true, + timeout: 3000, + agent: keepAliveAgent + }); +} diff --git a/load-test/src/routes/httpForward.js b/load-test/src/routes/httpForward.js deleted file mode 100644 index 352c880038..0000000000 --- a/load-test/src/routes/httpForward.js +++ /dev/null @@ -1,50 +0,0 @@ -/* eslint-disable no-console */ -'use strict'; - -var https = require('https'); - -exports.path = '/httpForward'; - -exports.router = function StandardRoute(res) { - // will make http calls in a sequence - Promise.resolve() - .then(function() {return callWeb();}) - .then(function() { - res.writeHead(200, {'Content-Type': 'text/plain'}); - res.end('OK.'); - }).catch(function(e) { - console.error('Error while trying to call multi call', e); - res.writeHead(500, {'Content-Type': 'text/plain'}); - res.end('Error doing Multi Call'); - }); -}; - -exports.connect = function() { - return Promise.resolve(); -}; - -exports.init = function() { - return Promise.resolve(); -}; - -function callWeb() { - return new Promise(function(resolve, reject) { - var req = https.get({ - hostname: 'instana.com', - path: '/', - timeout: 3000 - }, function(res) { - res.on('data', function() { - // without this, end is never being called....? - }); - res.on('end', function() { - resolve(); - }); - }); - req.on('error', function(err) { - console.error(err); - reject('Could not query web page.'); - }); - }); -} - diff --git a/load-test/src/routes/json.js b/load-test/src/routes/json.js deleted file mode 100644 index d31cd4ce85..0000000000 --- a/load-test/src/routes/json.js +++ /dev/null @@ -1,22 +0,0 @@ -'use strict'; - -exports.path = '/json'; - -exports.router = function StandardRoute(res) { - res.writeHead(200, {'Content-Type': 'application/json'}); - res.end(JSON.stringify({ - aNumber: 1, - aString: 'string', - anObject: {something: 'else'}, - aBoolean: true, - aDate: new Date() - })); -}; - -exports.connect = function() { - return Promise.resolve(); -}; - -exports.init = function() { - return Promise.resolve(); -}; diff --git a/load-test/src/routes/mongodb.js b/load-test/src/routes/mongodb.js deleted file mode 100644 index 31f5e24727..0000000000 --- a/load-test/src/routes/mongodb.js +++ /dev/null @@ -1,47 +0,0 @@ -/* eslint-disable no-console */ -'use strict'; - -var config = require('../config'); -var mongoose = require('mongoose'); - -var TestSchema = mongoose.model('test', new mongoose.Schema({ - someString: String, - someNumber: Number, - someDate: {type: Date, default: new Date().getTime() }, - someBoolean: Boolean -})); - -var fetchData = exports.fetchData = function fetchData() { - return TestSchema.find().exec(); -}; - -exports.path = '/mongo'; - -exports.router = function StandardRoute(res) { - fetchData() - .then(function(response) { - res.writeHead(200, {'Content-Type': 'application/json'}); - res.end(JSON.stringify(response[0])); - }).catch(function(error) { - res.writeHead(500, {'Content-Type': 'text/plain'}); - res.end('An error occured while querying mongodb.'); - console.error(error); - }); -}; - -exports.connect = function connect() { - return mongoose.connect('mongodb://' + config.services.mongo.host + '/load'); -}; - -exports.init = function init() { - return new Promise(function(resolve, reject) { - var newTestModel = new TestSchema({ - someString: 'Hello', - someNumber: 123456789, - someBoolean: true - }); - Promise.all([TestSchema.remove().exec(), newTestModel.save()]) - .then(resolve) - .catch(reject); - }); -}; diff --git a/load-test/src/routes/multiCall.js b/load-test/src/routes/multiCall.js deleted file mode 100644 index bec9a0c987..0000000000 --- a/load-test/src/routes/multiCall.js +++ /dev/null @@ -1,60 +0,0 @@ -/* eslint-disable no-console */ -'use strict'; - -var mongo = require('./mongodb'); -var mysql = require('./mysql'); -var redis = require('./redis'); -var https = require('https'); - -var NUMBER_OF_MONGO_CALLS = 5; -var NUMBER_OF_WEB_CALLS = 5; -var NUMBER_OF_REDIS_CALLS = 10; -var NUMBER_OF_MYSQL_CALLS = 5; - -exports.path = '/multi'; - -exports.router = function StandardRoute(res) { - Promise.all(new Array(NUMBER_OF_WEB_CALLS).fill(callInstana())) - .then(function() { - return Promise.all(new Array(NUMBER_OF_REDIS_CALLS).fill(redis.fetchData())); - }) - .then(function() { - return Promise.all(new Array(NUMBER_OF_MYSQL_CALLS).fill(mysql.fetchData())); - }) - .then(function() { - return Promise.all(new Array(NUMBER_OF_MONGO_CALLS).fill(mongo.fetchData())); - }) - .then(function() { - res.writeHead(200, {'Content-Type': 'text/plain'}); - res.end('All good.'); - }).catch(function(e) { - console.error('Error while trying to call multi call', e); - res.writeHead(500, {'Content-Type': 'text/plain'}); - res.end('Error doing Multi Call'); - }); -}; - -exports.connect = function() { - return Promise.resolve(); -}; - -exports.init = function() { - return Promise.resolve(); -}; - -function callInstana() { - return new Promise(function(resolve, reject) { - var req = https.get('https://instana.com', function(res) { - res.on('data', function() { - // without this, end is never being called....? - }); - res.on('end', function() { - resolve(); - }); - }); - req.on('error', function() { - reject('Could not query web page.'); - }); - }); -} - diff --git a/load-test/src/routes/mysql.js b/load-test/src/routes/mysql.js deleted file mode 100644 index e38d12f58b..0000000000 --- a/load-test/src/routes/mysql.js +++ /dev/null @@ -1,79 +0,0 @@ -'use strict'; - -var config = require('../config'); -var mysql = require('mysql2/promise'); - -var pool; -exports.path = '/mysql'; - -var fetchData = exports.fetchData = function() { - return pool.getConnection() - .then(function(connection) { - return query('SELECT * FROM %TABLE%', connection) - .then(function(result) { - connection.release(); - return result; - }); - }); -}; - -exports.router = function StandardRoute(res) { - fetchData() - .then(function(rows) { - res.writeHead(200, {'Content-Type': 'application/json'}); - res.end(JSON.stringify(rows)); - }).catch(function() { - res.writeHead(500, {'Content-Type': 'text/plain'}); - res.end('Error while trying to read from MySql'); - }); -}; - -exports.connect = function() { - pool = mysql.createPool({ - connectionLimit: 30, - host: config.services.mysql.host, - user: config.services.mysql.user, - database: config.services.mysql.database, - password: config.services.mysql.password - }); - - return Promise.resolve(); -}; - -exports.init = function() { - return new Promise(function(resolve, reject) { - pool.getConnection() - .then(function(con) { - query('Drop TABLE IF EXISTS %TABLE%', con); - return con; - }) - .then(function(con) { - query('CREATE TABLE %TABLE% (' + - ' someNumber int,' + - ' someString varchar(255),' + - ' someOtherString varchar(255)' + - ')', con); - return con; - }) - .then(function(con) { - query('INSERT INTO %TABLE%' + - '(someNumber, someString, someOtherString) ' + - 'VALUES ' + - '(0, "someString", "someOtherString")', - con - ); - return con; - }).then(function(connection) { - connection.release(); - resolve(); - }).catch(function(err) { - reject('Could not initialise MySql. ' + err); - }); - }); -}; - -function query(que, connection) { - var q = que.replace('%DB%', config.services.mysql.database) - .replace('%TABLE%', config.services.mysql.table); - return connection.query(q); -} diff --git a/load-test/src/routes/redis.js b/load-test/src/routes/redis.js deleted file mode 100644 index da87167a0c..0000000000 --- a/load-test/src/routes/redis.js +++ /dev/null @@ -1,48 +0,0 @@ -/* eslint-disable no-console */ -'use strict'; - -var Redis = require('ioredis'); -var config = require('../config'); -var redis; - -var fetchData = exports.fetchData = function fetchData() { - return redis.pipeline().get('load').get('someOtherLoad').exec(); -}; - - -exports.path = '/redis'; - -exports.router = function StandardRoute(res) { - fetchData().then(function(result) { - res.writeHead(200, {'Content-Type': 'application/json'}); - res.end(JSON.stringify(result)); - }).catch(function(err) { - console.error(err); - res.writeHead(500, {'Content-Type': 'text/plain'}); - res.end('Error querying Redis.'); - }); -}; - -exports.connect = function() { - return new Promise(function(resolve, reject) { - redis = new Redis('//' + config.services.redis.host); - redis.on('connect', function() { - resolve(); - }); - redis.on('error', function(error) { - redis.disconnect(); - reject('Could not connect to redis.', error); - }); - }); -}; - -exports.init = function() { - return new Promise(function(resolve, reject) { - if (redis == null) { - reject('Redis has not been setup'); - } - redis.set('load', 'test'); - redis.set('someOtherLoad', 'someOtherTest'); - resolve(); - }); -}; diff --git a/load-test/src/routes/standard.js b/load-test/src/routes/standard.js deleted file mode 100644 index 0f07d352b8..0000000000 --- a/load-test/src/routes/standard.js +++ /dev/null @@ -1,16 +0,0 @@ -'use strict'; - -exports.path = '/'; - -exports.router = function StandardRoute(res) { - res.writeHead(200, {'Content-Type': 'text/plain'}); - res.end('Instana Load Test'); -}; - -exports.connect = function() { - return Promise.resolve(); -}; - -exports.init = function() { - return Promise.resolve(); -}; diff --git a/load-test/src/simpleServer.js b/load-test/src/simpleServer.js deleted file mode 100644 index 968b9284b5..0000000000 --- a/load-test/src/simpleServer.js +++ /dev/null @@ -1,9 +0,0 @@ -'use strict'; - -// provides a simple http server without any special features -var http = require('http'); - -http.createServer(function(req, res) { - res.writeHead(200, {'Content-Type': 'text/plain'}); - res.end('OK'); -}).listen(5000); diff --git a/load-test/jmeter/httpOnly.jmx b/load-test/test/httpCallSequence.jmx similarity index 93% rename from load-test/jmeter/httpOnly.jmx rename to load-test/test/httpCallSequence.jmx index 31d9eddc93..e7be8e3f91 100644 --- a/load-test/jmeter/httpOnly.jmx +++ b/load-test/test/httpCallSequence.jmx @@ -17,12 +17,12 @@ false -1 - 150 + 300 10 1373789594000 1373789594000 true - 180 + 120 5 @@ -31,7 +31,7 @@ 127.0.0.1 - 3333 + 7681 http @@ -57,7 +57,7 @@ - /httpForward + /httpCallSequence GET true false @@ -74,8 +74,8 @@ Assertion.response_code false - 16 - Instana Load Test + 8 + Non 200 response code diff --git a/test/apps/agentStub.js b/test/apps/agentStub.js index a0b7417e98..158c5468e0 100644 --- a/test/apps/agentStub.js +++ b/test/apps/agentStub.js @@ -6,6 +6,7 @@ var morgan = require('morgan'); var app = express(); var logPrefix = 'Agent Stub (' + process.pid + '):\t'; +var dropAllData = process.env.DROP_DATA === 'true'; var discoveries = {}; var requests = {}; var retrievedData = { @@ -53,11 +54,13 @@ app.head('/com.instana.plugin.nodejs.:pid', checkExistenceOfKnownPid(function ha app.post('/com.instana.plugin.nodejs.:pid', checkExistenceOfKnownPid(function handleDataRetrieval(req, res) { - retrievedData.runtime.push({ - pid: parseInt(req.params.pid, 10), - time: Date.now(), - data: req.body - }); + if (!dropAllData) { + retrievedData.runtime.push({ + pid: parseInt(req.params.pid, 10), + time: Date.now(), + data: req.body + }); + } var requestsForPid = requests[req.params.pid] || []; log('Got new data for PID ' + req.params.pid + '. Responding with ' + requestsForPid.length + ' requests.'); @@ -67,23 +70,27 @@ app.post('/com.instana.plugin.nodejs.:pid', checkExistenceOfKnownPid(function ha app.post('/com.instana.plugin.nodejs/traces.:pid', checkExistenceOfKnownPid(function handleDataRetrieval(req, res) { - retrievedData.traces.push({ - pid: parseInt(req.params.pid, 10), - time: Date.now(), - data: req.body - }); + if (!dropAllData) { + retrievedData.traces.push({ + pid: parseInt(req.params.pid, 10), + time: Date.now(), + data: req.body + }); + } log('Got new spans for PID ' + req.params.pid); res.send('OK'); })); app.post('/com.instana.plugin.nodejs/response.:pid', checkExistenceOfKnownPid(function handleDataRetrieval(req, res) { - retrievedData.responses.push({ - pid: parseInt(req.params.pid, 10), - time: Date.now(), - messageId: req.query.messageId, - data: req.body - }); + if (!dropAllData) { + retrievedData.responses.push({ + pid: parseInt(req.params.pid, 10), + time: Date.now(), + messageId: req.query.messageId, + data: req.body + }); + } log('Got new responses for PID ' + req.params.pid); res.send('OK'); }));