diff --git a/README.md b/README.md index 49bc0006cf41a6cbf862e91079bf12053bdcac8e..1e1d053770f107262d84eb01aeaee6ca77eee1a0 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ A small express middleware to get base metrics for any node.js app. ## Usage -`import { Metrics } from '@plastdev/metrics'` +`import { Metrics, MetricType } from '@plastdev/metrics'` `let metrics = new Metrics(options)` Note: The options Part may be omitted, as all parts are optional. @@ -20,16 +20,93 @@ Before your Routes: And to enable the *_metrics*-Endpoint: `router.get('/_metrics', metrics.endpoint)` +### Custom Metrics + To Add your own custom Metrics: `metrics.addCustomMetric({ name: 'test', - help: 'Some Test Metric', - labelNames: ['tester'] - })` + help: 'Some Test Metric' + }, TYPE)` + +where TYPE is one of: + +- `MetricType.COUNTER` +- `MetricType.GAUGE` +- `MetricType.HISTOGRAM` +- `MetricType.SUMMARY` + +All metrics can take a labelNames property in the configuration object. All labelNames that the metric support needs to be declared here. There are 2 ways to add values to the labels + +```js +metrics.addCustomMetric({ + name: 'metric_name', + help: 'metric_help', + labelNames: ['method', 'statusCode'], +}, MetricType.GAUGE); + +metrics.customMetrics["NAME"].set({ method: 'GET', statusCode: '200' }, 100); // 1st version, Set value 100 with method set to GET and statusCode to 200 +metrics.customMetrics["NAME"].labels('GET', '200').set(100); // 2nd version, Same as above +``` + +It is also possible to use timers with labels, both before and after the timer is created: + +```js +const end = metrics.customMetrics["NAME"].startTimer({ method: 'GET' }); // Set method to GET, we don't know statusCode yet +xhrRequest(function (err, res) { + if (err) { + end({ statusCode: '500' }); // Sets value to xhrRequest duration in seconds with statusCode 500 + } else { + end({ statusCode: '200' }); // Sets value to xhrRequest duration in seconds with statusCode 200 + } +}); +``` + +#### Counter + +Counters go up, and reset when the process restarts. + +- `metrics.customMetrics["NAME"].inc(); // Inc with 1` +- `metrics.customMetrics["NAME"].inc(10); // Inc with 10` + +#### Gauge + +Gauges are similar to Counters but Gauges value can be decreased. + +- `metrics.customMetrics["NAME"].set(10); // Set to 10` +- `metrics.customMetrics["NAME"].inc(); // Inc with 1` +- `metrics.customMetrics["NAME"].inc(10); // Inc with 10` +- `metrics.customMetrics["NAME"].dec(); // Dec with 1` +- `metrics.customMetrics["NAME"].dec(10); // Dec with 10` + +#### Histograms + +Histograms track sizes and frequency of events. + +`metrics.customMetrics["NAME"].observe(10); // Observe value in histogram` + +Utility to observe request durations + +```js +const end = metrics.customMetrics["NAME"].startTimer(); +xhrRequest(function (err, res) { + const seconds = end(); // Observes and returns the value to xhrRequests duration in seconds +}); +``` + +#### Summary + +Summaries calculate percentiles of observed values. + +`metrics.customMetrics["NAME"].observe(10);` + +Utility to observe request durations -then you may increase or decrease the value at any given point: -`this.metrics.incCustomMetric('test', 'tester', 'called_bar')` -`this.metrics.decCustomMetric('test', 'tester', 'called_bar')` +```js +const end = metrics.customMetrics["NAME"].startTimer(); +xhrRequest(function (err, res) { + end(); // Observes the value to xhrRequests duration in seconds +}); +``` ### Options diff --git a/docs/test-report.html b/docs/test-report.html index e5a95381e9ef9597f55483e0f77a1da978738d0d..fdc172ac89d2da22ec9caa1fa5a47437094f333a 100644 --- a/docs/test-report.html +++ b/docs/test-report.html @@ -16,7 +16,7 @@ <div id="app"> </div> <script> - window.resData = "{\"numFailedTestSuites\":0,\"numFailedTests\":0,\"numPassedTestSuites\":1,\"numPassedTests\":14,\"numPendingTestSuites\":0,\"numPendingTests\":0,\"numRuntimeErrorTestSuites\":0,\"numTodoTests\":0,\"numTotalTestSuites\":1,\"numTotalTests\":14,\"openHandles\":[],\"snapshot\":{\"added\":0,\"didUpdate\":false,\"failure\":false,\"filesAdded\":0,\"filesRemoved\":0,\"filesRemovedList\":[],\"filesUnmatched\":0,\"filesUpdated\":0,\"matched\":0,\"total\":0,\"unchecked\":0,\"uncheckedKeysByFile\":[],\"unmatched\":0,\"updated\":0},\"startTime\":1591789696554,\"success\":false,\"testResults\":[{\"leaks\":false,\"numFailingTests\":0,\"numPassingTests\":14,\"numPendingTests\":0,\"numTodoTests\":0,\"openHandles\":[],\"perfStats\":{\"end\":1591789707158,\"start\":1591789696918},\"skipped\":false,\"snapshot\":{\"added\":0,\"fileDeleted\":false,\"matched\":0,\"unchecked\":0,\"unmatched\":0,\"updated\":0,\"uncheckedKeys\":[]},\"testFilePath\":\"/Users/sigmundd/Code/metrics/src/index.spec.ts\",\"testResults\":[{\"ancestorTitles\":[\"metrics\",\"constructor / options\"],\"duration\":457,\"failureMessages\":[],\"fullName\":\"metrics constructor / options should enable all 3 checks and default metrics by default\",\"location\":null,\"numPassingAsserts\":0,\"status\":\"passed\",\"title\":\"should enable all 3 checks and default metrics by default\"},{\"ancestorTitles\":[\"metrics\",\"constructor / options\"],\"duration\":21,\"failureMessages\":[],\"fullName\":\"metrics constructor / options should disable Route Counter if option is given\",\"location\":null,\"numPassingAsserts\":0,\"status\":\"passed\",\"title\":\"should disable Route Counter if option is given\"},{\"ancestorTitles\":[\"metrics\",\"constructor / options\"],\"duration\":24,\"failureMessages\":[],\"fullName\":\"metrics constructor / options should disable Error Counter if option is given\",\"location\":null,\"numPassingAsserts\":0,\"status\":\"passed\",\"title\":\"should disable Error Counter if option is given\"},{\"ancestorTitles\":[\"metrics\",\"constructor / options\"],\"duration\":22,\"failureMessages\":[],\"fullName\":\"metrics constructor / options should disable Duration Counter if option is given\",\"location\":null,\"numPassingAsserts\":0,\"status\":\"passed\",\"title\":\"should disable Duration Counter if option is given\"},{\"ancestorTitles\":[\"metrics\",\"constructor / options\"],\"duration\":11,\"failureMessages\":[],\"fullName\":\"metrics constructor / options should disable Default Metrics if option is given\",\"location\":null,\"numPassingAsserts\":0,\"status\":\"passed\",\"title\":\"should disable Default Metrics if option is given\"},{\"ancestorTitles\":[\"metrics\",\"constructor / options\"],\"duration\":25,\"failureMessages\":[],\"fullName\":\"metrics constructor / options should ignore /_metrics and /favicon.ico by default\",\"location\":null,\"numPassingAsserts\":0,\"status\":\"passed\",\"title\":\"should ignore /_metrics and /favicon.ico by default\"},{\"ancestorTitles\":[\"metrics\",\"constructor / options\"],\"duration\":21,\"failureMessages\":[],\"fullName\":\"metrics constructor / options should ignore given Routes, /_metrics and /favicon.ico by option\",\"location\":null,\"numPassingAsserts\":0,\"status\":\"passed\",\"title\":\"should ignore given Routes, /_metrics and /favicon.ico by option\"},{\"ancestorTitles\":[\"metrics\",\"collect()\"],\"duration\":24,\"failureMessages\":[],\"fullName\":\"metrics collect() should measure all 3 checks by default\",\"location\":null,\"numPassingAsserts\":0,\"status\":\"passed\",\"title\":\"should measure all 3 checks by default\"},{\"ancestorTitles\":[\"metrics\",\"collect()\"],\"duration\":24,\"failureMessages\":[],\"fullName\":\"metrics collect() should disable Route Counter if option is given\",\"location\":null,\"numPassingAsserts\":0,\"status\":\"passed\",\"title\":\"should disable Route Counter if option is given\"},{\"ancestorTitles\":[\"metrics\",\"collect()\"],\"duration\":27,\"failureMessages\":[],\"fullName\":\"metrics collect() should disable Error Counter if option is given\",\"location\":null,\"numPassingAsserts\":0,\"status\":\"passed\",\"title\":\"should disable Error Counter if option is given\"},{\"ancestorTitles\":[\"metrics\",\"collect()\"],\"duration\":22,\"failureMessages\":[],\"fullName\":\"metrics collect() should disable Duration Counter if option is given\",\"location\":null,\"numPassingAsserts\":0,\"status\":\"passed\",\"title\":\"should disable Duration Counter if option is given\"},{\"ancestorTitles\":[\"metrics\",\"collect()\"],\"duration\":32,\"failureMessages\":[],\"fullName\":\"metrics collect() should ignore urls in _ignore\",\"location\":null,\"numPassingAsserts\":0,\"status\":\"passed\",\"title\":\"should ignore urls in _ignore\"},{\"ancestorTitles\":[\"metrics\",\"endpoint()\"],\"duration\":39,\"failureMessages\":[],\"fullName\":\"metrics endpoint() should display all 3 basic metrics and default metrics by default\",\"location\":null,\"numPassingAsserts\":0,\"status\":\"passed\",\"title\":\"should display all 3 basic metrics and default metrics by default\"},{\"ancestorTitles\":[\"metrics\",\"endpoint()\"],\"duration\":16,\"failureMessages\":[],\"fullName\":\"metrics endpoint() should not scrape default metrics if disabled\",\"location\":null,\"numPassingAsserts\":0,\"status\":\"passed\",\"title\":\"should not scrape default metrics if disabled\"}],\"failureMessage\":null}],\"wasInterrupted\":false,\"coverageMap\":{\"/Users/sigmundd/Code/metrics/src/index.ts\":{\"path\":\"/Users/sigmundd/Code/metrics/src/index.ts\",\"statementMap\":{\"0\":{\"start\":{\"line\":90,\"column\":9},\"end\":{\"line\":96,\"column\":null}},\"1\":{\"start\":{\"line\":91,\"column\":4},\"end\":{\"line\":95,\"column\":null}},\"2\":{\"start\":{\"line\":98,\"column\":9},\"end\":{\"line\":102,\"column\":null}},\"3\":{\"start\":{\"line\":99,\"column\":21},\"end\":{\"line\":99,\"column\":23}},\"4\":{\"start\":{\"line\":100,\"column\":4},\"end\":{\"line\":100,\"column\":null}},\"5\":{\"start\":{\"line\":101,\"column\":4},\"end\":{\"line\":101,\"column\":null}},\"6\":{\"start\":{\"line\":103,\"column\":9},\"end\":{\"line\":107,\"column\":null}},\"7\":{\"start\":{\"line\":104,\"column\":21},\"end\":{\"line\":104,\"column\":23}},\"8\":{\"start\":{\"line\":105,\"column\":4},\"end\":{\"line\":105,\"column\":null}},\"9\":{\"start\":{\"line\":106,\"column\":4},\"end\":{\"line\":106,\"column\":null}},\"10\":{\"start\":{\"line\":109,\"column\":9},\"end\":{\"line\":130,\"column\":null}},\"11\":{\"start\":{\"line\":110,\"column\":4},\"end\":{\"line\":110,\"column\":null}},\"12\":{\"start\":{\"line\":111,\"column\":4},\"end\":{\"line\":128,\"column\":null}},\"13\":{\"start\":{\"line\":112,\"column\":6},\"end\":{\"line\":127,\"column\":null}},\"14\":{\"start\":{\"line\":113,\"column\":33},\"end\":{\"line\":113,\"column\":67}},\"15\":{\"start\":{\"line\":114,\"column\":8},\"end\":{\"line\":118,\"column\":null}},\"16\":{\"start\":{\"line\":115,\"column\":10},\"end\":{\"line\":117,\"column\":null}},\"17\":{\"start\":{\"line\":119,\"column\":8},\"end\":{\"line\":121,\"column\":null}},\"18\":{\"start\":{\"line\":120,\"column\":10},\"end\":{\"line\":120,\"column\":null}},\"19\":{\"start\":{\"line\":122,\"column\":8},\"end\":{\"line\":126,\"column\":null}},\"20\":{\"start\":{\"line\":123,\"column\":10},\"end\":{\"line\":125,\"column\":null}},\"21\":{\"start\":{\"line\":124,\"column\":12},\"end\":{\"line\":124,\"column\":null}},\"22\":{\"start\":{\"line\":129,\"column\":4},\"end\":{\"line\":129,\"column\":null}},\"23\":{\"start\":{\"line\":132,\"column\":9},\"end\":{\"line\":136,\"column\":null}},\"24\":{\"start\":{\"line\":133,\"column\":4},\"end\":{\"line\":133,\"column\":null}},\"25\":{\"start\":{\"line\":134,\"column\":4},\"end\":{\"line\":134,\"column\":null}},\"26\":{\"start\":{\"line\":135,\"column\":4},\"end\":{\"line\":135,\"column\":null}},\"27\":{\"start\":{\"line\":33,\"column\":4},\"end\":{\"line\":33,\"column\":null}},\"28\":{\"start\":{\"line\":34,\"column\":4},\"end\":{\"line\":34,\"column\":null}},\"29\":{\"start\":{\"line\":36,\"column\":4},\"end\":{\"line\":42,\"column\":null}},\"30\":{\"start\":{\"line\":37,\"column\":6},\"end\":{\"line\":37,\"column\":null}},\"31\":{\"start\":{\"line\":38,\"column\":6},\"end\":{\"line\":38,\"column\":null}},\"32\":{\"start\":{\"line\":39,\"column\":6},\"end\":{\"line\":39,\"column\":null}},\"33\":{\"start\":{\"line\":41,\"column\":6},\"end\":{\"line\":41,\"column\":null}},\"34\":{\"start\":{\"line\":43,\"column\":4},\"end\":{\"line\":47,\"column\":null}},\"35\":{\"start\":{\"line\":44,\"column\":6},\"end\":{\"line\":44,\"column\":null}},\"36\":{\"start\":{\"line\":46,\"column\":6},\"end\":{\"line\":46,\"column\":null}},\"37\":{\"start\":{\"line\":48,\"column\":4},\"end\":{\"line\":52,\"column\":null}},\"38\":{\"start\":{\"line\":49,\"column\":6},\"end\":{\"line\":49,\"column\":null}},\"39\":{\"start\":{\"line\":51,\"column\":6},\"end\":{\"line\":51,\"column\":null}},\"40\":{\"start\":{\"line\":53,\"column\":4},\"end\":{\"line\":57,\"column\":null}},\"41\":{\"start\":{\"line\":54,\"column\":6},\"end\":{\"line\":54,\"column\":null}},\"42\":{\"start\":{\"line\":56,\"column\":6},\"end\":{\"line\":56,\"column\":null}},\"43\":{\"start\":{\"line\":58,\"column\":4},\"end\":{\"line\":62,\"column\":null}},\"44\":{\"start\":{\"line\":59,\"column\":6},\"end\":{\"line\":59,\"column\":null}},\"45\":{\"start\":{\"line\":61,\"column\":6},\"end\":{\"line\":61,\"column\":null}},\"46\":{\"start\":{\"line\":63,\"column\":4},\"end\":{\"line\":65,\"column\":null}},\"47\":{\"start\":{\"line\":64,\"column\":6},\"end\":{\"line\":64,\"column\":null}},\"48\":{\"start\":{\"line\":66,\"column\":4},\"end\":{\"line\":72,\"column\":null}},\"49\":{\"start\":{\"line\":67,\"column\":6},\"end\":{\"line\":71,\"column\":null}},\"50\":{\"start\":{\"line\":73,\"column\":4},\"end\":{\"line\":79,\"column\":null}},\"51\":{\"start\":{\"line\":74,\"column\":6},\"end\":{\"line\":78,\"column\":null}},\"52\":{\"start\":{\"line\":80,\"column\":4},\"end\":{\"line\":87,\"column\":null}},\"53\":{\"start\":{\"line\":81,\"column\":6},\"end\":{\"line\":86,\"column\":null}},\"54\":{\"start\":{\"line\":17,\"column\":0},\"end\":{\"line\":17,\"column\":13}},\"55\":{\"start\":{\"line\":138,\"column\":0},\"end\":{\"line\":138,\"column\":null}}},\"fnMap\":{\"0\":{\"name\":\"(anonymous_0)\",\"decl\":{\"start\":{\"line\":32,\"column\":2},\"end\":{\"line\":32,\"column\":15}},\"loc\":{\"start\":{\"line\":32,\"column\":45},\"end\":{\"line\":88,\"column\":3}}},\"1\":{\"name\":\"(anonymous_1)\",\"decl\":{\"start\":{\"line\":90,\"column\":27},\"end\":{\"line\":90,\"column\":28}},\"loc\":{\"start\":{\"line\":90,\"column\":59},\"end\":{\"line\":96,\"column\":3}}},\"2\":{\"name\":\"(anonymous_2)\",\"decl\":{\"start\":{\"line\":98,\"column\":27},\"end\":{\"line\":98,\"column\":28}},\"loc\":{\"start\":{\"line\":98,\"column\":80},\"end\":{\"line\":102,\"column\":3}}},\"3\":{\"name\":\"(anonymous_3)\",\"decl\":{\"start\":{\"line\":103,\"column\":27},\"end\":{\"line\":103,\"column\":28}},\"loc\":{\"start\":{\"line\":103,\"column\":80},\"end\":{\"line\":107,\"column\":3}}},\"4\":{\"name\":\"(anonymous_4)\",\"decl\":{\"start\":{\"line\":109,\"column\":19},\"end\":{\"line\":109,\"column\":20}},\"loc\":{\"start\":{\"line\":109,\"column\":101},\"end\":{\"line\":130,\"column\":3}}},\"5\":{\"name\":\"(anonymous_5)\",\"decl\":{\"start\":{\"line\":111,\"column\":21},\"end\":{\"line\":111,\"column\":24}},\"loc\":{\"start\":{\"line\":111,\"column\":26},\"end\":{\"line\":128,\"column\":5}}},\"6\":{\"name\":\"(anonymous_6)\",\"decl\":{\"start\":{\"line\":132,\"column\":20},\"end\":{\"line\":132,\"column\":21}},\"loc\":{\"start\":{\"line\":132,\"column\":74},\"end\":{\"line\":136,\"column\":3}}}},\"branchMap\":{\"0\":{\"loc\":{\"start\":{\"line\":32,\"column\":43},\"end\":{\"line\":32,\"column\":45}},\"type\":\"default-arg\",\"locations\":[{\"start\":{\"line\":32,\"column\":43},\"end\":{\"line\":32,\"column\":45}}]},\"1\":{\"loc\":{\"start\":{\"line\":112,\"column\":6},\"end\":{\"line\":127,\"column\":null}},\"type\":\"if\",\"locations\":[{\"start\":{\"line\":112,\"column\":6},\"end\":{\"line\":127,\"column\":null}},{\"start\":{\"line\":112,\"column\":6},\"end\":{\"line\":127,\"column\":null}}]},\"2\":{\"loc\":{\"start\":{\"line\":114,\"column\":8},\"end\":{\"line\":118,\"column\":null}},\"type\":\"if\",\"locations\":[{\"start\":{\"line\":114,\"column\":8},\"end\":{\"line\":118,\"column\":null}},{\"start\":{\"line\":114,\"column\":8},\"end\":{\"line\":118,\"column\":null}}]},\"3\":{\"loc\":{\"start\":{\"line\":119,\"column\":8},\"end\":{\"line\":121,\"column\":null}},\"type\":\"if\",\"locations\":[{\"start\":{\"line\":119,\"column\":8},\"end\":{\"line\":121,\"column\":null}},{\"start\":{\"line\":119,\"column\":8},\"end\":{\"line\":121,\"column\":null}}]},\"4\":{\"loc\":{\"start\":{\"line\":122,\"column\":8},\"end\":{\"line\":126,\"column\":null}},\"type\":\"if\",\"locations\":[{\"start\":{\"line\":122,\"column\":8},\"end\":{\"line\":126,\"column\":null}},{\"start\":{\"line\":122,\"column\":8},\"end\":{\"line\":126,\"column\":null}}]},\"5\":{\"loc\":{\"start\":{\"line\":123,\"column\":10},\"end\":{\"line\":125,\"column\":null}},\"type\":\"if\",\"locations\":[{\"start\":{\"line\":123,\"column\":10},\"end\":{\"line\":125,\"column\":null}},{\"start\":{\"line\":123,\"column\":10},\"end\":{\"line\":125,\"column\":null}}]},\"6\":{\"loc\":{\"start\":{\"line\":36,\"column\":4},\"end\":{\"line\":42,\"column\":null}},\"type\":\"if\",\"locations\":[{\"start\":{\"line\":36,\"column\":4},\"end\":{\"line\":42,\"column\":null}},{\"start\":{\"line\":36,\"column\":4},\"end\":{\"line\":42,\"column\":null}}]},\"7\":{\"loc\":{\"start\":{\"line\":43,\"column\":4},\"end\":{\"line\":47,\"column\":null}},\"type\":\"if\",\"locations\":[{\"start\":{\"line\":43,\"column\":4},\"end\":{\"line\":47,\"column\":null}},{\"start\":{\"line\":43,\"column\":4},\"end\":{\"line\":47,\"column\":null}}]},\"8\":{\"loc\":{\"start\":{\"line\":48,\"column\":4},\"end\":{\"line\":52,\"column\":null}},\"type\":\"if\",\"locations\":[{\"start\":{\"line\":48,\"column\":4},\"end\":{\"line\":52,\"column\":null}},{\"start\":{\"line\":48,\"column\":4},\"end\":{\"line\":52,\"column\":null}}]},\"9\":{\"loc\":{\"start\":{\"line\":53,\"column\":4},\"end\":{\"line\":57,\"column\":null}},\"type\":\"if\",\"locations\":[{\"start\":{\"line\":53,\"column\":4},\"end\":{\"line\":57,\"column\":null}},{\"start\":{\"line\":53,\"column\":4},\"end\":{\"line\":57,\"column\":null}}]},\"10\":{\"loc\":{\"start\":{\"line\":58,\"column\":4},\"end\":{\"line\":62,\"column\":null}},\"type\":\"if\",\"locations\":[{\"start\":{\"line\":58,\"column\":4},\"end\":{\"line\":62,\"column\":null}},{\"start\":{\"line\":58,\"column\":4},\"end\":{\"line\":62,\"column\":null}}]},\"11\":{\"loc\":{\"start\":{\"line\":63,\"column\":4},\"end\":{\"line\":65,\"column\":null}},\"type\":\"if\",\"locations\":[{\"start\":{\"line\":63,\"column\":4},\"end\":{\"line\":65,\"column\":null}},{\"start\":{\"line\":63,\"column\":4},\"end\":{\"line\":65,\"column\":null}}]},\"12\":{\"loc\":{\"start\":{\"line\":66,\"column\":4},\"end\":{\"line\":72,\"column\":null}},\"type\":\"if\",\"locations\":[{\"start\":{\"line\":66,\"column\":4},\"end\":{\"line\":72,\"column\":null}},{\"start\":{\"line\":66,\"column\":4},\"end\":{\"line\":72,\"column\":null}}]},\"13\":{\"loc\":{\"start\":{\"line\":73,\"column\":4},\"end\":{\"line\":79,\"column\":null}},\"type\":\"if\",\"locations\":[{\"start\":{\"line\":73,\"column\":4},\"end\":{\"line\":79,\"column\":null}},{\"start\":{\"line\":73,\"column\":4},\"end\":{\"line\":79,\"column\":null}}]},\"14\":{\"loc\":{\"start\":{\"line\":80,\"column\":4},\"end\":{\"line\":87,\"column\":null}},\"type\":\"if\",\"locations\":[{\"start\":{\"line\":80,\"column\":4},\"end\":{\"line\":87,\"column\":null}},{\"start\":{\"line\":80,\"column\":4},\"end\":{\"line\":87,\"column\":null}}]}},\"s\":{\"0\":14,\"1\":0,\"2\":14,\"3\":0,\"4\":0,\"5\":0,\"6\":14,\"7\":0,\"8\":0,\"9\":0,\"10\":14,\"11\":6,\"12\":6,\"13\":6,\"14\":5,\"15\":5,\"16\":4,\"17\":5,\"18\":4,\"19\":5,\"20\":4,\"21\":3,\"22\":6,\"23\":14,\"24\":2,\"25\":2,\"26\":2,\"27\":14,\"28\":14,\"29\":14,\"30\":1,\"31\":1,\"32\":1,\"33\":13,\"34\":14,\"35\":2,\"36\":12,\"37\":14,\"38\":2,\"39\":12,\"40\":14,\"41\":2,\"42\":12,\"43\":14,\"44\":2,\"45\":12,\"46\":14,\"47\":12,\"48\":14,\"49\":12,\"50\":14,\"51\":12,\"52\":14,\"53\":12,\"54\":1,\"55\":1},\"f\":{\"0\":14,\"1\":0,\"2\":0,\"3\":0,\"4\":6,\"5\":6,\"6\":2},\"b\":{\"0\":[1],\"1\":[5,1],\"2\":[4,1],\"3\":[4,1],\"4\":[4,1],\"5\":[3,1],\"6\":[1,13],\"7\":[2,12],\"8\":[2,12],\"9\":[2,12],\"10\":[2,12],\"11\":[12,2],\"12\":[12,2],\"13\":[12,2],\"14\":[12,2]}}},\"config\":{\"bail\":0,\"changedFilesWithAncestor\":false,\"collectCoverage\":true,\"collectCoverageFrom\":[],\"coverageDirectory\":\"/Users/sigmundd/Code/metrics/docs/coverage\",\"coverageProvider\":\"babel\",\"coverageReporters\":[\"json\",\"lcov\",\"text\",\"clover\",\"html\"],\"detectLeaks\":false,\"detectOpenHandles\":false,\"errorOnDeprecated\":false,\"expand\":false,\"findRelatedTests\":false,\"forceExit\":false,\"json\":false,\"lastCommit\":false,\"listTests\":false,\"logHeapUsage\":false,\"maxConcurrency\":5,\"maxWorkers\":11,\"noStackTrace\":false,\"nonFlagArgs\":[],\"notify\":false,\"notifyMode\":\"failure-change\",\"onlyChanged\":false,\"onlyFailures\":false,\"passWithNoTests\":false,\"projects\":[],\"reporters\":[[\"default\",{}],[\"/Users/sigmundd/Code/metrics/node_modules/jest-html-reporters/index.js\",{\"publicPath\":\"./docs\",\"filename\":\"test-report.html\",\"pageTitle\":\"Metrics :: Test Results\"}]],\"rootDir\":\"/Users/sigmundd/Code/metrics\",\"runTestsByPath\":false,\"skipFilter\":false,\"testFailureExitCode\":1,\"testPathPattern\":\"\",\"testSequencer\":\"/Users/sigmundd/Code/metrics/node_modules/@jest/test-sequencer/build/index.js\",\"updateSnapshot\":\"new\",\"useStderr\":false,\"verbose\":true,\"watch\":false,\"watchAll\":false,\"watchman\":true},\"endTime\":1591789707810,\"_reporterOptions\":{\"publicPath\":\"./docs\",\"filename\":\"test-report.html\",\"pageTitle\":\"Metrics :: Test Results\"}}" + window.resData = "{\"numFailedTestSuites\":0,\"numFailedTests\":0,\"numPassedTestSuites\":1,\"numPassedTests\":14,\"numPendingTestSuites\":0,\"numPendingTests\":0,\"numRuntimeErrorTestSuites\":0,\"numTodoTests\":0,\"numTotalTestSuites\":1,\"numTotalTests\":14,\"openHandles\":[],\"snapshot\":{\"added\":0,\"didUpdate\":false,\"failure\":false,\"filesAdded\":0,\"filesRemoved\":0,\"filesRemovedList\":[],\"filesUnmatched\":0,\"filesUpdated\":0,\"matched\":0,\"total\":0,\"unchecked\":0,\"uncheckedKeysByFile\":[],\"unmatched\":0,\"updated\":0},\"startTime\":1591793734578,\"success\":false,\"testResults\":[{\"leaks\":false,\"numFailingTests\":0,\"numPassingTests\":14,\"numPendingTests\":0,\"numTodoTests\":0,\"openHandles\":[],\"perfStats\":{\"end\":1591793739577,\"start\":1591793734755},\"skipped\":false,\"snapshot\":{\"added\":0,\"fileDeleted\":false,\"matched\":0,\"unchecked\":0,\"unmatched\":0,\"updated\":0,\"uncheckedKeys\":[]},\"testFilePath\":\"/Users/sigmundd/Code/metrics/src/index.spec.ts\",\"testResults\":[{\"ancestorTitles\":[\"metrics\",\"constructor / options\"],\"duration\":142,\"failureMessages\":[],\"fullName\":\"metrics constructor / options should enable all 3 checks and default metrics by default\",\"location\":null,\"numPassingAsserts\":0,\"status\":\"passed\",\"title\":\"should enable all 3 checks and default metrics by default\"},{\"ancestorTitles\":[\"metrics\",\"constructor / options\"],\"duration\":14,\"failureMessages\":[],\"fullName\":\"metrics constructor / options should disable Route Counter if option is given\",\"location\":null,\"numPassingAsserts\":0,\"status\":\"passed\",\"title\":\"should disable Route Counter if option is given\"},{\"ancestorTitles\":[\"metrics\",\"constructor / options\"],\"duration\":14,\"failureMessages\":[],\"fullName\":\"metrics constructor / options should disable Error Counter if option is given\",\"location\":null,\"numPassingAsserts\":0,\"status\":\"passed\",\"title\":\"should disable Error Counter if option is given\"},{\"ancestorTitles\":[\"metrics\",\"constructor / options\"],\"duration\":14,\"failureMessages\":[],\"fullName\":\"metrics constructor / options should disable Duration Counter if option is given\",\"location\":null,\"numPassingAsserts\":0,\"status\":\"passed\",\"title\":\"should disable Duration Counter if option is given\"},{\"ancestorTitles\":[\"metrics\",\"constructor / options\"],\"duration\":7,\"failureMessages\":[],\"fullName\":\"metrics constructor / options should disable Default Metrics if option is given\",\"location\":null,\"numPassingAsserts\":0,\"status\":\"passed\",\"title\":\"should disable Default Metrics if option is given\"},{\"ancestorTitles\":[\"metrics\",\"constructor / options\"],\"duration\":14,\"failureMessages\":[],\"fullName\":\"metrics constructor / options should ignore /_metrics and /favicon.ico by default\",\"location\":null,\"numPassingAsserts\":0,\"status\":\"passed\",\"title\":\"should ignore /_metrics and /favicon.ico by default\"},{\"ancestorTitles\":[\"metrics\",\"constructor / options\"],\"duration\":13,\"failureMessages\":[],\"fullName\":\"metrics constructor / options should ignore given Routes, /_metrics and /favicon.ico by option\",\"location\":null,\"numPassingAsserts\":0,\"status\":\"passed\",\"title\":\"should ignore given Routes, /_metrics and /favicon.ico by option\"},{\"ancestorTitles\":[\"metrics\",\"collect()\"],\"duration\":14,\"failureMessages\":[],\"fullName\":\"metrics collect() should measure all 3 checks by default\",\"location\":null,\"numPassingAsserts\":0,\"status\":\"passed\",\"title\":\"should measure all 3 checks by default\"},{\"ancestorTitles\":[\"metrics\",\"collect()\"],\"duration\":17,\"failureMessages\":[],\"fullName\":\"metrics collect() should disable Route Counter if option is given\",\"location\":null,\"numPassingAsserts\":0,\"status\":\"passed\",\"title\":\"should disable Route Counter if option is given\"},{\"ancestorTitles\":[\"metrics\",\"collect()\"],\"duration\":13,\"failureMessages\":[],\"fullName\":\"metrics collect() should disable Error Counter if option is given\",\"location\":null,\"numPassingAsserts\":0,\"status\":\"passed\",\"title\":\"should disable Error Counter if option is given\"},{\"ancestorTitles\":[\"metrics\",\"collect()\"],\"duration\":14,\"failureMessages\":[],\"fullName\":\"metrics collect() should disable Duration Counter if option is given\",\"location\":null,\"numPassingAsserts\":0,\"status\":\"passed\",\"title\":\"should disable Duration Counter if option is given\"},{\"ancestorTitles\":[\"metrics\",\"collect()\"],\"duration\":13,\"failureMessages\":[],\"fullName\":\"metrics collect() should ignore urls in _ignore\",\"location\":null,\"numPassingAsserts\":0,\"status\":\"passed\",\"title\":\"should ignore urls in _ignore\"},{\"ancestorTitles\":[\"metrics\",\"endpoint()\"],\"duration\":16,\"failureMessages\":[],\"fullName\":\"metrics endpoint() should display all 3 basic metrics and default metrics by default\",\"location\":null,\"numPassingAsserts\":0,\"status\":\"passed\",\"title\":\"should display all 3 basic metrics and default metrics by default\"},{\"ancestorTitles\":[\"metrics\",\"endpoint()\"],\"duration\":9,\"failureMessages\":[],\"fullName\":\"metrics endpoint() should not scrape default metrics if disabled\",\"location\":null,\"numPassingAsserts\":0,\"status\":\"passed\",\"title\":\"should not scrape default metrics if disabled\"}],\"failureMessage\":null}],\"wasInterrupted\":false,\"coverageMap\":{\"/Users/sigmundd/Code/metrics/src/index.ts\":{\"path\":\"/Users/sigmundd/Code/metrics/src/index.ts\",\"statementMap\":{\"0\":{\"start\":{\"line\":17,\"column\":0},\"end\":{\"line\":17,\"column\":null}},\"1\":{\"start\":{\"line\":18,\"column\":2},\"end\":{\"line\":18,\"column\":null}},\"2\":{\"start\":{\"line\":19,\"column\":2},\"end\":{\"line\":19,\"column\":null}},\"3\":{\"start\":{\"line\":20,\"column\":2},\"end\":{\"line\":20,\"column\":null}},\"4\":{\"start\":{\"line\":21,\"column\":2},\"end\":{\"line\":21,\"column\":null}},\"5\":{\"start\":{\"line\":97,\"column\":9},\"end\":{\"line\":114,\"column\":null}},\"6\":{\"start\":{\"line\":98,\"column\":4},\"end\":{\"line\":113,\"column\":null}},\"7\":{\"start\":{\"line\":100,\"column\":8},\"end\":{\"line\":100,\"column\":null}},\"8\":{\"start\":{\"line\":101,\"column\":8},\"end\":{\"line\":101,\"column\":13}},\"9\":{\"start\":{\"line\":103,\"column\":8},\"end\":{\"line\":103,\"column\":null}},\"10\":{\"start\":{\"line\":104,\"column\":8},\"end\":{\"line\":104,\"column\":13}},\"11\":{\"start\":{\"line\":106,\"column\":8},\"end\":{\"line\":106,\"column\":null}},\"12\":{\"start\":{\"line\":107,\"column\":8},\"end\":{\"line\":107,\"column\":13}},\"13\":{\"start\":{\"line\":109,\"column\":8},\"end\":{\"line\":109,\"column\":null}},\"14\":{\"start\":{\"line\":110,\"column\":8},\"end\":{\"line\":110,\"column\":13}},\"15\":{\"start\":{\"line\":112,\"column\":8},\"end\":{\"line\":112,\"column\":13}},\"16\":{\"start\":{\"line\":116,\"column\":9},\"end\":{\"line\":137,\"column\":null}},\"17\":{\"start\":{\"line\":117,\"column\":4},\"end\":{\"line\":117,\"column\":null}},\"18\":{\"start\":{\"line\":118,\"column\":4},\"end\":{\"line\":135,\"column\":null}},\"19\":{\"start\":{\"line\":119,\"column\":6},\"end\":{\"line\":134,\"column\":null}},\"20\":{\"start\":{\"line\":120,\"column\":33},\"end\":{\"line\":120,\"column\":67}},\"21\":{\"start\":{\"line\":121,\"column\":8},\"end\":{\"line\":125,\"column\":null}},\"22\":{\"start\":{\"line\":122,\"column\":10},\"end\":{\"line\":124,\"column\":null}},\"23\":{\"start\":{\"line\":126,\"column\":8},\"end\":{\"line\":128,\"column\":null}},\"24\":{\"start\":{\"line\":127,\"column\":10},\"end\":{\"line\":127,\"column\":null}},\"25\":{\"start\":{\"line\":129,\"column\":8},\"end\":{\"line\":133,\"column\":null}},\"26\":{\"start\":{\"line\":130,\"column\":10},\"end\":{\"line\":132,\"column\":null}},\"27\":{\"start\":{\"line\":131,\"column\":12},\"end\":{\"line\":131,\"column\":null}},\"28\":{\"start\":{\"line\":136,\"column\":4},\"end\":{\"line\":136,\"column\":null}},\"29\":{\"start\":{\"line\":139,\"column\":9},\"end\":{\"line\":143,\"column\":null}},\"30\":{\"start\":{\"line\":140,\"column\":4},\"end\":{\"line\":140,\"column\":null}},\"31\":{\"start\":{\"line\":141,\"column\":4},\"end\":{\"line\":141,\"column\":null}},\"32\":{\"start\":{\"line\":142,\"column\":4},\"end\":{\"line\":142,\"column\":null}},\"33\":{\"start\":{\"line\":40,\"column\":4},\"end\":{\"line\":40,\"column\":null}},\"34\":{\"start\":{\"line\":41,\"column\":4},\"end\":{\"line\":41,\"column\":null}},\"35\":{\"start\":{\"line\":43,\"column\":4},\"end\":{\"line\":49,\"column\":null}},\"36\":{\"start\":{\"line\":44,\"column\":6},\"end\":{\"line\":44,\"column\":null}},\"37\":{\"start\":{\"line\":45,\"column\":6},\"end\":{\"line\":45,\"column\":null}},\"38\":{\"start\":{\"line\":46,\"column\":6},\"end\":{\"line\":46,\"column\":null}},\"39\":{\"start\":{\"line\":48,\"column\":6},\"end\":{\"line\":48,\"column\":null}},\"40\":{\"start\":{\"line\":50,\"column\":4},\"end\":{\"line\":54,\"column\":null}},\"41\":{\"start\":{\"line\":51,\"column\":6},\"end\":{\"line\":51,\"column\":null}},\"42\":{\"start\":{\"line\":53,\"column\":6},\"end\":{\"line\":53,\"column\":null}},\"43\":{\"start\":{\"line\":55,\"column\":4},\"end\":{\"line\":59,\"column\":null}},\"44\":{\"start\":{\"line\":56,\"column\":6},\"end\":{\"line\":56,\"column\":null}},\"45\":{\"start\":{\"line\":58,\"column\":6},\"end\":{\"line\":58,\"column\":null}},\"46\":{\"start\":{\"line\":60,\"column\":4},\"end\":{\"line\":64,\"column\":null}},\"47\":{\"start\":{\"line\":61,\"column\":6},\"end\":{\"line\":61,\"column\":null}},\"48\":{\"start\":{\"line\":63,\"column\":6},\"end\":{\"line\":63,\"column\":null}},\"49\":{\"start\":{\"line\":65,\"column\":4},\"end\":{\"line\":69,\"column\":null}},\"50\":{\"start\":{\"line\":66,\"column\":6},\"end\":{\"line\":66,\"column\":null}},\"51\":{\"start\":{\"line\":68,\"column\":6},\"end\":{\"line\":68,\"column\":null}},\"52\":{\"start\":{\"line\":70,\"column\":4},\"end\":{\"line\":72,\"column\":null}},\"53\":{\"start\":{\"line\":71,\"column\":6},\"end\":{\"line\":71,\"column\":null}},\"54\":{\"start\":{\"line\":73,\"column\":4},\"end\":{\"line\":79,\"column\":null}},\"55\":{\"start\":{\"line\":74,\"column\":6},\"end\":{\"line\":78,\"column\":null}},\"56\":{\"start\":{\"line\":80,\"column\":4},\"end\":{\"line\":86,\"column\":null}},\"57\":{\"start\":{\"line\":81,\"column\":6},\"end\":{\"line\":85,\"column\":null}},\"58\":{\"start\":{\"line\":87,\"column\":4},\"end\":{\"line\":94,\"column\":null}},\"59\":{\"start\":{\"line\":88,\"column\":6},\"end\":{\"line\":93,\"column\":null}},\"60\":{\"start\":{\"line\":24,\"column\":0},\"end\":{\"line\":24,\"column\":13}},\"61\":{\"start\":{\"line\":145,\"column\":0},\"end\":{\"line\":145,\"column\":null}}},\"fnMap\":{\"0\":{\"name\":\"(anonymous_0)\",\"decl\":{\"start\":{\"line\":17,\"column\":0},\"end\":{\"line\":17,\"column\":12}},\"loc\":{\"start\":{\"line\":17,\"column\":22},\"end\":{\"line\":22,\"column\":1}}},\"1\":{\"name\":\"(anonymous_1)\",\"decl\":{\"start\":{\"line\":39,\"column\":2},\"end\":{\"line\":39,\"column\":15}},\"loc\":{\"start\":{\"line\":39,\"column\":45},\"end\":{\"line\":95,\"column\":3}}},\"2\":{\"name\":\"(anonymous_2)\",\"decl\":{\"start\":{\"line\":97,\"column\":27},\"end\":{\"line\":97,\"column\":28}},\"loc\":{\"start\":{\"line\":97,\"column\":77},\"end\":{\"line\":114,\"column\":3}}},\"3\":{\"name\":\"(anonymous_3)\",\"decl\":{\"start\":{\"line\":116,\"column\":19},\"end\":{\"line\":116,\"column\":20}},\"loc\":{\"start\":{\"line\":116,\"column\":101},\"end\":{\"line\":137,\"column\":3}}},\"4\":{\"name\":\"(anonymous_4)\",\"decl\":{\"start\":{\"line\":118,\"column\":21},\"end\":{\"line\":118,\"column\":24}},\"loc\":{\"start\":{\"line\":118,\"column\":26},\"end\":{\"line\":135,\"column\":5}}},\"5\":{\"name\":\"(anonymous_5)\",\"decl\":{\"start\":{\"line\":139,\"column\":20},\"end\":{\"line\":139,\"column\":21}},\"loc\":{\"start\":{\"line\":139,\"column\":74},\"end\":{\"line\":143,\"column\":3}}}},\"branchMap\":{\"0\":{\"loc\":{\"start\":{\"line\":17,\"column\":12},\"end\":{\"line\":17,\"column\":22}},\"type\":\"binary-expr\",\"locations\":[{\"start\":{\"line\":17,\"column\":12},\"end\":{\"line\":17,\"column\":22}},{\"start\":{\"line\":17,\"column\":12},\"end\":{\"line\":17,\"column\":null}}]},\"1\":{\"loc\":{\"start\":{\"line\":39,\"column\":43},\"end\":{\"line\":39,\"column\":45}},\"type\":\"default-arg\",\"locations\":[{\"start\":{\"line\":39,\"column\":43},\"end\":{\"line\":39,\"column\":45}}]},\"2\":{\"loc\":{\"start\":{\"line\":99,\"column\":6},\"end\":{\"line\":101,\"column\":13}},\"type\":\"switch\",\"locations\":[{\"start\":{\"line\":99,\"column\":6},\"end\":{\"line\":101,\"column\":13}},{\"start\":{\"line\":102,\"column\":6},\"end\":{\"line\":104,\"column\":13}},{\"start\":{\"line\":105,\"column\":6},\"end\":{\"line\":107,\"column\":13}},{\"start\":{\"line\":108,\"column\":6},\"end\":{\"line\":110,\"column\":13}},{\"start\":{\"line\":111,\"column\":6},\"end\":{\"line\":112,\"column\":13}}]},\"3\":{\"loc\":{\"start\":{\"line\":119,\"column\":6},\"end\":{\"line\":134,\"column\":null}},\"type\":\"if\",\"locations\":[{\"start\":{\"line\":119,\"column\":6},\"end\":{\"line\":134,\"column\":null}},{\"start\":{\"line\":119,\"column\":6},\"end\":{\"line\":134,\"column\":null}}]},\"4\":{\"loc\":{\"start\":{\"line\":121,\"column\":8},\"end\":{\"line\":125,\"column\":null}},\"type\":\"if\",\"locations\":[{\"start\":{\"line\":121,\"column\":8},\"end\":{\"line\":125,\"column\":null}},{\"start\":{\"line\":121,\"column\":8},\"end\":{\"line\":125,\"column\":null}}]},\"5\":{\"loc\":{\"start\":{\"line\":126,\"column\":8},\"end\":{\"line\":128,\"column\":null}},\"type\":\"if\",\"locations\":[{\"start\":{\"line\":126,\"column\":8},\"end\":{\"line\":128,\"column\":null}},{\"start\":{\"line\":126,\"column\":8},\"end\":{\"line\":128,\"column\":null}}]},\"6\":{\"loc\":{\"start\":{\"line\":129,\"column\":8},\"end\":{\"line\":133,\"column\":null}},\"type\":\"if\",\"locations\":[{\"start\":{\"line\":129,\"column\":8},\"end\":{\"line\":133,\"column\":null}},{\"start\":{\"line\":129,\"column\":8},\"end\":{\"line\":133,\"column\":null}}]},\"7\":{\"loc\":{\"start\":{\"line\":130,\"column\":10},\"end\":{\"line\":132,\"column\":null}},\"type\":\"if\",\"locations\":[{\"start\":{\"line\":130,\"column\":10},\"end\":{\"line\":132,\"column\":null}},{\"start\":{\"line\":130,\"column\":10},\"end\":{\"line\":132,\"column\":null}}]},\"8\":{\"loc\":{\"start\":{\"line\":43,\"column\":4},\"end\":{\"line\":49,\"column\":null}},\"type\":\"if\",\"locations\":[{\"start\":{\"line\":43,\"column\":4},\"end\":{\"line\":49,\"column\":null}},{\"start\":{\"line\":43,\"column\":4},\"end\":{\"line\":49,\"column\":null}}]},\"9\":{\"loc\":{\"start\":{\"line\":50,\"column\":4},\"end\":{\"line\":54,\"column\":null}},\"type\":\"if\",\"locations\":[{\"start\":{\"line\":50,\"column\":4},\"end\":{\"line\":54,\"column\":null}},{\"start\":{\"line\":50,\"column\":4},\"end\":{\"line\":54,\"column\":null}}]},\"10\":{\"loc\":{\"start\":{\"line\":55,\"column\":4},\"end\":{\"line\":59,\"column\":null}},\"type\":\"if\",\"locations\":[{\"start\":{\"line\":55,\"column\":4},\"end\":{\"line\":59,\"column\":null}},{\"start\":{\"line\":55,\"column\":4},\"end\":{\"line\":59,\"column\":null}}]},\"11\":{\"loc\":{\"start\":{\"line\":60,\"column\":4},\"end\":{\"line\":64,\"column\":null}},\"type\":\"if\",\"locations\":[{\"start\":{\"line\":60,\"column\":4},\"end\":{\"line\":64,\"column\":null}},{\"start\":{\"line\":60,\"column\":4},\"end\":{\"line\":64,\"column\":null}}]},\"12\":{\"loc\":{\"start\":{\"line\":65,\"column\":4},\"end\":{\"line\":69,\"column\":null}},\"type\":\"if\",\"locations\":[{\"start\":{\"line\":65,\"column\":4},\"end\":{\"line\":69,\"column\":null}},{\"start\":{\"line\":65,\"column\":4},\"end\":{\"line\":69,\"column\":null}}]},\"13\":{\"loc\":{\"start\":{\"line\":70,\"column\":4},\"end\":{\"line\":72,\"column\":null}},\"type\":\"if\",\"locations\":[{\"start\":{\"line\":70,\"column\":4},\"end\":{\"line\":72,\"column\":null}},{\"start\":{\"line\":70,\"column\":4},\"end\":{\"line\":72,\"column\":null}}]},\"14\":{\"loc\":{\"start\":{\"line\":73,\"column\":4},\"end\":{\"line\":79,\"column\":null}},\"type\":\"if\",\"locations\":[{\"start\":{\"line\":73,\"column\":4},\"end\":{\"line\":79,\"column\":null}},{\"start\":{\"line\":73,\"column\":4},\"end\":{\"line\":79,\"column\":null}}]},\"15\":{\"loc\":{\"start\":{\"line\":80,\"column\":4},\"end\":{\"line\":86,\"column\":null}},\"type\":\"if\",\"locations\":[{\"start\":{\"line\":80,\"column\":4},\"end\":{\"line\":86,\"column\":null}},{\"start\":{\"line\":80,\"column\":4},\"end\":{\"line\":86,\"column\":null}}]},\"16\":{\"loc\":{\"start\":{\"line\":87,\"column\":4},\"end\":{\"line\":94,\"column\":null}},\"type\":\"if\",\"locations\":[{\"start\":{\"line\":87,\"column\":4},\"end\":{\"line\":94,\"column\":null}},{\"start\":{\"line\":87,\"column\":4},\"end\":{\"line\":94,\"column\":null}}]}},\"s\":{\"0\":1,\"1\":1,\"2\":1,\"3\":1,\"4\":1,\"5\":14,\"6\":0,\"7\":0,\"8\":0,\"9\":0,\"10\":0,\"11\":0,\"12\":0,\"13\":0,\"14\":0,\"15\":0,\"16\":14,\"17\":6,\"18\":6,\"19\":6,\"20\":5,\"21\":5,\"22\":4,\"23\":5,\"24\":4,\"25\":5,\"26\":4,\"27\":3,\"28\":6,\"29\":14,\"30\":2,\"31\":2,\"32\":2,\"33\":14,\"34\":14,\"35\":14,\"36\":1,\"37\":1,\"38\":1,\"39\":13,\"40\":14,\"41\":2,\"42\":12,\"43\":14,\"44\":2,\"45\":12,\"46\":14,\"47\":2,\"48\":12,\"49\":14,\"50\":2,\"51\":12,\"52\":14,\"53\":12,\"54\":14,\"55\":12,\"56\":14,\"57\":12,\"58\":14,\"59\":12,\"60\":1,\"61\":1},\"f\":{\"0\":1,\"1\":14,\"2\":0,\"3\":6,\"4\":6,\"5\":2},\"b\":{\"0\":[1,1],\"1\":[1],\"2\":[0,0,0,0,0],\"3\":[5,1],\"4\":[4,1],\"5\":[4,1],\"6\":[4,1],\"7\":[3,1],\"8\":[1,13],\"9\":[2,12],\"10\":[2,12],\"11\":[2,12],\"12\":[2,12],\"13\":[12,2],\"14\":[12,2],\"15\":[12,2],\"16\":[12,2]}}},\"config\":{\"bail\":0,\"changedFilesWithAncestor\":false,\"collectCoverage\":true,\"collectCoverageFrom\":[],\"coverageDirectory\":\"/Users/sigmundd/Code/metrics/docs/coverage\",\"coverageProvider\":\"babel\",\"coverageReporters\":[\"json\",\"lcov\",\"text\",\"clover\",\"html\"],\"detectLeaks\":false,\"detectOpenHandles\":false,\"errorOnDeprecated\":false,\"expand\":false,\"findRelatedTests\":false,\"forceExit\":false,\"json\":false,\"lastCommit\":false,\"listTests\":false,\"logHeapUsage\":false,\"maxConcurrency\":5,\"maxWorkers\":11,\"noStackTrace\":false,\"nonFlagArgs\":[],\"notify\":false,\"notifyMode\":\"failure-change\",\"onlyChanged\":false,\"onlyFailures\":false,\"passWithNoTests\":false,\"projects\":[],\"reporters\":[[\"default\",{}],[\"/Users/sigmundd/Code/metrics/node_modules/jest-html-reporters/index.js\",{\"publicPath\":\"./docs\",\"filename\":\"test-report.html\",\"pageTitle\":\"Metrics :: Test Results\"}]],\"rootDir\":\"/Users/sigmundd/Code/metrics\",\"runTestsByPath\":false,\"skipFilter\":false,\"testFailureExitCode\":1,\"testPathPattern\":\"\",\"testSequencer\":\"/Users/sigmundd/Code/metrics/node_modules/@jest/test-sequencer/build/index.js\",\"updateSnapshot\":\"new\",\"useStderr\":false,\"verbose\":true,\"watch\":false,\"watchAll\":false,\"watchman\":true},\"endTime\":1591793739784,\"_reporterOptions\":{\"publicPath\":\"./docs\",\"filename\":\"test-report.html\",\"pageTitle\":\"Metrics :: Test Results\"}}" </script> <script type="text/javascript">/*! Copyright Harry All rights reserved. */!function(n){var r={};function o(e){if(r[e])return r[e].exports;var t=r[e]={i:e,l:!1,exports:{}};return n[e].call(t.exports,t,t.exports,o),t.l=!0,t.exports}o.m=n,o.c=r,o.d=function(e,t,n){o.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},o.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},o.t=function(t,e){if(1&e&&(t=o(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var n=Object.create(null);if(o.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var r in t)o.d(n,r,function(e){return t[e]}.bind(null,r));return n},o.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return o.d(t,"a",t),t},o.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},o.p="",o(o.s=344)}([function(e,t,n){e.exports=n(494)()},function(e,t,n){"use strict";e.exports=n(364)},function(e,t,n){var r; /*! diff --git a/examples/src/app.ts b/examples/src/app.ts index 9c4760f57d7a815a6c128ade1dac73edca036ee5..de34e23ebce4bfd31c96ca3e91f7fe22f4e1474e 100644 --- a/examples/src/app.ts +++ b/examples/src/app.ts @@ -3,7 +3,7 @@ import * as http from 'http' import * as express from 'express' -import { Metrics } from '../../dist/index' +import { Metrics, MetricType } from '../../dist/index' class App { public app: express.Application @@ -27,9 +27,8 @@ class App { this.metrics.addCustomMetric({ name: 'test', - help: 'Some Test Metric', - labelNames: ['tester'] - }) + help: 'Some Test Metric' + }, MetricType.COUNTER) this.router.use(this.metrics.collect) @@ -39,7 +38,7 @@ class App { res.status(200).send('foo') }) this.router.get('/bar', (req:express.Request, res:express.Response) => { - this.metrics.incCustomMetric('test', 'tester', 'called_bar') + this.metrics["test"].inc() res.status(200).send('bar') }) this.router.get('/404', (req:express.Request, res:express.Response) => { diff --git a/src/index.ts b/src/index.ts index 5d4716eea68f693a0ad7f9e05db0523cf5742129..b6e90c7292e9de9397b6516b9909581b6f01ef76 100644 --- a/src/index.ts +++ b/src/index.ts @@ -11,7 +11,14 @@ export interface Options { export interface CustomMetric { name: string help: string - labelNames: string[] + labelNames?: string[] +} + +export enum MetricType { + GAUGE, + COUNTER, + HISTOGRAM, + SUMMARY } export class Metrics { @@ -27,11 +34,11 @@ export class Metrics { public readonly _numOfRequests: any public readonly _numOfErrors: any - public readonly _customMetrics: any + public readonly customMetrics: any constructor (options: Partial<Options> = {}) { this._client = require('prom-client') - this._customMetrics = {} + this.customMetrics = {} if (typeof options.ignore !== 'undefined') { this._ignore = options.ignore @@ -87,24 +94,23 @@ export class Metrics { } } - public addCustomMetric = (options: CustomMetric): void => { - this._customMetrics[options.name] = new this._client.Gauge({ - name: options.name, - help: options.help, - labelNames: options.labelNames - }) - } - - public incCustomMetric = (name: string, label: string, value: string): void => { - const inc: any = {} - inc[label] = value - this._customMetrics[name].inc(inc) - } - - public decCustomMetric = (name: string, label: string, value: string): void => { - const dec: any = {} - dec[label] = value - this._customMetrics[name].dec(dec) + public addCustomMetric = (options: CustomMetric, type: MetricType): void => { + switch (type) { + case MetricType.COUNTER: + this.customMetrics[options.name] = new this._client.Counter(options) + break + case MetricType.GAUGE: + this.customMetrics[options.name] = new this._client.Gauge(options) + break + case MetricType.HISTOGRAM: + this.customMetrics[options.name] = new this._client.Histogram(options) + break + case MetricType.SUMMARY: + this.customMetrics[options.name] = new this._client.Summary(options) + break + default: + break + } } public collect = (req: express.Request, res: express.Response, next: express.NextFunction): void => {