{"id":21041718,"url":"https://github.com/quantumplation/capillary-logger","last_synced_at":"2025-09-05T08:31:59.755Z","repository":{"id":48026887,"uuid":"86485651","full_name":"Quantumplation/capillary-logger","owner":"Quantumplation","description":"A nodejs logging library with hierarchical context attached to each message.","archived":false,"fork":false,"pushed_at":"2021-08-10T21:19:41.000Z","size":118,"stargazers_count":8,"open_issues_count":5,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-12-26T23:49:21.425Z","etag":null,"topics":["javascript","logging"],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","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/Quantumplation.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-03-28T17:01:30.000Z","updated_at":"2018-12-30T18:06:17.000Z","dependencies_parsed_at":"2022-08-12T17:00:38.734Z","dependency_job_id":null,"html_url":"https://github.com/Quantumplation/capillary-logger","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Quantumplation%2Fcapillary-logger","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Quantumplation%2Fcapillary-logger/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Quantumplation%2Fcapillary-logger/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Quantumplation%2Fcapillary-logger/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Quantumplation","download_url":"https://codeload.github.com/Quantumplation/capillary-logger/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":232032048,"owners_count":18462966,"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":["javascript","logging"],"created_at":"2024-11-19T13:55:59.312Z","updated_at":"2024-12-31T21:43:17.535Z","avatar_url":"https://github.com/Quantumplation.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Capillary\n![Codeship Badge](https://codeship.com/projects/84ae51b0-fde4-0134-56ba-5274708b3ee2/status?branch=master)\n[![npm version](https://badge.fury.io/js/capillary-logger.svg)](https://badge.fury.io/js/capillary-logger)\n\nCapillary is a logging library with hierarchical context attached to each message.\n\n## Usage\n\nFirst import the logger for use\n```javascript\nvar capillary = require('capillary');\nimport { Logger } from 'capillary';\n```\n\nFrom there, you can instantiate and use a logger as one might expect.\nThe logger exposes helper methods for logging at various severity levels.\n\n```javascript\nlet logger = new Logger();\n\nlogger.info('Attempting to connect to database.');\nlogger.error('Failed to connect to database.');\n```\n\nYou can also log structured messages\n\n```javascript\nlogger.warn({ message: 'Unable to connect to rabbitmq', connectionString: '...', error: err }); \n```\n\nOften, however, there is information you'd like to include with every message,\nto provide context.  These are usually things like a request identifier, trace id, \netc.  It can become quite annoying to \n - thread this information throughout the code base purely for logging purposes\n - remember to include this information on each and every logger statement\n\n When instantiating the logger, Capillary lets you specify this context.\n\n```javascript\nlogger = new Logger({ requestId: '123...' });\nlogger.info('Processing request...');\n```\n\nYou can split off child loggers, which inherit their parents context:\n\n```javascript\nlet logger = new Logger({ requestId: '123...' });\nlet child = logger.split({ activity: 'Setup' });\n// The following message will additionally include the requestId and the activity\nchild.info({ message: 'Reading data from database', databaseId: '456...' }); \n```\n\nSometimes, especially in dependency injection scenarios, you don't have all the\ncontext you would like when you split off a child.  Instead, a method is called\nlater (such as an initialize, configure, or service method) which adds additional\ncontext you'd like to capture in log messages.  Splitting off a separate logger\nfor this is often inconvenient.\n\nTo solve this, we've seen people modifying the context, and to make the intention\nof this clearer, we've added a an `augment` method\n\n```javascript\nlet logger = new Logger({ requestId: '123...' });\n\n...\n\nlogger.augment({ currentStep: 'Phase1' });\nlogger.info({ message: 'Average computed successfully' });\n```\n\nWhen you augment the context, messages logged with any child loggers will include\nthe updated context\n\n```javascript\nlet logger = new Logger({ requestId: '123...' });\nlet averageCalculationLogger = logger.split({ activity: 'Average Calculation' });\n...\nlogger.augment({ currentStep: 'Phase1' });\n...\n// The following message will include currentStep: Phase1\nchild.info({ message: 'Average computed successfully' });\n...\nlogger.augment({ currentStep: 'Phase2' });\n...\n// The following message will include currentStep: Phase2\nchild.info({ message: 'Average computed successfully' });\n...\nlogger.augment({ currentStep: 'Phase3' });\n...\n// The following message will include currentStep: Phase3\nchild.error({ message: 'Failed to compute average', error: ... });\n```\n\n### Accepting Capillary Loggers\n\nIf you are writing another library, and want to allow (but not require) the use of\na capillary logger, you can check if the logger passed in is capillary compliant via\nthe the isCapillaryCompatible property on the logger, as so:\n\n```javascript\nif(parentLogger \u0026\u0026 parentLogger.isCapillaryCompatible) {\n  this._logger = parentLogger.split({ component: 'my-library' });\n} else {\n  this._logger = parentLogger;\n}\n```\n\n## Asynchronicity\n\nBecause some plugins may be communicating with outside services, you may want to\nrespond to failures to log specific messages.  For this, we provide a logAsync\nmethod which returns a promise.\n\n## Plugins\n\nCapillary supports a plugin architecture.  Each message will be passed into\neach plugin in the order in which they were activated. This can perform custom \ntransformations, filter based on custom logic, or log to custom sources. By\ndefault, the \"console\" plugin will be active, which logs each message as JSON\nto the console.\n\nAs soon as the first plugin is registered, however, the default console plugin\nwill be replaced by the registered plugin.\n\n```javascript\nclass FileWriterPlugin extends capillary.AsyncPlugin {\n  private filename: string;\n  constructor(filename: string) {\n    this.filename = filename;\n  }\n  process(message: any): Promise\u003cany\u003e {\n    return new Promise((resolve, reject) =\u003e {\n      const strMessage = JSON.stringify(message);\n      fs.appendFile(this.filename, strMessage, err =\u003e {\n        return err ? reject(err): resolve();\n      });\n    });\n  }\n}\n\nlogger.addPlugin(new FileWriterPlugin('logs.txt'));\n```\n\nPlugins come in two flavors: Sync and Async.  Capillary makes the guarantee that\nany Sync plugins are run synchronously when possible.  That is, if all of your \nplugins are synchronous, the entire thing will be executed synchronously.\n\n### ConsolePlugin\n\nWrites each log message out to console after passing it through JSON.stringify.\n\nAllows pretty printing, configurable through the following options:\n\n - prettyPrint\n   - (default: `false`)\n   - Enables or disables pretty printing altogether\n - seperator\n   - (default: `''`)\n   - Seperate each log message with some token\n - severityColors\n   - (default: `{ trace: 'grey', debug: 'green', info: 'white', warn: 'yellow', error: 'red', fatal: 'bgRed' }`)\n   - Specifies the colors to use for each severity level \n\n### MinimumSeverityPlugin\n\nFilters and discards any messages whose severity is below a pre-defined level.\n\n### TimestampPlugin\n\nAdds the current date and time to each message, using a configurable property name.\n\n### TypePrefixPlugin\n\nPrefixes all top level properties of a message with a prefix based on typeof that property.\nThis is for use with elastic search and microservices, which has trouble indexing fields\nof different types.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fquantumplation%2Fcapillary-logger","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fquantumplation%2Fcapillary-logger","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fquantumplation%2Fcapillary-logger/lists"}