{"id":19621330,"url":"https://github.com/commenthol/debug-level","last_synced_at":"2025-04-28T03:32:17.510Z","repository":{"id":26895911,"uuid":"107903556","full_name":"commenthol/debug-level","owner":"commenthol","description":"debug with levels","archived":false,"fork":false,"pushed_at":"2025-02-10T20:00:11.000Z","size":735,"stargazers_count":13,"open_issues_count":1,"forks_count":4,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-04-20T17:39:21.471Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"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/commenthol.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","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-10-22T21:17:10.000Z","updated_at":"2025-02-10T20:00:15.000Z","dependencies_parsed_at":"2024-06-18T20:12:53.218Z","dependency_job_id":"9ae8450c-bab8-4baa-8478-7f4067adf9fd","html_url":"https://github.com/commenthol/debug-level","commit_stats":{"total_commits":76,"total_committers":3,"mean_commits":"25.333333333333332","dds":0.02631578947368418,"last_synced_commit":"8af9c5345a35864051ce82ab3f463326c99719fd"},"previous_names":[],"tags_count":26,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/commenthol%2Fdebug-level","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/commenthol%2Fdebug-level/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/commenthol%2Fdebug-level/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/commenthol%2Fdebug-level/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/commenthol","download_url":"https://codeload.github.com/commenthol/debug-level/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251246236,"owners_count":21558761,"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":[],"created_at":"2024-11-11T11:22:24.128Z","updated_at":"2025-04-28T03:32:17.502Z","avatar_url":"https://github.com/commenthol.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# debug-level\n\n\u003e debug with levels\n\n[![NPM version](https://badge.fury.io/js/debug-level.svg)](https://www.npmjs.com/package/debug-level/)\n[![CI](https://github.com/commenthol/debug-level/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/commenthol/debug-level/actions/workflows/ci.yml)\n\nA universal JavaScript logging/ debugging utility which works in node and\nbrowsers.  \nIt behaves similar to the popular [debug][] module but adds additional\nlog levels.  \nPrints colored and human readable output for development and [bunyan][] like\nJSON for production environments.  \nFully typed with JSDocs and Typescript.\n\n*human readable format for development*\n\n![debug server development][debug-level-dev.png]\n\n*machine readable with colors*\n\n![debug server development][debug-level-dev-json.png]\n\n*machine readable for production use*\n\n![debug server development][debug-level-prod.png]\n\n**Table of Contents**\n\n\u003c!-- !toc (minlevel=2) --\u003e\n\n* [Installation](#installation)\n* [Usage](#usage)\n* [Examples](#examples)\n* [Settings](#settings)\n  * [Environment Variables](#environment-variables)\n  * [Options](#options)\n  * [Writing to file](#writing-to-file)\n  * [Serializers](#serializers)\n* [Levels](#levels)\n* [Namespaces](#namespaces)\n  * [Conventions](#conventions)\n  * [Wildcards](#wildcards)\n* [Output](#output)\n  * [JSON output](#json-output)\n  * [toJSON](#tojson)\n* [Wrap console logs](#wrap-console-logs)\n* [Wrap debug output](#wrap-debug-output)\n* [Handle node exit events](#handle-node-exit-events)\n* [Emit Log events with ProcLog](#emit-log-events-with-proclog)\n* [Logging HTTP requests](#logging-http-requests)\n* [Logging Browser messages](#logging-browser-messages)\n* [Logging in Elastic Common Schema (ECS)](#logging-in-elastic-common-schema-ecs)\n  * [ECS-Serializers](#ecs-serializers)\n* [License](#license)\n* [Benchmarks](#benchmarks)\n* [References](#references)\n\n\u003c!-- toc! --\u003e\n\n## Installation\n\n```\n$ npm install --save debug-level\n```\n\n## Usage\n\n`debug-level` provides 7 log levels which are `TRACE`, `DEBUG`, `INFO`, `WARN`, `ERROR`,\n`FATAL` and `OFF`.\n\nEach level has a corresponding method `DEBUG` -\u003e `log.debug` ... `FATAL` --\u003e\n`log.fatal` which shall be used to indicated the level to log.\n\nThe characters `%s`, `%d`, `%i`, `%f`, `%j`, `%o`, `%O`, `%%` are supported\n[formatters](https://nodejs.org/api/util.html#util_util_format_format_args) when\ngiven in the first argument.\n\n[examples/levels.js](./examples/levels.js)\n\n```js\n// ESM\nimport { Log, logger } from 'debug-level'\n// Commonjs\nconst { Log, logger } = require('debug-level')\n\n// creates a logger for \u003cnamespace\u003e `test`\nconst log = new Log('test')\n// or using a global Log instance\nconst log = logger('test')\n\nlog.fatal(new Error('fatal'))        // logs an Error at level FATAL\nlog.error(new Error('boom'))         // logs an Error at level ERROR\nlog.warn('huh %o', {ghost: 'rider'}) // logs a formatted object at level WARN\nlog.info('%s world', 'hello')        // logs a formatted string at level INFO\nlog.debug({object: 1})               // logs an object at level DEBUG\nlog.trace('hi')                      // logs a string at level TRACE\nlog.log('always logs')               // always logs regardless of set level\n```\n\nRunning `levels.js` without environment variables will show no output (apart\nfrom `log.log()`). Setting `DEBUG_LEVEL` only shows all lines with their\nrespective level. Combined with `DEBUG`, using comma separated\n[namespaces](#namespaces), only those log lines with matching namespace and\nlevel get logged.\n\nThe following table gives an overview of possible combinations:\n\n| DEBUG_LEVEL |            DEBUG            | Output                                                                                                                |\n| :---------: | :-------------------------: | :-------------------------------------------------------------------------------------------------------------------- |\n|     --      |             --              | no output                                                                                                             |\n|    FATAL    |             --              | logs only log.fatal                                                                                                   |\n|    ERROR    |             --              | log.fatal, log.error                                                                                                  |\n|    WARN     |             --              | log.fatal, log.error, log.warn                                                                                        |\n|    INFO     |             --              | log.fatal, log.error, log.warn and log.info                                                                           |\n|    DEBUG    |             --              | log.fatal, log.error, log.warn, log.info and log.debug                                                                |\n|    TRACE    |             --              | log.fatal, log.error, log.warn, log.info, log.debug and log.trace                                                     |\n|     --      |       `\u003cnamespaces\u003e`        | log.fatal, to log.debug which apply to `\u003cnamespaces\u003e`. \u003cbr\u003e Same behavior as [debug][].                               |\n|    FATAL    |       `\u003cnamespaces\u003e`        | log.fatal for all `\u003cnamespaces\u003e` only                                                                                 |\n|    ERROR    |       `\u003cnamespaces\u003e`        | log.fatal, log.error for `\u003cnamespaces\u003e` only                                                                          |\n|    WARN     |       `\u003cnamespaces\u003e`        | log.fatal, to log.warn for `\u003cnamespaces\u003e` only                                                                        |\n|    INFO     |       `\u003cnamespaces\u003e`        | log.fatal, to log.info for `\u003cnamespaces\u003e` only                                                                        |\n|    DEBUG    |       `\u003cnamespaces\u003e`        | log.fatal, to log.debug for `\u003cnamespaces\u003e` only                                                                       |\n|    TRACE    |       `\u003cnamespaces\u003e`        | log.fatal, to log.trace for `\u003cnamespaces\u003e` only                                                                       |\n|     --      | `ERROR:n1,DEBUG:n2,FATAL:*` | Logs namespace `n1` at level `ERROR`, namespace `n2` at level `DEBUG` and all other namespaces (`*`) at level `FATAL` |\n|    FATAL    |        `ERROR:n1,n2`        | Logs `n1` at level `ERROR`, `n2` at level `FATAL`. All other namespaces will **NOT** get logged                       |\n\n## Examples\n\nRun the [server.js](./examples/server.js) example with different settings:\n\nNo output\n\n```sh\n$ node examples/server.js\n```\n\nLogging .info and .error\n\n```sh\n$ DEBUG_LEVEL=INFO node examples/server.js\n```\n\nLogging .error for server only\n\n```sh\n$ DEBUG_LEVEL=ERROR DEBUG=server node examples/server.js\n```\n\nLogging .error in production mode (JSON without colors)\n\n```sh\n$ NODE_ENV=production DEBUG_LEVEL=ERROR node examples/server.js\n```\n\nBehavior is as with [debug][].\n\n```sh\n$ DEBUG=server,client:A node examples/server.js\n```\n\nLog `server` at level `INFO`, and all other modules at level `ERROR`\n\n```sh\n$ DEBUG=INFO:server,ERROR:* node examples/server.js\n```\n\n## Settings\n\n### Environment Variables\n\n**Common**\n\n| Setting      | Values                       | Description                                    |\n| ------------ | ---------------------------- | ---------------------------------------------- |\n| DEBUG        | \u003cnamespace\u003e                  | Enables/disables specific debugging namespaces |\n| DEBUG_LEVEL  | ERROR, WARN, **INFO**, DEBUG | sets debug level                               |\n| DEBUG_COLORS | **true**/false               | display colors (if supported)                  |\n\n**Node only**\n\n| Setting             | Values             | `NODE_ENV=`\u003cbr\u003e`development` | Description                                       |\n| ------------------- | ------------------ | ---------------------------- | ------------------------------------------------- |\n| DEBUG_JSON          | **true**/false     | false                        | use JSON format instead of string based log       |\n| DEBUG_SERVERINFO    | **true**/false     | false                        | adds server information like `pid` and `hostname` |\n| DEBUG_TIMESTAMP     | **iso**/epoch/unix | undefined                    | datetime format                                   |\n| DEBUG_LEVEL_NUMBERS | true/**false**     | false                        | log levels as numbers                             |\n\nFor `NODE_ENV !== 'development'` the default logging is in JSON format using serverinfo and iso date.\n\n**Browsers only**\n\n| Setting   | Values | Description                                                             |\n| --------- | ------ | ----------------------------------------------------------------------- |\n| DEBUG_URL | URL    | log in JSON format to server (needs `middleware.js` at the server side) |\n\nIn the browser `localStorage` is used to set/save the settings.\nE.g. to enable level ERROR an all namespaces type in console and refresh your page/ app:\n\n```\nlocalStorage.DEBUG_LEVEL='ERROR'\nlocalStorage.DEBUG='*'\n```\n\n### Options\n\nYou may set the global log options with:\n\n[examples/options.js](./examples/options.js)\n\n```js\nimport fs from 'fs'\nimport { Log } from 'debug-level'\n\n// log into file instead of process.stderr\nconst stream = fs.createWriteStream('./my.log')\n\n// The options will be set for all Loggers...\nLog.options({\n  level: 'DEBUG',\n  json: true,\n  levelNumbers: false,\n  serverinfo: true,\n  timestamp: 'epoch',\n  colors: false,\n  stream,\n  serializers: {\n    err: Log.serializers.err // default error serializer is always set\n  }\n})\nconst log = new Log('my:namespace')\n\nlog.debug({ object: 1 }) // ...\n```\n\n\n| Option name  | Setting              | env     | Type     | Description                                  |\n| ------------ | -------------------- | ------- | -------- | -------------------------------------------- |\n| level        | DEBUG_LEVEL          | _both_  | String   |                                              |\n| namespaces   | DEBUG                | _both_  | String   |                                              |\n| json         | DEBUG_JSON           | node    | Boolean  |                                              |\n| spaces       | DEBUG_SPACES         | node    | Number   | JSON spaces                                  |\n| splitLine    | DEBUG_SPLIT_LINE     | node    | Boolean  | split lines for pretty, debug like, output   |\n| timestamp    | DEBUG_TIMESTAMP      | node    | String   | Set null/iso/unix/epoch timestamp format     |\n| colors       | DEBUG_COLORS         | _both_  | Boolean  |                                              |\n| stream       | --                   | node    | Stream   | output stream (defaults to `process.stderr`) |\n| sonic        | DEBUG_SONIC          | node    | Boolean  | fast buffered writer                         |\n| sonicLength  | DEBUG_SONIC_LENGTH   | node    | number   | min size of buffer in byte (default is 4096) |\n| sonicFlushMs | DEBUG_SONIC_FLUSH_MS | node    | number   | flush after each x ms (default is 1000)      |\n| toJson       | --                   | node    | Function | custom json serializer                       |\n| serializers  | --                   | _both_  | Object   | serializers by keys                          |\n| url          | DEBUG_URL            | browser | String   |                                              |\n\n### Writing to file\n\nConsider using a tool like [logrotate](https://github.com/logrotate/logrotate) to rotate the log-file.\n\n```sh\n$ node server.js 2\u003e /var/log/server.log\n```\n\nTo rotate the file with logrotate, add the following to `/etc/logrotate.d/server`:\n\n```\n/var/log/server.log {\n  su root\n  daily\n  rotate 7\n  delaycompress\n  compress\n  notifempty\n  missingok\n  copytruncate\n}\n```\n\nEnsure that logrotate is running as a service on startup:\n\n```sh\n$ sudo service enable logrotate\n```\n\n\n### Serializers\n\nTo serialize top-level object keys you may use standard or custom functions.\nPer default a serializer for key `err` is provided in node and browser.\n\n```js\n// custom serialize function for key `my`\nconst mySerializer = function (val) {\n  if (typeof val !== 'object' || !val) return\n  const { foo } = val\n  return foo\n}\n\nconst log = new Log('foobar', { serializers: { my: mySerializer }})\n\nconst my = { foo: 'bar', sense: 42 }\nlog.info({ my })\n//\u003e INFO foobar {my: 'bar'} +0ms\n```\n\n## Levels\n\n(From [bunyan][])\n\n- `FATAL`: The service/app is going to stop or becomes unusable.\n   An operator should definitely look into this soon.\n- `ERROR`: Fatal for a particular request, but the service/app continues\n  servicing. An operator should look at this soon(ish)\n- `WARN`: A note on something that should probably be looked at by an operator\n  eventually.\n- `INFO`: Detail on regular operation.\n- `DEBUG`: Anything else, i.e. too verbose to be included in `INFO` level.\n- `TRACE`: Trace level.\n\n## Namespaces\n\nNamespaces select dedicated packages for logging (check\n[Conventions](#conventions)) considering the level selected with `DEBUG_LEVEL`.\nTo choose a different log-level prefix the namespace with the level to be set\nfor that namespace.\n\nE.g. to log all packages on level `FATAL`, `test` on `ERROR`, `log:A` on `WARN`.\nAs a side-effect `*` will also cause **all** modules using [debug][] being\nlogged.\n\n```\n$ DEBUG_LEVEL=FATAL DEBUG=ERROR:test,WARN:log:A,* node examples/levels.js\n  ERROR test Error: boom\n  FATAL test fatal test +7ms\n  WARN log:A huh {\"ghost\":\"rider\"} +0ms\n  ERROR log:A Error: baam\n  FATAL log:A fatal A +1ms\n  FATAL log:B fatal B +0ms\n  using-debug using debug +0ms\n  using-debug:A using debug - feature A +1ms\n```\n\nSo maybe consider using `DEBUG=...,FATAL:*` instead:\n\n```\n$ DEBUG=ERROR:test,WARN:log:A,FATAL:*,using-debug:* node examples/levels.js\n  ERROR test Error: boom\n  FATAL test fatal test +7ms\n  WARN log:A huh {\"ghost\":\"rider\"} +0ms\n  ERROR log:A Error: baam\n  FATAL log:A fatal A +1ms\n  FATAL log:B fatal B +0ms\n  using-debug:A using debug - feature A +1ms\n```\n\n### Conventions\n\n(from [debug][])\n\nIf you're using this in one or more of your libraries, you should use the name\nof your library so that developers may toggle debugging as desired without\nguessing names. If you have more than one debuggers you should prefix them with\nyour package name and use \":\" to separate features. For example `bodyParser`\nfrom Connect would then be `connect:bodyParser`. If you append a `*` to the end\nof your name, it will always be enabled regardless of the setting of the DEBUG\nenvironment variable. You can then use it for normal output as well as debug\noutput.\n\n### Wildcards\n\n(from [debug][])\n\nThe `*` character may be used as a wildcard. Suppose for example your library\nhas debuggers named `connect:bodyParser`, `connect:compress`, `connect:session`,\ninstead of listing all three with\n`DEBUG=connect:bodyParser,connect:compress,connect:session`, you may simply do\n`DEBUG=connect:*`, or to run everything using this module simply use `DEBUG=*`.\n\nYou can also exclude specific debuggers by prefixing them with a `-` character.\nFor example, `DEBUG=*,-connect:*` would include all debuggers except those\nstarting with `connect:`.\n\n## Output\n\n`debug-level` supports two types of outputs\n\n1. human readable - this pretty much follows the output of [debug][] This is the\n   default for `NODE_ENV=development`. Can be forced using `DEBUG_JSON=0`\n2. machine readable - JSON output (similar to [bunyan][]) This is the default\n   for test/production envs. Can be forced using `DEBUG_JSON=1`\n\n### JSON output\n\nWhen using `%j`, `%o`, `%O` all will expand to `%j` JSON, so there is no\ndifference when using in node.\n\nNonetheless it is **not recommended to use** these formatters for logging errors\nand objects as this complicates later log inspection.\n\nEach log records into a single JSON stringified line.\n\nCore fields are:\n\n- `level`: One of the six log levels.\n- `name`: The name of the namespace logged.\n- `msg`: A message which should give reason for logging the line.\n- `hostname`: Hostname of the server. (Requires option serverinfo)\n- `pid`: PID of the logged process. (Requires option serverinfo).\n- `time`: Timestamp (Suppress with option timestamp='').\n- `diff`: Diff-time in milliseconds.\n\nSee [examples/jsonOutput.cjs](./examples/jsonOutput.cjs).\n\nWhen logging a message string, number or a formatted string it will show up under `msg` like:\n\n```js\nlog.debug('a %s, a number %d, an %o and %j', 'string', 1.2, {object: 1}, {NOT: 'RECOMMENDED'})\n// \u003e\n{ \"level\": \"DEBUG\",           // log level\n  \"name\": \"package:feature\",  // the namespace of the logger\n  \"msg\": \"a string, a number 1.2, an {\\\"object\\\":1} and {\\\"NOT\\\":\\\"RECOMMENDED\\\"}\", // the formatted message\n  \"hostname\": \"server\",       // server hostname\n  \"pid\": 8310,                // process pid\n  \"time\": \"2017-11-08T21:01:00.025Z\", // timestamp as ISOString\n  \"diff\": 5                   // difftime in ms\n}\n```\n\nObjects without formatters get assigned, arrays will show up under `arr`:\n\n```js\nlog.info({object: 1}, {json: true}, [1, 2, 3], '%s #%d', 'message', 1)\n// \u003e\n{ \"level\": \"INFO\",\n  \"name\": \"package:feature\",\n    \"msg\": \"message #1\"\n  \"object\": 1,\n    \"json\": true,\n  \"arr\": [1,2,3],\n  \"time\": \"2017-11-09T21:09:49.482Z\",\n  \"diff\": 0\n}\n```\n\nAn error gets logged under `err`\n\n```js\nconst err = new TypeError('bam')\nerr.status = 500\nlog.error(err, {object: 1}) // you may add an additional object\n// \u003e\n{ \"level\":\"ERROR\",\n  \"name\":\"package:feature\",\n    \"msg\":\"bam\",\n  \"err\": { // the error object\n    \"name\":\"TypeError\",\n    \"stack\":\"Error: bam\\n    at Object.\u003canonymous\u003e (...\\n    at bootstrap_node.js:608:3\",\n    \"status\": 500\n  },\n  \"object\": 1,\n  \"time\":\"2017-11-09T21:16:16.764Z\",\n  \"diff\":0\n}\n```\n\n### toJSON\n\nIf logging an object you may define a `toJSON()` function on that object to\nchange proper logging of the object itself:\n\n[examples/toJSON.cjs](./examples/toJSON.cjs)\n\n```js\nimport { Log } from 'debug-level'\nconst log = new Log('*')\n\nfunction reqToJSON () {\n  const {ip, method, url} = this\n  return {ip, method, url}\n}\n\n// assume a request obj\nconst req = {\n  method: 'GET', url: '/path', ip: '10.10.10.10',\n  headers: {'user-agent': 'Custom/2.0'}, connection: {/* ... */}\n}\nreq.toJSON = reqToJSON.bind(req)\n\nlog.debug({req: req})\n//\u003e DEBUG * {\"req\":{\"ip\":\"10.10.10.10\",\"method\":\"GET\",\"url\":\"/path\"}} +0ms\n```\n\n## Wrap console logs\n\nSome packages may use `console.log` statements which you may wish to log with\n`debug-level` as well.\n\nBy standard levels are assigned the same way as console does. E.g.\n`console.debug` is assigned to level DEBUG, `console.error` to ERROR.\n\nYou may explicitly assign `console.log` to a log level by attributing e.g. `{\nlevel4log: 'INFO' }`\n\n```js\nimport { Log } from 'debug-level'\n\n// standard - namespace is `console`\nLog.wrapConsole()\n\n// with custom namespace and console.log at level INFO\nLog.wrapConsole('my-console', {level4log: 'INFO'})\n```\n\n## Wrap debug output\n\nFor node only. A lot of packages use the popular [debug][] package. To write the\noutput in JSON with this package you may wrap those log statements.\n\n```js\nimport { Log } from 'debug-level'\n\nLog.wrapDebug()\n```\n\nDo not forget to add the debug package with `npm i debug` within your package.\n\n## Handle node exit events\n\nFor node only. To handle exit events like\n[unhandledRejection](https://nodejs.org/api/process.html#process_event_unhandledrejection)\nand [uncaughtException](https://nodejs.org/api/process.html#process_event_uncaughtexception)\nadd `Log.handleExitEvents()` somewhere in your code. This with log the error at\nlevel FATAL and exit the process with code 1.\n\n```js\n// standard - namespace is `exit`\nLog.handleExitEvents()\n\n// with custom namespace\nLog.handleExitEvents('process-exit')\n```\n\n## Emit Log events with ProcLog\n\nDecouple logging via process event 'log-level'. This allows to use a different\nlogger framework than 'debug-level'. In such cases you'd need to adapt your\nframework of choice for logging. Check `initProcLog()` for inspiration.\n\nEmits the following process event:\n\n```\nprocess.emit('log-level', level, name, fmt, args)\n```\n\nwhere\n- `level` is TRACE, DEBUG, INFO, WARN, ERROR, FATAL, LOG\n- `name` is the namespace of the logger\n- `fmt` is optional formatter, e.g. `%s`\n- `args` is an array of arguments passed to the logger\n\nOnly enabled namespaces emit log events.\n\n```js\nimport { ProcLog, initProcLog } from 'debug-level'\n\n// Initialize process event logging with 'debug-level'\n// define here serializer, stream options, etc.\n// If using a different logger you'd need to provide a custom initializer which \n// connects to the framework of choice.\ninitProcLog({ serializers: {...}, Log: LogEcs })\n// or default\ninitProcLog()\n\n// Add a logger with a namespace.\n// Use options only for defining the log-level (or leave undefined to control\n// via env-vars)\nconst log = new ProcLog('my-webapp:namespace')\n// add some logging\nlog.info('show some logging')\n```\n\n## Logging HTTP requests\n\nTo log http requests/ responses you can enable the `httpLogs` middleware in your\nexpress/ connect server.\n\n```js\nimport express from 'express'\nimport { httpLogs } from 'debug-level'\n\nconst app = express()\napp.use(httpLogs('my-module:http'))\n```\n\nRequest and Response are logged with the built in `reqSerializer` and\n`resSerializer`.  \nAdditionally a request-id is set on `req.id` to allow for building associations\non logs containing that same id. On each request a new id is generated.  \nUse `{ customGenerateRequestId }` in options, to overwrite the built-in method.\n\n**Example** using above code\n\n```js\ncurl \"http://localhost\"\n---\n{\n  \"level\": \"INFO\",\n  \"name\": \"my-module:http\",\n  \"diff\": 0,\n  \"req\": {\n    \"id\": \"1021\",\n    \"method\": \"GET\",\n    \"url\": \"/\",\n    \"remoteAddress\": \"::1\",\n    \"remotePort\": 56259,\n    \"headers\": {\n      \"host\": \"localhost\",\n      \"connection\": \"close\"\n    }\n  },\n  \"res\": {\n    \"headers\": {},\n    \"statusCode\": 200,\n    \"ms\": 1\n  }\n}\n```\n\n## Logging Browser messages\n\nTo log debug messages from the browser on your server you can enable a logger\nmiddleware in your express/ connect server.\n\n```js\nconst app = require('express')()\nconst { browserLogs } = require('debug-level')\n\napp.use('./debug-level', browserLogs({ maxSize: 100 }))\n...\n```\n\nIn your single page application use:\n\n```js\nimport { Log } from 'debug-level/browser'\n\nlocalStorage.setItem('DEBUG_URL', '/debug-level')\nlocalStorage.setItem('DEBUG', 'my-app*')\n// ...\nconst log = new Log('my-app')\n\nlog.debug('my first %s', 'logline')\n```\n\nCheck example at `examples/app`. To run it use:\n\n```bash\nnpm run example\n```\n\nand open \u003chttp://localhost:3000\u003e\n\n## Logging in Elastic Common Schema (ECS)\n\ndebug-level supports logging in ECS format in case you use the ELK stack for log\nmonitoring.\n\nPer default err, req, res serializers are available.\n\n```js\nimport { LogEcs } from 'debug-level' \n\nconst log = new LogEcs('foobar')\n\nlog.fatal(new Error('fatal')) // logs an Error at level FATAL\n//\u003e {\"log\":{\"level\":\"FATAL\",\"logger\":\"foobar\",\"diff_ms\":0},\"message\":\"fatal\",\"@timestamp\":\"2023-07-06T18:40:25.154Z\",\"error\":{\"type\":\"Error\",\"message\":\"fatal\",\"stack_trace\":\"Error: fatal\\\\n    at file:///logecs.js:6:11\\\\n    at ModuleJob.run (node:internal/modules/esm/module_job:194:25)\"}}\n```\n\n`httpLogs`, `logger` and `browserLogs` allow overwriting the standard `Log`\nclass in order to use ECS logging.\n\n```js\nimport { LogEcs, httpLogs } from 'debug-level'\n\nconst logHandler = httpLogs('my-pkg:http', { Log: LogEcs })\n\n// use then e.g. in express app\napp.use(logHandler)\n```\n\n```js\nimport { LogEcs, logger } from 'debug-level'\n\nconst log = logger('my-pkg:topic', { Log: LogEcs })\n\nlog.error(new Error('baam'))\n```\n\n### ECS-Serializers\n\nTo serialize top-level object keys you may use standard or custom functions. For\nLogEcs a serializer for key `err` (error), `req` (http-request) and `res`\n(http-response) is provided in node.\n\nThe signature is a bit different to [Log-serializers](#serializers) due to the\nJSON nature of ecs logging.\n\nWe recommend to adhere to [ECS field reference](https://www.elastic.co/guide/en/ecs/current/ecs-field-reference.html).\n\n```js\n/**\n * custom serialize function for key `my`\n * @see https://www.elastic.co/guide/en/ecs/current/ecs-custom-fields-in-ecs.html#_capitalization\n * @param {object} val\n * @param {object} ecsFields\n */\nconst myEcsSerializer = function (val, ecsFields) {\n  if (typeof val !== 'object' || !val) return\n  const { foo } = val\n  ecsFields.My = foo // using capitalized custom field\n}\n\nconst log = new LogEcs('foobar', { serializers: { my: myEcsSerializer }})\n\nconst my = { foo: 'bar', sense: 42 }\nlog.info({ my })\n//\u003e {\"log\":{\"level\":\"INFO\",\"logger\":\"foobar\",\"diff_ms\":0},\"@timestamp\":\"2025-02-09T08:09:02.719Z\",⏎\n//   \"process\":{\"pid\":33921},\"host\":{\"hostname\":\"einstein\"},\"My\":\"bar\"}\n```\n\n\n## License\n\n[MIT](./LICENSE)\n\n## Benchmarks\n\n[benchmarks][benchmarks]\n\n## References\n\n- [debug][]\n- [bunyan][]\n\n[bunyan]: https://www.npmjs.com/package/bunyan\n[debug]: https://www.npmjs.com/package/debug\n\n[debug-level-dev.png]: https://raw.githubusercontent.com/commenthol/debug-level/master/docs/images/debug-level-dev.png\n[debug-level-dev-json.png]: https://raw.githubusercontent.com/commenthol/debug-level/master/docs/images/debug-level-dev-json.png\n[debug-level-prod.png]: https://raw.githubusercontent.com/commenthol/debug-level/master/docs/images/debug-level-prod.png\n[benchmarks]: https://github.com/commenthol/debug-level/blob/master/docs/benchmarks.md\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcommenthol%2Fdebug-level","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcommenthol%2Fdebug-level","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcommenthol%2Fdebug-level/lists"}