{"id":19408469,"url":"https://github.com/4lessandrodev/ts-logs","last_synced_at":"2025-04-24T09:31:54.203Z","repository":{"id":65552704,"uuid":"594255824","full_name":"4lessandrodev/ts-logs","owner":"4lessandrodev","description":"Understand what happens in your application. Manage your logs and audit the steps of each request.","archived":false,"fork":false,"pushed_at":"2025-04-01T05:26:09.000Z","size":3138,"stargazers_count":4,"open_issues_count":6,"forks_count":3,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-03T03:11:09.635Z","etag":null,"topics":["log","log-analytics","log-files","logfile","logger","logging","logs"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/ts-logs","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/4lessandrodev.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-01-28T01:04:28.000Z","updated_at":"2025-03-03T22:50:16.000Z","dependencies_parsed_at":"2024-01-02T02:48:01.747Z","dependency_job_id":"b0c71ebe-3739-451d-90aa-796dc406e0cd","html_url":"https://github.com/4lessandrodev/ts-logs","commit_stats":{"total_commits":116,"total_committers":3,"mean_commits":"38.666666666666664","dds":"0.26724137931034486","last_synced_commit":"0d4b274ac365bdf13893f9d6ec5d1ac0de972d0c"},"previous_names":[],"tags_count":26,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/4lessandrodev%2Fts-logs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/4lessandrodev%2Fts-logs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/4lessandrodev%2Fts-logs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/4lessandrodev%2Fts-logs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/4lessandrodev","download_url":"https://codeload.github.com/4lessandrodev/ts-logs/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250600717,"owners_count":21457017,"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":["log","log-analytics","log-files","logfile","logger","logging","logs"],"created_at":"2024-11-10T12:06:17.926Z","updated_at":"2025-04-24T09:31:53.622Z","avatar_url":"https://github.com/4lessandrodev.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ts-logs\nUnderstand what happens in your application. Manage your logs and audit the steps of each request.\n\n\u003ca href=\"https://www.npmjs.com/package/ts-logs\" rel=\"nofollow\" class=\"keychainify-checked\"\u003e\n \u003cimg src=\"https://badgen.net/github/checks/4lessandrodev/ts-logs/main\" \n alt=\"checks\" \n style=\"max-width: 100%;\"\u003e\n\u003c/a\u003e\n\u003ca href=\"https://www.npmjs.com/package/ts-logs\" rel=\"nofollow\" class=\"keychainify-checked\"\u003e\n \u003cimg src=\"https://badgen.net/github/stars/4lessandrodev/ts-logs\" \n alt=\"stars\" \n style=\"max-width: 100%;\"\u003e\n\u003c/a\u003e\n\u003ca href=\"https://www.npmjs.com/package/ts-logs\" rel=\"nofollow\" class=\"keychainify-checked\"\u003e\n \u003cimg src=\"https://badgen.net/github/commits/4lessandrodev/ts-logs/main\" \n alt=\"commits\" \n style=\"max-width: 100%;\"\u003e\n\u003c/a\u003e\n\u003ca href=\"https://www.npmjs.com/package/ts-logs\" rel=\"nofollow\" class=\"keychainify-checked\"\u003e\n \u003cimg src=\"https://badgen.net/github/last-commit/4lessandrodev/ts-logs/main\" \n alt=\"last commit\" \n style=\"max-width: 100%;\"\u003e\n\u003c/a\u003e\n\u003ca href=\"https://www.npmjs.com/package/ts-logs\" rel=\"nofollow\" class=\"keychainify-checked\"\u003e\n \u003cimg src=\"https://badgen.net/github/license/4lessandrodev/ts-logs\" \n alt=\"license\" \n style=\"max-width: 100%;\"\u003e\n\u003c/a\u003e\n\u003ca href=\"https://www.npmjs.com/package/ts-logs\" rel=\"nofollow\" class=\"keychainify-checked\"\u003e\n \u003cimg src=\"https://badgen.net/github/dependabot/4lessandrodev/ts-logs\" \n alt=\"dependabot\" \n style=\"max-width: 100%;\"\u003e\n\u003c/a\u003e\n\u003ca href=\"https://www.npmjs.com/package/ts-logs\" rel=\"nofollow\" class=\"keychainify-checked\"\u003e\n \u003cimg src=\"https://badgen.net/github/tag/4lessandrodev/ts-logs\" \n alt=\"tags\" \n style=\"max-width: 100%;\"\u003e\n\u003c/a\u003e\n\u003ca href=\"https://www.npmjs.com/package/ts-logs\" rel=\"nofollow\" class=\"keychainify-checked\"\u003e\n \u003cimg src=\"https://badgen.net/github/closed-issues/4lessandrodev/ts-logs\" \n alt=\"issues\" \n style=\"max-width: 100%;\"\u003e\n\u003c/a\u003e\n\u003ca href=\"https://github.com/4lessandrodev/ts-logs?branch=main\" rel=\"nofollow\" class=\"keychainify-checked\"\u003e\n \u003cimg src=\"https://img.shields.io/codecov/c/github/dwyl/hapi-auth-jwt2.svg?maxAge=2592000\" \n alt=\"issues\" \n style=\"max-width: 100%;\"\u003e\n\u003c/a\u003e\n\n---\n\n## About the lib\n\nThis package provide a sdk to manage logs.\n\n---\n\n## Installation\n\ninstall using yarn or npm\n\n```sh\n\n$ npm install ts-logs\n\n# OR\n\n$ yarn add ts-logs\n\n```\n\n---\n## Documentation\n\nExample\n\n```ts\nimport { Log, Step } from 'ts-logs';\n\n// create a global log\nconst log = Log.init({ name: 'First Log', origin: 'https://global.com' });\n\n// create steps\nconst info = Step.info({ message: 'Fetching api...', name: 'Request Login', method: 'POST' });\nconst error = Step.error({ message: 'Timeout', name: 'Login', stack: 'Error stack' });\n\n// add steps to global log\nlog.addSteps([ info, error ]);\n\n// print or save logs\nlog.print();\nawait log.writeLocal();\nawait log.publish(config);\n\n```\n\n---\n\n### Use a Singleton Instance Globally\n\nYou can use a global log to publish once on finish all process\n\n```ts\n\nimport { GlobalLog, Config } from 'ts-logs';\n\nconst global = GlobalLog.singleton();\n\n// ...\n\nglobal.addStep(step);\n\n// ...\n\nawait global.publish(Config.Mongo({ url: 'mongodb://localhost:27017' }));\n\n// remember when using global log as singleton clear steps\nglobal.clear();\n\n```\n\n### Create step from catch block\n\nCreate a step instance from error. This method get many important information from axios error.\n\n```ts\n\nclass DoSomething {\n    async execute(data: Data): Promise\u003cvoid\u003e {\n        try {\n            \n            // try do something ...\n            await axios.post(url, data);\n\n        } catch(error) {\n\n            // create step instance from error\n            global.addStep(Step.catch(error));\n        }\n    }\n}\n\n```\n\n---\n\n### Log object\n\nExample generated log. The log is a json object with array of step object \n\n```json\n\n{\n  \"uid\": \"1c7e5aca-c9f4-4e33-a5e7-d8a9cfe94053\",\n  \"name\": \"Log Example\",\n  \"ip\": \"127.0.0.1\",\n  \"origin\": \"http://127.0.0.1:3000\",\n  \"createdAt\": \"2023-02-05T23:00:40.481Z\",\n  \"stateType\": \"stateful\",\n  \"steps\": [\n    {\n      \"name\": \"Find Item\",\n      \"category\": \"none\",\n      \"tags\": [\"item\", \"product\", \"card\"],\n      \"url\": \"https://my-app.com/products/1\",\n      \"stack\": \"none\",\n      \"data\": \"none\",\n      \"statusCode\": 200,\n      \"message\": \"Fetching api...\",\n      \"type\": \"info\",\n      \"method\": \"GET\",\n      \"createdAt\": \"2023-02-05T23:00:40.481Z\",\n      \"uid\": \"673e17fb-55aa-4ea9-8668-e34b94bfd22c\",\n      \"additionalInfo\": \"a complementary information\"\n    }\n  ]\n}\n\n```\n\n---\n\n### Use as middleware\n\nExpress middleware to capture app errors.\n\n```ts\n\nimport express from 'express';\nimport { stackLog } from 'ts-logs';\n\nconst app = express();\napp.use(express.json());\n\n// ...\napp.use(routes);\n\n// last middleware to handle errors using `stackLog` all errors will be intercepted.\napp.use(stackLog({ writeLocal: true })); // \u003c------ middleware\n\napp.liste(3000);\n\n```\n\n### Bind\n\nYou also may use bind middleware to apply a log instance to request\n\n```ts\n\nimport express from 'express';\nimport { bindLog, Config } from 'ts-logs';\n\nconst app = express();\napp.use(express.json());\n\n// on top of routes you can bind a log instance to request\napp.use(bindLog()); // \u003c------ middleware\n\napp.get(\"/log\", async (req: Request, res: Response) =\u003e {\n\n    // you can do anything with log instance from request.\n    req.log.addStep( /* any step */ );\n    req.log.print(); // show steps on terminal\n    await req.log.publish(Config.S3(/* ... */)) // publish to s3\n\n    res.status(200).json(req.log);\n});\n\n// ...\n\napp.use(routes);\n\n```\n\n---\n\n### Use as middleware step\n\nif you use many steps as middleware you can use global log\n\n```ts\n\nimport express from 'express';\nimport { bindLog, Config } from 'ts-logs';\n\nconst app = express();\napp.use(express.json());\n\n// on top of routes you can bind a log instance to request\napp.use(bindLog()); // \u003c------ middleware\n\napp.get(\"/process\", (req: Request, res: Response, next: NextFunction) =\u003e {\n\n    // you can do anything with log instance\n    req.log.addStep( /* info step */ ); // \u003c------ add step to global log state.\n\n    // call next step\n    next();\n}, (req: Request, res: Response, next: NextFunction) =\u003e {\n\n    // you can do anything with log instance\n    req.log.addStep( /* error step */ ); // \u003c------ add step to global log state.\n\n    // call next step\n    next();\n}, async (req: Request, res: Response, next: NextFunction) =\u003e {\n\n    // you can do anything with log instance\n    req.log.addStep( /* stack step */ ); // \u003c------ add step to global log state.\n\n    // publish log with steps to aws s3\n    await req.log.publish(Config.S3(/* ... */));\n\n    // send log to client\n    res.status(200).json(req.log);\n});\n\n// ...\n\napp.use(routes);\n\n```\n\n---\n\n### Publish log automatically\n\nyou can use in conjunction with binding middleware other middleware to automatically publish logs to your preferred provider.\n\n```ts\n\nimport express from 'express';\nimport { bindLog, autoPublishLog, Config } from 'ts-logs';\n\nconst app = express();\napp.use(express.json());\n\n// on top of routes you can bind a log instance to request\napp.use(bindLog()); // \u003c------ middleware\n\n// after `bindLog` add `autoPublishLog` to automatically publish logs\napp.use(autoPublishLog(Config.S3())); // \u003c------ middleware\n\napp.get(\"/log\", async (req: Request, res: Response) =\u003e {\n\n    // you can do anything with log instance from request.\n    req.log.addStep( /* any step */ ); // \u003c------ add step to publish\n\n    res.status(200).json(req.log);\n});\n\n// ...\n\napp.use(routes);\n\n```\n\n---\n\n### Secure logs\n\nIt is possible to remove any key from body (data) or encrypt some sensitive information\n\n#### Removing data\n\n```ts\n\nconst name = \"Step Test\";\nconst data = JSON.stringify({ password: \"123456\", name: \"Jane\" });\n\nconst step = Step.create({ name, data });\n\nconst updated = step.remove([\"password\"]);\n\nconsole.log(updated.data);\n\n\u003e \"{ \\\"name\\\": \\\"Jane\\\" }\"\n\n// or encrypt attribute\n\nstep.encrypt({ attributes: [\"password\"], secretKey: \"my-secret-key\" });\n\n```\n\n#### Hidden Value - Mask\nyou can mask any key value in step data. provide the key name you want or the path. example `user.password` for specific key in user object or `password` for any key called password\n\n```ts\n\nconst name = 'sample';\n\nconst data = { \n  info: 'secret-text', \n  user: { \n    name: 'Jane',\n    password: '12345'\n  }\n};\n\nconst step = Step.create({ name, data });\n\nconst updated = step.mask([ { key: 'password' } ]);\n\nconsole.log(updated);\n{\n  info: 'secret-text', \n  user: { \n    name: 'Jane',\n    password: '*****'\n  } \n}\n\n```\n\n\n#### Encrypt data\n\nEncryption is also available for `stackLog` and as cypher.\n\n\n```ts\n\napp.use(\n  stackLog({ \n    writeLocal: true, \n    encrypt: true, \n    encryptOption: { \n      level: \"cypher\",\n      secretKey: \"my-secret-key\"\n    } \n  })\n);\n\n```\n\n---\n\n### Flows\n\nFlows using middleware\n\nUsing `bindLog` combined with `autoPublishLog` middleware\n\n![flow](docs/flow-01.png)\n\nUsing `bindLog` combined with `stackLog` middleware\n\n![flow](docs/flow-02.png)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F4lessandrodev%2Fts-logs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2F4lessandrodev%2Fts-logs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F4lessandrodev%2Fts-logs/lists"}