{"id":14984981,"url":"https://github.com/psychollama/holz","last_synced_at":"2025-04-10T23:15:53.925Z","repository":{"id":69447732,"uuid":"603537138","full_name":"PsychoLlama/holz","owner":"PsychoLlama","description":"A composable structured logging framework.","archived":false,"fork":false,"pushed_at":"2025-04-10T13:46:59.000Z","size":6011,"stargazers_count":5,"open_issues_count":2,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-10T23:15:44.275Z","etag":null,"topics":["browser","json","logger","nodejs","structured-logging"],"latest_commit_sha":null,"homepage":"","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/PsychoLlama.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":"2023-02-18T20:12:05.000Z","updated_at":"2025-04-10T13:45:28.000Z","dependencies_parsed_at":"2023-12-30T02:54:31.759Z","dependency_job_id":"8d5eb76f-7ac6-4f2f-b9df-a418b55ade92","html_url":"https://github.com/PsychoLlama/holz","commit_stats":{"total_commits":419,"total_committers":3,"mean_commits":"139.66666666666666","dds":0.2482100238663485,"last_synced_commit":"2ef3ace74620e76e51e6475710b27faa21af1b1f"},"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PsychoLlama%2Fholz","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PsychoLlama%2Fholz/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PsychoLlama%2Fholz/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PsychoLlama%2Fholz/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/PsychoLlama","download_url":"https://codeload.github.com/PsychoLlama/holz/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248312132,"owners_count":21082638,"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":["browser","json","logger","nodejs","structured-logging"],"created_at":"2024-09-24T14:10:01.738Z","updated_at":"2025-04-10T23:15:53.913Z","avatar_url":"https://github.com/PsychoLlama.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n  \u003ch1\u003eHolz\u003c/h1\u003e\n  \u003cp\u003eA structured, composable logging framework.\u003c/p\u003e\n\u003c/div\u003e\n\n## Purpose\n\nMost logging frameworks are destructive. The act of converting logs to strings partially destroys the data it contains. Instead, Holz encourages pipelines of structured data:\n\n```typescript\nlogger.info('Sending new user email', { userId: user.id });\n```\n\n```typescript\n{\n  message: 'Sending new user email',\n  level: level.info,\n  origin: ['UserService'],\n  context: { userId: '465ebaec-2b53-4b81-95e9-9f35771c0af2' },\n}\n```\n\nEach log is sent through a chain of plugins that choose how to filter, transform, serialize, or upload them.\n\n## Usage\n\nHolz is built on a chain of plugins, but if you want something that Just Works, use the preconfigured bundle:\n\n```typescript\nimport logger from '@holz/logger';\n\nlogger.info('Hello, world!');\n```\n\nThat's it! You can use Holz in Node or in the browser.\n\nBy default, logs are hidden. To enable them, set the `DEBUG` environment variable to the namespace(s) you want to see logs for:\n\n```bash\nDEBUG='your-app*' node script.js\n```\n\nAlternatively, you can enable logs by setting the `localStorage.debug` property:\n\n```typescript\nlocalStorage.debug = 'your-app*';\n```\n\nFor more details, check [the documentation](https://github.com/PsychoLlama/holz/tree/main/packages/holz-logger).\n\n## Rules\n\nTo keep logs consistent and useful, the API is designed to follow these two rules:\n\n1. **Don't Interpolate:** Never interpolate data into your log messages. Instead, pass variables as structured data. This makes it easier to search, analyze, and visualize your logs.\n2. **Keep Context Shallow:** While the `log.context` property provides additional context for your log messages, we don't allow nested objects in it. This is to prevent the accidental inclusion of unsuitable log context, like sensitive user data or redux state.\n\nBy following these rules, we make sure our logs are well-organized and useful, without compromising on the privacy and security of our users.\n\n## Customizing the Logger\n\nAlmost everything in Holz is a plugin. Plugins are functions that take a log and do something with it:\n\n```typescript\nimport { createLogger } from '@holz/core';\n\nconst plugin = (log: Log) =\u003e {\n  // Print it, save it to a file, pass it to another plugin...\n  // This is up to you.\n};\n\nconst logger = createLogger(plugin);\n```\n\nHolz has a number of plugins already available. See each package for documentation:\n\n| Plugin                                                                                                             | Description                                      |\n| ------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------ |\n| [`@holz/core`](https://github.com/PsychoLlama/holz/tree/main/packages/holz-core)                                   | Core framework. Includes tools and types.        |\n| [`@holz/ansi-terminal-backend`](https://github.com/PsychoLlama/holz/tree/main/packages/holz-ansi-terminal-backend) | Pretty-print logs to the terminal.               |\n| [`@holz/console-backend`](https://github.com/PsychoLlama/holz/tree/main/packages/holz-console-backend)             | Pretty-print logs to the browser console.        |\n| [`@holz/json-backend`](https://github.com/PsychoLlama/holz/tree/main/packages/holz-json-backend)                   | Write logs as NDJSON to a writable stream.       |\n| [`@holz/stream-backend`](https://github.com/PsychoLlama/holz/tree/main/packages/holz-stream-backend)               | Send plaintext logs to a writable stream.        |\n| [`@holz/pattern-filter`](https://github.com/PsychoLlama/holz/tree/main/packages/holz-pattern-filter)               | Filter logs against a pattern.                   |\n| [`@holz/env-filter`](https://github.com/PsychoLlama/holz/tree/main/packages/holz-env-filter)                       | Pull filters from `env.DEBUG` or `localStorage`. |\n\n## Recipes\n\n### Multiple Logging Destinations\n\nHolz supports forking to different log destinations by using the `combine(...)` operator:\n\n```typescript\nimport { createLogger, combine } from '@holz/core';\n\nconst logger = createLogger(\n  combine([\n    createConsoleBackend(),\n    createFileBackend('./my-app.log'),\n    createUploadBackend({ apiKey: config.apiKey }),\n  ]),\n);\n```\n\n### Filtering Debug Logs\n\n```typescript\nimport { createLogger, filter, level } from '@holz/core';\n\nconst logger = createLogger(\n  filter(\n    (log) =\u003e log.level \u003e= level.info,\n    createStreamBackend({ stream: process.stderr }),\n  ),\n);\n```\n\n### Filtering Logs Before Uploading\n\n```typescript\nimport { createLogger, combine, filter } from '@holz/core';\n\nconst logger = createLogger(\n  combine([\n    createStreamBackend({ stream: process.stderr }),\n    filter(\n      (log) =\u003e log.origin[0] === 'my-app',\n      createUploadBackend({ key: config.uploadKey }),\n    ),\n  ]),\n);\n```\n\n## Related Projects\n\nHolz is inspired by other loggers:\n\n- [pino](https://getpino.io/)\n- [debug](https://github.com/debug-js/debug)\n- [winston](https://github.com/winstonjs/winston)\n\n## Name\n\nIt's a play on the word \"logger\":\n\n\u003e Holz (German, noun): a piece of wood, usually small.\n\nThere is another library named [`holz`](https://www.npmjs.com/package/holz) (without the org scope). It is not related.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpsychollama%2Fholz","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpsychollama%2Fholz","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpsychollama%2Fholz/lists"}