{"id":26942443,"url":"https://github.com/connectedcars/node-logutil","last_synced_at":"2025-04-02T16:49:07.737Z","repository":{"id":24308505,"uuid":"101165138","full_name":"connectedcars/node-logutil","owner":"connectedcars","description":null,"archived":false,"fork":false,"pushed_at":"2025-01-21T14:30:29.000Z","size":1391,"stargazers_count":2,"open_issues_count":3,"forks_count":2,"subscribers_count":11,"default_branch":"master","last_synced_at":"2025-03-25T11:02:26.577Z","etag":null,"topics":["backend","nodejs"],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/connectedcars.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-08-23T09:53:30.000Z","updated_at":"2025-01-21T14:30:33.000Z","dependencies_parsed_at":"2024-03-21T23:33:35.829Z","dependency_job_id":"46d0789d-3c66-4def-bdda-f6e5ae8749a3","html_url":"https://github.com/connectedcars/node-logutil","commit_stats":{"total_commits":138,"total_committers":14,"mean_commits":9.857142857142858,"dds":0.7681159420289855,"last_synced_commit":"cc18085fe044a6fc9c8d75fc9476b2722b946dca"},"previous_names":[],"tags_count":43,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/connectedcars%2Fnode-logutil","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/connectedcars%2Fnode-logutil/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/connectedcars%2Fnode-logutil/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/connectedcars%2Fnode-logutil/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/connectedcars","download_url":"https://codeload.github.com/connectedcars/node-logutil/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246598199,"owners_count":20802975,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["backend","nodejs"],"created_at":"2025-04-02T16:49:05.982Z","updated_at":"2025-04-02T16:49:07.729Z","avatar_url":"https://github.com/connectedcars.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# node-logutil\n\n[![Build Status](https://travis-ci.org/connectedcars/node-logutil.svg?branch=master)](https://travis-ci.org/connectedcars/node-logutil)\n[![Coverage Status](https://coveralls.io/repos/github/connectedcars/node-logutil/badge.svg?branch=master)](https://coveralls.io/github/connectedcars/node-logutil?branch=master)\n\n## Installation\n\n``` javascript\nnpm install https://github.com/connectedcars/node-logutil#v1.1.3\n```\n\n## API\n\n### log.debug(message[, context])\n\nLogs the provided `message` with the optional `context` as a JSON string, if the log level is set to output debug.\n\nThe method takes most input, but the combination described above is the recommended one.\n\n#### message\n\nType: `string`\n\nDescriptive log message\n\n#### context\n\nType: `object`\n\nObject hash to provide log context.\n\n### log.statistic(message[, context])\n\nLogs the provided `message` with the optional `context` as a JSON string, if the log level is set to output statistic.\n\nThe method takes most input, but the combination described above is the recommended one.\n\n#### message\n\nType: `string`\n\nDescriptive log message\n\n#### context\n\nType: `object`\n\nObject hash to provide log context.\n\n### log.info(message[, context])\n\nLogs the provided `message` with the optional `context` as a JSON string, if the log level is set to output info.\n\nThe method takes most input, but the combination described above is the recommended one.\n\n#### message\n\nType: `string`\n\nDescriptive log message\n\n#### context\n\nType: `object`\n\nObject hash to provide log context.\n\n### log.warn(message[, context])\n\nLogs the provided `message` with the optional `context` as a JSON string, if the log level is set to output warnings.\n\nThe method takes most input, but the combination described above is the recommended one.\n\n#### message\n\nType: `string`\n\nDescriptive log message\n\n#### context\n\nType: `object`\n\nObject hash to provide log context.\n\n### log.error(message[, context])\n\nLogs the provided `message` with the optional `context` as a JSON string, if the log level is set to output errors.\n\nThe method takes most input, but the combination described above is the recommended one.\n\n#### message\n\nType: `string`\n\nDescriptive log message\n\n#### context\n\nType: `object`\n\nObject hash to provide log context.\n\n### log.critical(message[, context])\n\nLogs the provided `message` with the optional `context` as a JSON string, if the log level is set to output critical.\n\nThe method takes most input, but the combination described above is the recommended one.\n\n#### message\n\nType: `string`\n\nDescriptive log message\n\n#### context\n\nType: `object`\n\nObject hash to provide log context.\n\n## log.MetricRegistry()\nA singleton instance that holds the state of all metrics in the application at a given point in time. The class should be instantiated globally and kept through the process lifetime.\n\n### log.MetricsRegistry.prototype.cumulative(name, value[, labels])\nA monotically increasing number that. E.g. the number of requests since the process started.\n\n#### name\nType: `string`\nName of the metric to write. The recommended format is `[namespace]/[metric-name]`. E.g. `ingester/queue-size` \n\n\n#### value\nType: `number`\nA value to write. It's worth noting that we're always using floating-point precision for these values.\n\n#### labels\nType: `object`\nAn optional label map that denotes some specific properties you want to group by / filter on later. Please note that this map _must_ have hashable values. Thus, you're not allowed to nest objects.\nIt's also worth noting that the `MetricRegistry` will log all permutations of the label, so please only use it to store categorical types and not, say `carId`s.\nExample: `{tableName: 'LatestCarPositions'}`\n\n\n##### Scenarios where you'd want to use this metric type\nGenerally every time you're interested in monitoring:\n* the relative change in a value (marginal difference)\n* or the value relative to the time period\n\nE.g.\n* Inserted rows since last time\n* Incoming HTTP requests\n\n\n### log.MetricsRegistry.prototype.gauge(name, value[, labels, reducerFn])\n_Please refer to `log.MetricsRegistry.prototype.cumulative()` for a definition of the arguments name, value and labels_\n\nAn instantaneous measurement of a varying number. Per default, we will only store the value and timestamp of the latest inserted value. So if you insert two values, e.g. `gauge('foo', 2)` at time 0 and `gauge('foo', 4)` at time 2, and the metrics are scraped at time 3, we will report `value=4,time=2` to the log. If you for some reason don't want this, you can specify an optional `reducerFn` argument:\n```\n// Function that takes the mean over all values in that timespan\nconst fn = (arr) =\u003e arr.reduce((a, b) =\u003e a+b)) / arr.length\n\n// Sample some data\nregistry.gauge('foo', 10, null, fn)\nregistry.gauge('foo', 20, null, fn)\n\n// logMetric reports value=30 and generates a timestamp\nregistry.logMetrics()\n```\n\n##### Scenarios where you'd want to use this metric type\nEvery time you want to capture a state at a particular time. E.g.:\n* Size of a queue at a particular time\n* CPU utilization\n\nA rule of thumb: If a value can go vary (i.e. go up and down), and it should be captured at a specific time, then it's a good candidate for a gauge.\n\n\n### log.MetricRegistry.prototype.logMetrics()\nCaptures a snapshot of the image state and adds `endTime=Date.now()` to all objects. Afterwards all metrics are dumped to stdout using `node-logutil`'s `log.statistic` function. All metrics are dumped using `LOG_LEVEL=INFO`, so make sure your application uses at least that log level.\n\nThis function is intended to be used together with [metrics-subscriber-api](https://github.com/connectedcars/metrics-subscriber-api)\n\n\n### log.MetricRegistry.prototype.getMetrics()\nReturns all metrics as an array of objects.\nExample:\n```\n{\n  name: 'gauge-metric',\n  type: 'GAUGE',\n  value: 50,\n  labels: { brand: 'vw' }\n}\n```\n### log.MetricRegistry.prototype.getPrometheusMetrics()\nReturns an array of strings formatted using the [Prometheus exposition format](https://github.com/prometheus/docs/blob/master/content/docs/instrumenting/exposition_formats.md)\nThe format should follow their EBNF definition, but is not tested against a parser as of this moment.\n\n\nThis function is intended to be exposed through a small HTTP server and used in conjunction with Prometheus in the future.\n\n## Usage\n\n``` javascript\nconst log = require('logutil')\n\nlog.debug('This is a debug message')\n// Outputs to stdout: {\"message\":\"This is a debug message\",\"severity\":\"DEBUG\",\"timestamp\":\"2017-09-01T13:37:42Z\"}\nlog.debug('This is a statistic value', { foo: 42, bar: 1337 })\n// Outputs to stdout: {\"message\":\"Statistics\",\"severity\":\"STATISTIC\",\"timestamp\":\"2017-09-01T13:37:42Z\", \"content\":{\"foo\":42,\"bar\":1337}}\nlog.info('This is an info message')\n// Outputs to stdout: {\"message\":\"This is an info message\",\"severity\":\"INFO\",\"timestamp\":\"2017-09-01T13:37:42Z\"}\nlog.warn('This is a warning message', { type: 'missing-item' })\n// Outputs to stderr: {\"message\":\"This is a warning message\",\"severity\":\"WARNING\",\"timestamp\":\"2017-09-01T13:37:42Z\",\"context\":{\"type\":\"missing-item\"}}\nlog.error('This is an error message', { context: { items: ['foo', 'bar'] } })\n// Outputs to stderr: {\"message\":\"This is an error message\",\"severity\":\"ERROR\",\"timestamp\":\"2017-09-01T13:37:42Z\",\"context\":{\"items\":[\"foo\",\"bar\"]}}\nlog.critical('This is a critical message', { context: { items: ['foo', 'bar'] } })\n// Outputs to stderr: {\"message\":\"This is a critical message\",\"severity\":\"CRITICAL\",\"timestamp\":\"2017-09-01T13:37:42Z\",\"context\":{\"items\":[\"foo\",\"bar\"]}}\n\nlog.debug(() =\u003e {\n  // Only runs if log level is debug\n  return Promise.resolve('This is a debug message')\n})\n// Outputs to stdout: {\"message\":\"This is a debug message\",\"severity\":\"DEBUBG\",\"timestamp\":\"2017-09-01T13:37:42Z\"}\nlog.info(() =\u003e {\n  // Only runs if log level is info\n  return new Promise(resolve =\u003e {\n    setTimeout(() =\u003e {\n      resolve('This is an info message')\n    }, 500)\n  })\n})\n// Outputs to stdout (after 500 ms): {\"message\":\"This is an info message\",\"severity\":\"INFO\",\"timestamp\":\"2017-09-01T13:37:42Z\"}\n\n// Instantiate as a singleton\nconst registry = log.MetricRegistry()\n\n// Write some data\nawait registry.gauge('namespace/metric-name', 20, {brand: 'vw'})\nawait registry.cumulative('namespace/cumulative-metric-name', 40, {brand: 'seat'})\n\n// In case you want to do aggregations more granular than the regular dump, you can pass in a reducer function taking an array of numbers.\nawait registry.gauge('namespace/metric-name', 20, {brand: 'vw'}, (arr) =\u003e arr.reduce((a, b) =\u003e a+b)) / arr.length\n\n// Dump metrics to stdout regularly\nsetInterval(registry.logMetrics, 30000)\n```\n\n## Configuration\n\nDetermining what to output depends on the environment variable `LOG_LEVEL`. This variable can be `DEBUG`, `STATISTIC`, `INFO`, `WARN`, `ERROR`, or `CRITICAL` but defaults to `WARN`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fconnectedcars%2Fnode-logutil","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fconnectedcars%2Fnode-logutil","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fconnectedcars%2Fnode-logutil/lists"}