{"id":20364080,"url":"https://github.com/ekino/node-logger","last_synced_at":"2025-04-12T04:33:33.154Z","repository":{"id":21510435,"uuid":"93131192","full_name":"ekino/node-logger","owner":"ekino","description":"A Lightweight logger that combines debug namespacing capabilities with winston levels and multioutput","archived":false,"fork":false,"pushed_at":"2023-10-04T05:58:19.000Z","size":3214,"stargazers_count":18,"open_issues_count":6,"forks_count":6,"subscribers_count":10,"default_branch":"master","last_synced_at":"2024-10-30T05:27:28.675Z","etag":null,"topics":["lightweight","logger","namespaces"],"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/ekino.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-06-02T05:44:54.000Z","updated_at":"2023-02-15T15:05:56.000Z","dependencies_parsed_at":"2024-06-19T11:25:40.795Z","dependency_job_id":"a4e66492-1f8c-4f53-9b0a-6c1c2f491bfe","html_url":"https://github.com/ekino/node-logger","commit_stats":{"total_commits":49,"total_committers":10,"mean_commits":4.9,"dds":0.7959183673469388,"last_synced_commit":"962984800b12912447da49d8d7917872775827fe"},"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ekino%2Fnode-logger","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ekino%2Fnode-logger/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ekino%2Fnode-logger/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ekino%2Fnode-logger/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ekino","download_url":"https://codeload.github.com/ekino/node-logger/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248517447,"owners_count":21117455,"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":["lightweight","logger","namespaces"],"created_at":"2024-11-15T00:09:41.674Z","updated_at":"2025-04-12T04:33:33.121Z","avatar_url":"https://github.com/ekino.png","language":"JavaScript","readme":"# @ekino/logger\n\n[![NPM version][npm-image]][npm-url]\n[![Travis CI][travis-image]][travis-url]\n[![Coverage Status][coverage-image]][coverage-url]\n[![styled with prettier][prettier-image]][prettier-url]\n\nA Lightweight logger that combines debug namespacing capabilities with winston levels and multioutput\n\n-   [Installation](#installation)\n-   [Usage](#usage)\n    -   [Using context ID](#using-context-id)\n    -   [Using namespaces](#using-namespaces)\n        -   [Using Logging Namespaces](#using-logging-namespaces)\n    -   [Outputs](#outputs)\n        -   [JSON](#json)\n        -   [Pretty](#pretty)\n        -   [Output function](#output-function)\n        -   [JSON Stringify utility](#json-stringify-utility)\n    -   [Log data](#log-data)\n        -   [Adding global metadata](#adding-global-metadata)\n-   [TypeScript](#typescript)\n\n## Installation\n\nUsing npm:\n\n```sh\nnpm install @ekino/logger\n```\n\nOr yarn:\n\n```sh\nyarn add @ekino/logger\n```\n\n## Usage\n\nBy default, the logger output warn and error levels for all namespaces.\nYou can set LOG_LEVEL environment to override the default behavior.\nBy default, it writes logs to stdout in JSON format\n\nThe logger api allows you to set log level for all namespaces. For advanced usage, you define it even per namespace.\n\nA log instance is bounded to a namespace. To use it, instantiate a logger with a namespace and call a log function.\n\nThis logger define 5 log levels: error, warn, info, debug, trace.\nWhen you set a level, all levels above it are enabled too.\nLog level can be set by calling `setLevel` function.\n\nFor example, enabling `info` will enable `info`, `warn` and `error` but not `debug` or `trace`.\nThe \"special\" log level `none` means no log and can only be used to set a namespace level.\n\n```js\n{ trace: 0, debug: 1, info: 2, warn: 3, error: 4 }\n```\n\nThe basic log function signature is:\n\n```js\nmy_log.the_level(message, data) // With data an object holding informations usefull for debug purpose\n```\n\nExample\n\n```js\nconst { setNamespaces, setLevel, createLogger } = require('@ekino/logger')\n\nsetNamespaces('root:*')\nsetLevel('debug')\n\nconst logger = createLogger('root:testing')\nlogger.debug('sample message', {\n    foo: 'bar',\n})\n```\n\noutput:\n\n![Example](docs/images/example_usage1.gif)\n\n### Using context ID\n\nOne of the main complexity working with node is ability to follow all logs attached to one call or one function.\nThis is not mandatory, but based on our experience, we recommend as a best practice to add a unique identifier that will be passed all along functions calls.\nWhen you log something, you can provide this id as a first parameter and logger will log it. If not provided, it's auto generated.\n\nThe signature of the function with contextId is:\n\n```js\nmy_log.the_level(contextId, message, data)\n```\n\nExample app.js\n\n```javascript\nconst { setNamespaces, setLevel, createLogger } = require('@ekino/logger')\n\nsetNamespaces('root:*')\nsetLevel('debug')\n\nconst logger = createLogger('root:testing')\nlogger.debug('ctxId', 'log with predefined context ID', {\n    foo: 'bar',\n})\n```\n\noutput:\n\n![Example](docs/images/example_usage2.gif)\n\n### Using namespaces\n\nLogger relies on namespaces. When you want to log something, you should define a namespace that is bound to it.\nWhen you debug, this gives you the flexibility to enable only the namespaces you need to output.\nAs a good practice, we recommend setting a namespace by folder / file.\nFor example for a file in modules/login/dao you could define 'modules:login:dao'.\nWarning, \"=\" can't be part of the namespace as it's a reserved symbol.\n\nYou can also define a level per namespace. If no level is defined, the default global level is used.\nTo disable logs of a namespace, you can specify a level `none`\nA namespace ':\\*' means eveything after ':' will be enabled. Namespaces are parsed as regexp.\n\nTo define namespace level, you should suffix namespace with \"=the_level\"\nFor example let's say you need to enable all info logs but for debug purpose you need to lower the level\nof the namespace database to `debug`. You could then use:\n\n```js\nconst { setLevel, setNamespaces } = require('@ekino/logger')\n\nsetLevel('info')\nsetNamespaces('*,database*=debug,database:redis*=none')\n```\n\n#### Using Logging Namespaces\n\n```js\nconst { setNamespaces, setLevel, createLogger } = require('@ekino/logger')\n\nsetNamespaces('namespace:*, namespace:mute=none')\nsetLevel('debug')\n\nconst loggerA = createLogger('namespace:subNamespace')\nconst loggerB = createLogger('namespace:mute')\n\nloggerA.debug('Will be logged')\nloggerB.info('Will not be logged')\n```\n\n```js\nconst { setNamespaces, setLevel, createLogger } = require('@ekino/logger')\n\nsetNamespaces('*, wrongNamespace=none')\nsetLevel('debug')\n\nconst loggerA = createLogger('namespace:subNamespace')\nconst loggerB = createLogger('wrongNamespace')\n\nloggerA.debug('Will be logged')\nloggerB.info('Will not be logged')\n```\n\n### Outputs\n\nLogger allow you to provide your own output adapter to customize how and where to write logs.\nIt's bundle by default with `pretty` adapter and `json` that both write to stdout.\nBy default, json adapter is enabled.\nYou can use multiple adapters at the same time\n\n#### JSON\n\n```js\nconst { setNamespaces, setLevel, setOutput, outputs, createLogger } = require('@ekino/logger')\n\nsetNamespaces('namespace:*')\nsetLevel('debug')\nsetOutput(outputs.json)\n\nconst logger = createLogger('namespace:subNamespace')\nlogger.debug('ctxId', 'Will be logged', {\n    someData: 'someValue',\n    someData2: 'someValue',\n})\n```\n\noutput:\n\n![Example](docs/images/example_usage3.gif)\n\n#### Pretty\n\nPretty will output a yaml like content.\n\n```js\nconst { setNamespaces, setLevel, setOutput, outputs, createLogger } = require('@ekino/logger')\n\nsetNamespaces('namespace:*')\nsetLevel('debug')\nsetOutput(outputs.pretty)\n\nconst logger = createLogger('namespace:subNamespace')\nlogger.debug('ctxId', 'Will be logged', {\n    someData: 'someValue',\n    someData2: 'someValue',\n})\n```\n\noutput:\n\n![Example](docs/images/example_pretty.gif)\n\n#### Output function\n\nAn output, is a function that will receive log data and should transform and store it\n\nLog data follow the format:\n\n```\n{\n    time: Date,\n    level: string,\n    namespace: string,\n    contextId: string,\n    meta: { any data defined in global context },\n    message: string,\n    data: object\n}\n```\n\n```js\nconst { setNamespaces, setLevel, setOutput, outputs, outputUtils, createLogger } = require('@ekino/logger')\n\nsetNamespaces('namespace:*')\nsetLevel('debug')\n\nconst consoleAdapter = (log) =\u003e {\n    console.log(outputUtils.stringify(log))\n}\n\n// This will output in stdout with the pretty output\n// and in the same will log through native console.log() function (usually to stdout too)\nsetOutput([outputs.pretty, consoleAdapter])\n\nconst logger = createLogger('namespace:subNamespace')\nlogger.debug('ctxId', 'Will be logged', {\n    someData: 'someValue',\n    someData2: 'someValue',\n})\n```\n\n#### JSON Stringify utility\n\nTo ease the creation of an output adapter, we provide a utility to stringify a json object that support circular reference\nand add stack to output for errors.\n\n```js\nconst { outputUtils } = require('@ekino/logger')\n\nconst consoleAdapter = (log) =\u003e {\n    console.log(outputUtils.stringify(log))\n}\n```\n\n### Log data\n\nMost of the time, a log message is not enough to guess context.\nYou can append arbitrary data to your logs.\nIf you're using some kind of log collector, you'll then be able to extract those values and inject them in elasticsearch for example.\n\n```js\nconst { setOutput, setNamespaces, setLevel, createLogger } = require('@ekino/logger')\n\nsetOutput('pretty')\nsetNamespaces('namespace:*')\nsetLevel('info')\n\nconst logger = createLogger('namespace:subNamespace')\nlogger.warn('message', { someData: 'someValue' })\n```\n\noutput:\n\n![Example](docs/images/example_data.gif)\n\n### Force Log\n\nYou can force to write the log even the logLevel isn't enabled.\n\n```js\nconst { setOutput, setNamespaces, setLevel, createLogger } = require('@ekino/logger')\n\nsetOutput('pretty')\nsetNamespaces('namespace:*')\nsetLevel('info')\n\nconst log = logger.createLogger('namespace', true)\nconst num = 1\nlog.debug('Will be logged', { someData: 'someValue' }, num \u003e 0)\n```\n\n#### Adding global metadata\n\nSometimes, you need to identify to which version or which application the logs refers to.\nTo do so, we provide a function to set informations that will be added to the each log at a top level key.\n\n```js\nconst { setOutput, setNamespaces, setLevel, setGlobalContext, createLogger } = require('@ekino/logger')\n\nsetOutput('pretty')\nsetNamespaces('*')\nsetLevel('info')\nsetGlobalContext({ version: '2.0.0', env: 'dev' })\n\nconst logger = createLogger('namespace')\nlogger.warn('message', { someData: 'someValue' })\n```\n\noutput:\n\n![Example](docs/images/example_context.gif)\n\n## TypeScript\n\nThis package provides its own definition, so it can be easily used with TypeScript.\n\n[npm-image]: https://img.shields.io/npm/v/@ekino/logger.svg?style=flat-square\n[npm-url]: https://www.npmjs.com/package/@ekino/logger\n[travis-image]: https://img.shields.io/travis/ekino/node-logger.svg?style=flat-square\n[travis-url]: https://travis-ci.org/ekino/node-logger\n[prettier-image]: https://img.shields.io/badge/styled_with-prettier-ff69b4.svg?style=flat-square\n[prettier-url]: https://github.com/prettier/prettier\n[coverage-image]: https://img.shields.io/coveralls/ekino/node-logger/master.svg?style=flat-square\n[coverage-url]: https://coveralls.io/github/ekino/node-logger?branch=master\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fekino%2Fnode-logger","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fekino%2Fnode-logger","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fekino%2Fnode-logger/lists"}