{"_id":"2steps-jslogger","_rev":"3-377862b0dc71753b0f09aab26263ab2b","name":"2steps-jslogger","dist-tags":{"latest":"1.2.0"},"versions":{"1.0.3":{"name":"2steps-jslogger","version":"1.0.3","keywords":["logging","elasticsearch","ecs","elastic","logger"],"author":{"name":"Twosteps"},"license":"MIT","_id":"2steps-jslogger@1.0.3","maintainers":[{"name":"ahsan-maqbool","email":"muhammad.maqbool@twosteps.ai"}],"dist":{"shasum":"e2f6bb283c57ce17da4633dfd6d383b19f0a07ae","tarball":"https://registry.npmjs.org/2steps-jslogger/-/2steps-jslogger-1.0.3.tgz","fileCount":15,"integrity":"sha512-Pj3xnNwrCJt7WzYeoWxsSquyzypYk7o6fAfTuZBlPc0wy6qxmHX/x1nw3JD89sbEegYth3maiGq0sVM5ZLizqA==","signatures":[{"sig":"MEUCIQCiaWq8BgX+M7RBTG/SrIGP1AIgTWM5rmz4TwughGjoWgIgG8teRTX9DI2B63btL0bfNlZJQS8YOZBFHtbNQEkp4SA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":25654},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=18.0.0"},"gitHead":"1879ee97e72139c1d56a17c4f77d97f6c0e861d7","scripts":{"dev":"npm run demo","demo":"npm run build && node demo/app.js","build":"tsc","start":"npm run demo","test:new":"npm run build && node new-test-node.js","prepublishOnly":"npm run build","template:create":"node scripts/create-es-template.js"},"_npmUser":{"name":"ahsan-maqbool","email":"muhammad.maqbool@twosteps.ai"},"_npmVersion":"10.8.2","description":"Node.js logger for Elasticsearch with ECS format. Filter logs by index name, date, month.","directories":{},"_nodeVersion":"20.20.1","dependencies":{"@elastic/elasticsearch":"^8.19.1"},"_hasShrinkwrap":false,"devDependencies":{"express":"^4.18.0","typescript":"^5.0.0","@types/node":"^20.0.0"},"_npmOperationalInternal":{"tmp":"tmp/2steps-jslogger_1.0.3_1774534980082_0.7029848956843128","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"name":"2steps-jslogger","version":"1.1.0","keywords":["logging","elasticsearch","ecs","elastic","logger"],"author":{"name":"Twosteps"},"license":"MIT","_id":"2steps-jslogger@1.1.0","maintainers":[{"name":"ahsan-maqbool","email":"muhammad.maqbool@twosteps.ai"}],"dist":{"shasum":"7b729fd5ab7ebd85b2bfba71340edf67f70eb1e3","tarball":"https://registry.npmjs.org/2steps-jslogger/-/2steps-jslogger-1.1.0.tgz","fileCount":17,"integrity":"sha512-4frStlWTwmaszpBjrgLMlcqqgRMi2v4/lSdMsYceBhfXgrziLHP2yoN5AcvuBdjIGBxlhCO01oxue+U7emZG4w==","signatures":[{"sig":"MEQCIHBffGp5BlLAK+5gfwxu6HfVhMXzzSpUdskXqslCp2snAiAtDnLsezu+W3qVprGHsW4XHKFOy4dc5D9qefef0kflOw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":37227},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=18.0.0"},"gitHead":"d5dee492d2e712286dd214538d59e8c47ee6deb4","scripts":{"test":"npm run build && node --test tests/*.test.js","build":"tsc","test:logger":"npm run build && npm link && npm link 2steps-jslogger && node examples/test-logger.js","version:add":"bumpit add","version:bump":"bumpit bump","dev:test:prod":"npm run build && node otel-prod-test-node.js","dev:test:local":"npm run build && node otel-test-node.js","prepublishOnly":"npm run build","version:status":"bumpit status"},"_npmUser":{"name":"ahsan-maqbool","email":"muhammad.maqbool@twosteps.ai"},"_npmVersion":"10.8.2","description":"Node.js logger with ECS format. Ships logs to OpenTelemetry Collector (OTEL → Elasticsearch → Kibana).","directories":{},"_nodeVersion":"20.20.2","dependencies":{"@elastic/elasticsearch":"^8.19.1","@opentelemetry/api-logs":"^0.57.0","@opentelemetry/sdk-logs":"^0.57.0","@opentelemetry/resources":"^1.30.0","@opentelemetry/exporter-logs-otlp-http":"^0.57.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"dotenv":"^16.4.5","express":"^4.18.0","typescript":"^5.0.0","@types/node":"^20.0.0","@twostepsai/bumpit":"^0.2.1"},"_npmOperationalInternal":{"tmp":"tmp/2steps-jslogger_1.1.0_1781279463851_0.7500256569688613","host":"s3://npm-registry-packages-npm-production"}},"1.2.0":{"name":"2steps-jslogger","version":"1.2.0","description":"Node.js logger with ECS format. Ships logs to OpenTelemetry Collector (OTEL → Elasticsearch → Kibana).","main":"dist/index.js","types":"dist/index.d.ts","scripts":{"build":"tsc","prepublishOnly":"npm run build","test":"npm run build && node --test tests/*.test.js","test:logger":"npm run build && npm link && npm link 2steps-jslogger && node examples/test-logger.js","dev:test:local":"npm run build && node otel-test-node.js","dev:test:prod":"npm run build && node otel-prod-test-node.js","version:add":"bumpit add","version:status":"bumpit status","version:bump":"bumpit bump"},"publishConfig":{"access":"public"},"keywords":["logging","elasticsearch","ecs","elastic","logger"],"author":{"name":"Twosteps"},"license":"MIT","dependencies":{"@elastic/elasticsearch":"^8.19.1","@opentelemetry/api-logs":"^0.57.0","@opentelemetry/exporter-logs-otlp-http":"^0.57.0","@opentelemetry/resources":"^1.30.0","@opentelemetry/sdk-logs":"^0.57.0"},"devDependencies":{"@twostepsai/bumpit":"^0.2.1","@types/node":"^20.0.0","dotenv":"^16.4.5","express":"^4.18.0","typescript":"^5.0.0"},"engines":{"node":">=18.0.0"},"_id":"2steps-jslogger@1.2.0","gitHead":"5a479d66dcd12706922c16a2a173630e76afc565","_nodeVersion":"20.20.2","_npmVersion":"10.8.2","dist":{"integrity":"sha512-mHpTHrgqYRBfhotaYQldrHNkOL8UW7M4IfLV/XV0ODa/Ny5YTSU4FMf5xtfGKpkgwyXpshb4S+A8Ylnlb3t6Iw==","shasum":"bbfe7ecb66faff2c32910aa9e87e145e2e992e10","tarball":"https://registry.npmjs.org/2steps-jslogger/-/2steps-jslogger-1.2.0.tgz","fileCount":17,"unpackedSize":37227,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIEboccU8beBQLKO9aSQ/euTpL3KEsy83i+n0gRZzkexBAiBbtIihm/xhRrxfENvHYNaojbZWy2ldqp7wDMH1UsqntQ=="}]},"_npmUser":{"name":"ahsan-maqbool","email":"muhammad.maqbool@twosteps.ai"},"directories":{},"maintainers":[{"name":"ahsan-maqbool","email":"muhammad.maqbool@twosteps.ai"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/2steps-jslogger_1.2.0_1781281480270_0.4073368511505764"},"_hasShrinkwrap":false}},"time":{"created":"2026-03-26T14:22:59.990Z","modified":"2026-06-12T16:24:40.532Z","1.0.3":"2026-03-26T14:23:00.267Z","1.1.0":"2026-06-12T15:51:04.003Z","1.2.0":"2026-06-12T16:24:40.421Z"},"author":{"name":"Twosteps"},"license":"MIT","keywords":["logging","elasticsearch","ecs","elastic","logger"],"description":"Node.js logger with ECS format. Ships logs to OpenTelemetry Collector (OTEL → Elasticsearch → Kibana).","maintainers":[{"name":"ahsan-maqbool","email":"muhammad.maqbool@twosteps.ai"}],"readme":"# 2steps-jslogger\n\nnpm package for Twosteps Node.js apps. Install in **any project** — logs go to OTEL Collector → Elasticsearch → Kibana.\n\n```\nyour-app  →  OTEL Collector  →  Elasticsearch  →  Kibana\n```\n\n**Node.js 18+**\n\n---\n\n## Quick start\n\n### 1. Install\n\n```bash\nnpm install 2steps-jslogger dotenv\n```\n\n### 2. Create `.env` (project root)\n\n```bash\nOTEL_EXPORTER_OTLP_ENDPOINT=https://otel.your-host.example.com\nOTEL_EXPORTER_OTLP_HEADERS=\"Authorization=Basic <your-token>\"\nOTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf\n\nOTEL_SERVICE_NAME=service-my-app\nLOGGER_PROJECT_NAME=Project-my-app\nLOGGER_ENVIRONMENT=development\n\nOTEL_RESOURCE_ATTRIBUTES=\"environment=mac,host.name=my-host,elasticsearch.index=my-app-logs-v1\"\nOTEL_ELASTIC_MAPPING_MODE=bodymap\n```\n\n\n### 3. Create `logger.js`\n\n```js\nrequire('dotenv').config();\nconst { CustomLogger } = require('2steps-jslogger');\n\nconst logger = new CustomLogger();\n\nmodule.exports = { logger };\n```\n\nService, project, environment, and index come from `.env` — **no options needed in code**.\n\n### 4. Use in your app\n\n```js\nconst { logger } = require('./logger');\n\nlogger.info('Server started');\nlogger.info('User action', { user_id: 789, action: 'login' });\nlogger.warning('Slow API', { latency_ms: 420 });\nlogger.debug('Debug info', { step: 1 });\nlogger.error('Failed', { error_code: 'ERR_001' }, new Error('details'));\n\nawait logger.flush();\nawait logger.close();\n```\n\n**Note:** `logger.info()` and similar calls do not throw if OTLP export fails. Errors appear when you call `flush()` or `close()`. Always call both before process exit (scripts, tests, graceful shutdown).\n\n---\n\n## Testing\n\n### A. This repo — OTEL logs to Kibana (`examples/test-logger.js`)\n\nUses `require('2steps-jslogger')` like real apps. One-time setup:\n\n```bash\ncd nodejs-logger\ncp examples/.env.example examples/.env\n# Edit examples/.env — token, elasticsearch.index, service name\n```\n\nEach test run:\n\n```bash\nnpm run build\nnpm link\nnpm link 2steps-jslogger\nnode examples/test-logger.js\n```\n\nOr one command (build + link + run):\n\n```bash\nnpm run test:logger\n```\n\n**Env file:** `examples/.env`  \n**Kibana:** data view `{your-index}*` from `elasticsearch.index` (e.g. `jslogger-otel-v4*`), time field `@timestamp`, last 15 minutes.\n\n### B. This repo — production env file (`.env.production`)\n\nNo `2steps-jslogger` link; uses local `dist/`:\n\n```bash\nnpm run dev:test:prod\n```\n\n**Env file:** `.env.production` (repo root)\n\n### C. Unit tests (no logs sent)\n\n```bash\nnpm test\n```\n\n### D. Your app (after `npm install 2steps-jslogger`)\n\n```bash\nnpm install 2steps-jslogger dotenv\ncp node_modules/2steps-jslogger/examples/test-logger.js scripts/test-logger.js\ncp node_modules/2steps-jslogger/examples/.env.example scripts/.env\n# Edit scripts/.env\nnode scripts/test-logger.js\n```\n\n---\n\n## Express example\n\n```js\nconst express = require('express');\nconst { logger } = require('./logger');\n\nconst app = express();\n\napp.get('/health', (req, res) => {\n  logger.info('Health check');\n  res.json({ ok: true });\n});\n\nconst server = app.listen(3000, () => logger.info('Listening on 3000'));\n\nasync function shutdown() {\n  await logger.flush();\n  await logger.close();\n  server.close(() => process.exit(0));\n}\n\nprocess.on('SIGINT', shutdown);\nprocess.on('SIGTERM', shutdown);\n```\n\n---\n\n## Log levels\n\n| `LOGGER_ENVIRONMENT` | Default |\n|----------------------|---------|\n| `development` | DEBUG and above |\n| `production` | INFO and above |\n\nOverride: `LOGGER_LEVEL=DEBUG` or `LOGGER_LEVEL=INFO`\n\n| Method | Level |\n|--------|-------|\n| `logger.debug()` | DEBUG |\n| `logger.info()` | INFO |\n| `logger.warning()` / `.warn()` | WARNING |\n| `logger.error()` | ERROR |\n| `logger.critical()` | CRITICAL |\n\n---\n\n## Extra fields\n\n```js\nlogger.info('Request', {\n  request_id: 'abc',\n  method: 'POST',\n  endpoint: '/api/orders',\n  duration_ms: 120,\n});\n\nlogger.info('Login', {\n  user_id: '123',\n  email: 'user@example.com',\n});\n```\n\nIn Kibana: `custom_fields.*`, `auth.*`, `request_context.*`\n\n---\n\n## Example `.env`\n\n```bash\nOTEL_EXPORTER_OTLP_ENDPOINT=https://otel.your-host.example.com\nOTEL_EXPORTER_OTLP_HEADERS=\"Authorization=Basic <token>\"\nOTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf\n\nOTEL_SERVICE_NAME=service-my-app\nLOGGER_PROJECT_NAME=Project-my-app\nLOGGER_ENVIRONMENT=development\n\nOTEL_RESOURCE_ATTRIBUTES=\"environment=mac,host.name=my-host,elasticsearch.index=my-app-logs-v1\"\nOTEL_ELASTIC_MAPPING_MODE=bodymap\n```\n\n---\n\n## TypeScript\n\n```ts\nimport { CustomLogger } from '2steps-jslogger';\n\nexport const logger = new CustomLogger();\n```\n\n---\n\n## Troubleshooting\n\n| Problem | Solution |\n|---------|----------|\n| No logs in Kibana | Check endpoint and headers; `await logger.flush()` |\n| DEBUG missing | `LOGGER_ENVIRONMENT=development` or `LOGGER_LEVEL=DEBUG` |\n| No `message` field | `OTEL_ELASTIC_MAPPING_MODE=bodymap` |\n| Wrong index | Fix `elasticsearch.index` in `OTEL_RESOURCE_ATTRIBUTES` |\n| Export errors silent | Call `await logger.flush()` — errors log to stderr |\n\n---\n\n## Versioning & release (bumpit)\n\nThis repo uses [@twostepsai/bumpit](https://www.npmjs.com/package/@twostepsai/bumpit) for semver and changelog.\n\n### Contributor workflow (before merge)\n\nAfter your code changes, record release intent:\n\n```bash\nnpx @twostepsai/bumpit add\n```\n\nOr non-interactive (CI / scripts):\n\n```bash\nnpx @twostepsai/bumpit add --level patch --message \"Fix OTLP header parsing\"\n```\n\nCommit the generated `.bumpit/*.md` change file with your PR.\n\nCheck pending changes:\n\n```bash\nnpm run version:status\n```\n\n### Maintainer — publish via GitHub Actions\n\n1. Merge all PRs to `main`.\n2. GitHub → **Actions** → **Release** → **Run workflow**.\n3. Choose bump type: `patch` | `minor` | `major`.\n4. Workflow runs: test → bumpit bump → build → `npm publish` → git tag → GitHub Release.\n\n**Required secret:** `NPM_TOKEN` (npm automation token with publish access).\n\n### Maintainer — publish locally (optional)\n\n```bash\nnpm run version:bump    # bumps package.json + CHANGELOG.md\nnpm run build\nnpm publish --access public\ngit push origin HEAD --follow-tags\n```\n\n---\n\n## License\n\nMIT\n","readmeFilename":"README.md"}