{"id":20499668,"url":"https://github.com/apla/logsome","last_synced_at":"2026-01-02T02:02:04.273Z","repository":{"id":66835375,"uuid":"305196390","full_name":"apla/logsome","owner":"apla","description":null,"archived":false,"fork":false,"pushed_at":"2024-07-18T06:24:12.000Z","size":108,"stargazers_count":0,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-01-21T14:02:13.088Z","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":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/apla.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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":"2020-10-18T21:05:44.000Z","updated_at":"2024-07-18T06:24:15.000Z","dependencies_parsed_at":"2023-02-21T13:45:26.760Z","dependency_job_id":null,"html_url":"https://github.com/apla/logsome","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apla%2Flogsome","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apla%2Flogsome/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apla%2Flogsome/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apla%2Flogsome/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/apla","download_url":"https://codeload.github.com/apla/logsome/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243647682,"owners_count":20324744,"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-15T18:18:02.764Z","updated_at":"2026-01-02T02:02:04.166Z","avatar_url":"https://github.com/apla.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# LOGSOME\n\nApp objects consumable by loggers and reporters\n\n## TL;DR\n\nCode:\n\n```javascript\nconst array = [1,2,3];\nconst str   = \"aaa\";\nconst obj   = {a: 1, b: 2, c: 3};\nconsole.log (...report`array ${{array}}, string ${{str}}, number ${42}, object ${{obj}}`);\n```\n\nNode.js console:\n\n![](https://github.com/apla/logsome/blob/docs/logsome-console.jpg?raw=true)\n\nBrowser console:\n\n![](https://github.com/apla/logsome/blob/docs/logsome-safari.jpg?raw=true)\n\nLoggly:\n\n![](https://github.com/apla/logsome/blob/docs/logsome-loggly.jpg?raw=true)\n\n## Install\n\nimport for browser:\n\n```javascript\nimport {format,  endpoint} from \"https://cdn.jsdelivr.net/npm/logsome@latest/logsome.js\";\n```\n\ninstall for node:\n\n```sh\nnpm i -D logsome\n```\n\nthen use esm\n\n```javascript\nimport {format, endpoint} from 'logsome';\n```\n\nor cjs\n\n```javascript\nconst {format, endpoint} = require('logsome');\n```\n\n## Why?\n\n 1. Human readable logs with attached machine readable objects\n 4. Can be used for plain text console logs and remote server json logs\n 3. Caller information not screwed up\n\nWorks in the [browser (Chrome 62+, Safari 11+, Firefox 53+) and in the Node.js (8.10+)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#browser_compatibility)\n\n\n## Usage\n\n```javascript\n// log formatting\nimport {format} from 'logsome';\n\n// `obj` class name and `just launched` suffix will be in console,\n// followed by inspectable `obj` object\nconsole.log (...format`${obj} just launched`);\n\n// TODO: not yet implemented\n// mute unneeded logs in console\n// verbose setting once per app, also supports env vars\n// logsome.mute ('Loader');\n// logsome.only ('Loader');\n\nimport {endpoint} from 'logsome';\n\n// configure API endpoint once\nconst sender = endpoint('https://site.com/api/v1/log', {name: 'remote'});\n\n// use everywhere\nconst sendR1 = endpoint('remote');\n\n// `obj` class name and `just launched` suffix will be in console,\n// followed by inspectable `obj` object\nconsole.log (...sendR1`${obj} just launched`);\n\n// `obj` class name and `just launched` suffix will be in console,\n// followed by inspectable `obj` object. `obj` will be placed\n// into `obj` key of reported data\nconsole.log (...sendR1`${{obj}} just launched`);\n\n// `obj` class name and `just launched` suffix will be in console,\n// followed by inspectable `obj` object. `_` is ignored by format,\n// but merged into reported data\nconsole.log (...sendR1`${{obj}} just launched${_: {loglevel: 'log'}}`);\n\n\n// void endpoint to temporarily disable remote endpoint\nendpoint(`void:`, {name: 'base'});\nconst sendR2 = endpoint('base');\n\n// loggly endpoint for demonstation purposes\nendpoint(`loggly:${logglyToken}`, {name: 'loggly'});\nconst sendR3 = endpoint('loggly');\n\n// Customization for external classes can be specified\n// within `classFormats` export. `Error` and `Element` customizations available\n// by calling `classFormats.installPredefined()`. Please note performance degradation.\nimport {classFormats} from 'logsome';\nclassFormats.installPredefined();\n\n```\n\n## API\n\n### format\\`template\\`\n\nFormat and returns array, consumable by `console.log`\n\n### endpoint(url, [options]) =\u003e report\n### endpoint(urlOrName) =\u003e report\n\nCreates or gets reporting object for endpoint. Custom url protocols can be used\nto simplify setup. Take a look at `locators/loggly.js`.\n`void:` protocol can be used to skip data submission.\n\n```javascript\nlet debugEndpoint = 'void:';\nif (process.env.DEBUG) {\n    debugEndpoint = 'local:';\n}\n\nconst debugSender = endpoint(debugEndpoint);\n\nconsole.log(...debugSender`debug`);\n```\n\n### report\\`template\\`\n\nFormat message for log and send it to the endpoint.\n\nIf `report` function imported, then it only can send data through default endpoint.\nDefault endpoint have `.name` = '' or if there is no other enpoints configured.\nThrows error with `.code` = `NO_DEFAULT_ENDPOINT` if no default endpoint configured.\n`void:` endpoint not counting as configured endpoint.\n\nIf `report` received as a result of `endpoint` call, it is bound to that endpoint.\n\nReturned array contains `.sending` thenable property. Usually it is not needed for long running scripts.\n\n### styles\n\nStyle description for displaying different objects\n\n### locators\n\nLocator is a function to create report sender configuration from url. \nExample in `locators/loggly.js`\n\n```javascript\n\nimport {locators} from 'logsome';\n\nlocators['local'] = local3KLocator;\n\nconst sender = logsome.endpoint('local:');\n\nconsole.log(...sender`hello`);\n\nfunction local3KLocator(url) {\n\n    return {\n        url: `http://localhost:3000/api/v1/logs`,\n        data: {\n            // TODO: add IP and more meta\n            // hostname: typeof process !== 'undefined' ? require('os').hostname() : undefined,\n            pid: typeof process !== 'undefined' ? process.pid : undefined,\n            \n        },\n        options: {\n            styles: 'server',\n            headers: {\n                contentType: 'application/json'\n            },\n            method: 'POST'\n        }\n    }\n}\n\n\n\n```\n\n### custom presentation, embedded within class\n\nWhen object have `Symbol.for('logsome')` method or getter, returned custom in the `title` and `style`\nkeys will be displayed instead of standard ones. Function at `facade` key\nwill be called and result is used instead of object. No one can tell what should be reported.\nList safe fields and avoid any sensitive data leak. Skip extra fields to reduce bandwith.\n\nModern browsers and Node.js supports `Symbol.toStringTag`, but it is almost unusable\ndue differences between node and browsers. First of all, browsers won't display\n`Symbol.toStringTag` when inspecting objects in console. It is displayed only\nwhen object stringified. Node.js displays `Symbol.toStringTag` in square brackets\nafter class name.\n\n### custom class instances presentation, external\n\nWhen you want to present some external classes, import `classFormats` from logsome.\n\n```javascript\nimport {classFormats} from 'logsome';\n\nclassFormats.set(/Error$/, {\n    classRef: Error, // just to ensure class match by class constructor, not name\n\tstyle: {browser: 'background-color: #f63;', node: '\\x1b[31m'}\n});\n\n// or install predefined formats for Error, Element (Element is available only in the browser)\n\nclassFormats.installPredefined();\n```\n\n## Notes\n\n### Browser: Rollup \u0026 Buble integration\n\nSeems like `buble` and `@rollup/plugin-buble` cannot parse string like `return import(…`.\n\nRequires adding replacement plugin with configuration like this:\n\n```javascript\nreplace({\n    preventAssignment: true,\n    delimiters: ['\\\\b', '\\\\b(?=\\\\s*\\\\()'],\n    values: {\n        import: '_import'\n    }\n}),\n```\n\n## TODO\n\n### Comparison\n\nhttps://geshan.com.np/blog/2021/01/nodejs-logging-library/\nhttps://github.com/pinojs/pino/blob/master/docs/benchmarks.md\n\n### Web UI\n\nhttps://github.com/guigrpa/storyboard\n\n### Optimization\n\n * Sender should be rewritten; easiest ways to do is open\n file/https/other stream and send data. Flush stream after every record,\n close stream on reasonable timeout, use pool of connections.\n\n * use acorn to find out log levels (info, debug, …)\n\n * find out why profiler reports SearchString all the time\n```\n    439   47.7%   50.1%  t unsigned long node::stringsearch::SearchString\u003cunsigned short\u003e(node::stringsearch::Vector\u003cunsigned short const\u003e, node::stringsearch::Vector\u003cunsigned short const\u003e, unsigned long)\n    321   34.9%   36.6%  T __kernelrpc_thread_policy_set\n```\n\n## Articles\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fapla%2Flogsome","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fapla%2Flogsome","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fapla%2Flogsome/lists"}