{"_id":"@cobui/node-monitoring","_rev":"7-51e176de31901006c3a615d1cbb0e30e","name":"@cobui/node-monitoring","dist-tags":{"latest":"1.2.0"},"versions":{"1.0.0":{"name":"@cobui/node-monitoring","version":"1.0.0","keywords":["monitoring","metrics","influxdb","counter","gauge","histogram","nodejs"],"author":{"name":"Dennis Zerihun"},"license":"MIT","_id":"@cobui/node-monitoring@1.0.0","maintainers":[{"name":"cobui","email":"dennis.zerihun@mailbox.org"}],"homepage":"https://github.com/cobui/node-monitoring#readme","bugs":{"url":"https://github.com/cobui/node-monitoring/issues"},"dist":{"shasum":"3ec5d69f3ccc34dceb950555729f984b6ad2bbe4","tarball":"https://registry.npmjs.org/@cobui/node-monitoring/-/node-monitoring-1.0.0.tgz","fileCount":60,"integrity":"sha512-ifp433cGGlJ02GVCxKW3rpTBc/LkDe/5dUZQKXZMBBlYAhZwpA4VIKCDae4Ad8CDf8E2ahohmlt923q2GIWzeA==","signatures":[{"sig":"MEYCIQDFJmZIzLBAwCS9q6trxJTr29HABOt/yvL4M8Tpy8LRhAIhALs4R11LwPnQnRmT+MzKzZbaND5Ogr8VK8N8eoF7/ox6","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":158293},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=18"},"gitHead":"caa413d8ca64b9cf7e6ee5ebe0233c06b88a264a","scripts":{"docs":"typedoc","test":"vitest run","build":"tsc -p tsconfig.build.json","test:watch":"vitest","test:coverage":"vitest run --coverage"},"_npmUser":{"name":"cobui","email":"dennis.zerihun@mailbox.org"},"repository":{"url":"git+https://github.com/cobui/node-monitoring.git","type":"git"},"_npmVersion":"10.9.4","description":"A lightweight monitoring library for Node.js","directories":{},"_nodeVersion":"22.21.0","dependencies":{"js-yaml":"^4.1.1","lru-cache":"^11.3.0"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.21.0","vitest":"^4.1.3","typedoc":"^0.28.18","prettier":"^3.8.3","typescript":"^6.0.2","@types/node":"^25.5.2","@types/js-yaml":"^4.0.9","@vitest/coverage-v8":"^4.1.4"},"_npmOperationalInternal":{"tmp":"tmp/node-monitoring_1.0.0_1776763164079_0.18948455953779786","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@cobui/node-monitoring","version":"1.0.1","keywords":["monitoring","metrics","influxdb","counter","gauge","histogram","nodejs"],"author":{"name":"Dennis Zerihun"},"license":"MIT","_id":"@cobui/node-monitoring@1.0.1","maintainers":[{"name":"cobui","email":"dennis.zerihun@mailbox.org"}],"homepage":"https://github.com/cobui/node-monitoring#readme","bugs":{"url":"https://github.com/cobui/node-monitoring/issues"},"dist":{"shasum":"8aebc97d9674b5009ba031f9bbc7742a7239b1cf","tarball":"https://registry.npmjs.org/@cobui/node-monitoring/-/node-monitoring-1.0.1.tgz","fileCount":60,"integrity":"sha512-mQfzSgdQQBiyUyiUxYNSRT33im9r/N+urGQGuju4Q8H55wtyaGzDwqF7uFUsC2UnPn1US2sFRQyiSvmhWCcEWA==","signatures":[{"sig":"MEUCIQChprhbyA4EA7UOJJVZxzPz3TbqQWav4UafNADmNAb2KwIgNjwgYvBnGKLJMVHnbxh88L2HmaZXVQhGiwdHt1gqvKc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":159670},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=18"},"gitHead":"d5dd161d4b6c787033e6d1666e02dc4c3e3f079f","scripts":{"docs":"typedoc","test":"vitest run","build":"tsc -p tsconfig.build.json","test:watch":"vitest","test:coverage":"vitest run --coverage"},"_npmUser":{"name":"cobui","email":"dennis.zerihun@mailbox.org"},"repository":{"url":"git+https://github.com/cobui/node-monitoring.git","type":"git"},"_npmVersion":"10.9.4","description":"A lightweight monitoring library for Node.js","directories":{},"_nodeVersion":"22.21.0","dependencies":{"js-yaml":"^4.1.1","lru-cache":"^11.3.0"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.21.0","vitest":"^4.1.3","typedoc":"^0.28.18","prettier":"^3.8.3","typescript":"^6.0.2","@types/node":"^25.5.2","@types/js-yaml":"^4.0.9","@vitest/coverage-v8":"^4.1.4"},"_npmOperationalInternal":{"tmp":"tmp/node-monitoring_1.0.1_1776852635966_0.66737643581124","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"name":"@cobui/node-monitoring","version":"1.1.0","keywords":["monitoring","metrics","influxdb","counter","gauge","histogram","nodejs"],"author":{"name":"Dennis Zerihun"},"license":"MIT","_id":"@cobui/node-monitoring@1.1.0","maintainers":[{"name":"cobui","email":"dennis.zerihun@mailbox.org"}],"homepage":"https://github.com/cobui/node-monitoring#readme","bugs":{"url":"https://github.com/cobui/node-monitoring/issues"},"dist":{"shasum":"dbb91e11859c478a84a190491f27fc90907bc28c","tarball":"https://registry.npmjs.org/@cobui/node-monitoring/-/node-monitoring-1.1.0.tgz","fileCount":60,"integrity":"sha512-ftLG/7apNmjKYDh6004RblvGcsXUsxjmhwRwX7459ZEVTOQa/mgQgQp/VsExia7O7RMlQYuXO7z+KR1JFcU4QQ==","signatures":[{"sig":"MEUCIGH4ZCo0xMUnbKflTnvOw15LDfpTPGOKTxffVbq5SIxLAiEAsKuqYkvwv65l+3ZoPVWSfqKthGde+iapW+aSPJ9lMBY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":160681},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=18"},"gitHead":"8ee93be16e028cf1c2c9967c235966802797d0bc","scripts":{"docs":"typedoc","test":"vitest run","build":"tsc -p tsconfig.build.json","test:watch":"vitest","test:coverage":"vitest run --coverage"},"_npmUser":{"name":"cobui","email":"dennis.zerihun@mailbox.org"},"repository":{"url":"git+https://github.com/cobui/node-monitoring.git","type":"git"},"_npmVersion":"10.9.4","description":"A lightweight monitoring library for Node.js","directories":{},"_nodeVersion":"22.21.0","dependencies":{"js-yaml":"^4.1.1","lru-cache":"^11.3.0"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.21.0","vitest":"^4.1.3","typedoc":"^0.28.18","prettier":"^3.8.3","typescript":"^6.0.2","@types/node":"^25.5.2","@types/js-yaml":"^4.0.9","@vitest/coverage-v8":"^4.1.4"},"_npmOperationalInternal":{"tmp":"tmp/node-monitoring_1.1.0_1777280183103_0.6131237398357117","host":"s3://npm-registry-packages-npm-production"}},"1.1.1":{"name":"@cobui/node-monitoring","version":"1.1.1","keywords":["monitoring","metrics","influxdb","counter","gauge","histogram","nodejs"],"author":{"name":"Dennis Zerihun"},"license":"MIT","_id":"@cobui/node-monitoring@1.1.1","maintainers":[{"name":"cobui","email":"dennis.zerihun@mailbox.org"}],"homepage":"https://github.com/cobui/node-monitoring#readme","bugs":{"url":"https://github.com/cobui/node-monitoring/issues"},"dist":{"shasum":"d5c13a14b620f97bbf5e3c5000facfc4f9057a20","tarball":"https://registry.npmjs.org/@cobui/node-monitoring/-/node-monitoring-1.1.1.tgz","fileCount":60,"integrity":"sha512-KVTsUwcpVRO8KE5eaihjNgvgeqQBBjXz9x/JLa5zTF+n1zpLMMJ5Ukw3hqamawCKbVkGqGUvGHuv1GJK48/cKA==","signatures":[{"sig":"MEUCIFOCwEzUN1zgWD4I2YWEiEvs1nVTRG2joSwd0J5lndUdAiEAqSoXtCWz6AndCBRg8Pdf5yEoIkp584tZ7nJuuhtaBGg=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":160701},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=18"},"gitHead":"f453b7c9e11e3ba9f1bed1faa0358c7072d3fd95","scripts":{"docs":"typedoc","test":"vitest run","build":"tsc -p tsconfig.build.json","test:watch":"vitest","test:coverage":"vitest run --coverage"},"_npmUser":{"name":"cobui","email":"dennis.zerihun@mailbox.org"},"repository":{"url":"git+https://github.com/cobui/node-monitoring.git","type":"git"},"_npmVersion":"10.9.4","description":"A lightweight monitoring library for Node.js","directories":{},"_nodeVersion":"22.21.0","dependencies":{"js-yaml":"^4.1.1","lru-cache":"^11.3.0"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.21.0","vitest":"^4.1.3","typedoc":"^0.28.18","prettier":"^3.8.3","typescript":"^6.0.2","@types/node":"^25.5.2","@types/js-yaml":"^4.0.9","@vitest/coverage-v8":"^4.1.4"},"_npmOperationalInternal":{"tmp":"tmp/node-monitoring_1.1.1_1777291925371_0.6687970058850674","host":"s3://npm-registry-packages-npm-production"}},"1.1.2":{"name":"@cobui/node-monitoring","version":"1.1.2","keywords":["monitoring","metrics","influxdb","counter","gauge","histogram","nodejs"],"author":{"name":"Dennis Zerihun"},"license":"MIT","_id":"@cobui/node-monitoring@1.1.2","maintainers":[{"name":"cobui","email":"dennis.zerihun@mailbox.org"}],"homepage":"https://github.com/cobui/node-monitoring#readme","bugs":{"url":"https://github.com/cobui/node-monitoring/issues"},"dist":{"shasum":"2289a2771d4a1350cbef337560172e98732f09f7","tarball":"https://registry.npmjs.org/@cobui/node-monitoring/-/node-monitoring-1.1.2.tgz","fileCount":60,"integrity":"sha512-z9eP0K7vb4V84C13LAgHHzliD14wsakdZiat0w0C8g2h1yqdFqJCE/ayIDvz3MuxugJPV9Z7w50FJs96yEQv7A==","signatures":[{"sig":"MEUCIQDucw14gPSkLBQgBPh2vWI2kraaYfSjSy+c6PWj1fPAuAIgHK5FckObGVXww+8TozUPdzFV7EPzY0ugXBTXnBIJO0g=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":160723},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=18"},"gitHead":"a64bdea3d15abb037e80df8bc1fcc9fece966366","scripts":{"docs":"typedoc","test":"vitest run","build":"tsc -p tsconfig.build.json","test:watch":"vitest","test:coverage":"vitest run --coverage"},"_npmUser":{"name":"cobui","email":"dennis.zerihun@mailbox.org"},"repository":{"url":"git+https://github.com/cobui/node-monitoring.git","type":"git"},"_npmVersion":"10.9.4","description":"A lightweight monitoring library for Node.js","directories":{},"_nodeVersion":"22.21.0","dependencies":{"js-yaml":"^4.1.1","lru-cache":"^11.3.0"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.21.0","vitest":"^4.1.3","typedoc":"^0.28.18","prettier":"^3.8.3","typescript":"^6.0.2","@types/node":"^25.5.2","@types/js-yaml":"^4.0.9","@vitest/coverage-v8":"^4.1.4"},"_npmOperationalInternal":{"tmp":"tmp/node-monitoring_1.1.2_1777292246822_0.44682458167606964","host":"s3://npm-registry-packages-npm-production"}},"1.1.3":{"name":"@cobui/node-monitoring","version":"1.1.3","keywords":["monitoring","metrics","influxdb","counter","gauge","histogram","nodejs"],"author":{"name":"Dennis Zerihun"},"license":"MIT","_id":"@cobui/node-monitoring@1.1.3","maintainers":[{"name":"cobui","email":"dennis.zerihun@mailbox.org"}],"homepage":"https://github.com/cobui/node-monitoring#readme","bugs":{"url":"https://github.com/cobui/node-monitoring/issues"},"dist":{"shasum":"9ddfb681ba9a08af60c04057ba87058c5d612c87","tarball":"https://registry.npmjs.org/@cobui/node-monitoring/-/node-monitoring-1.1.3.tgz","fileCount":60,"integrity":"sha512-bTBUgbE+PKn2t4+qNOVuqxMtaWsZGpq8lcbetLOKaXm8+xbSKsIhYxjzig/+KEGUiZO3YDhVxDB0QkSJ7NBo+g==","signatures":[{"sig":"MEUCICQwOmpiPZXOdmH0PrV+CVadTL7E0BF6iSJ++zfpF9RZAiEA9ozRsgZN2Gg7/0s/5lUH/OzuhgVHqKxIdY7K9G4Ff24=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":171254},"main":"dist/index.js","type":"commonjs","types":"dist/index.d.ts","engines":{"node":">=18"},"gitHead":"ebd37b43eeed8e40e6edcfe1c2c6ee8401e4e77d","scripts":{"docs":"typedoc","test":"vitest run","build":"tsc -p tsconfig.build.json","test:watch":"vitest","test:coverage":"vitest run --coverage"},"_npmUser":{"name":"cobui","email":"dennis.zerihun@mailbox.org"},"repository":{"url":"git+https://github.com/cobui/node-monitoring.git","type":"git"},"_npmVersion":"10.9.4","description":"A lightweight monitoring library for Node.js","directories":{},"_nodeVersion":"22.21.0","dependencies":{"js-yaml":"^4.1.1","lru-cache":"^11.3.0"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.21.0","vitest":"^4.1.3","typedoc":"^0.28.18","prettier":"^3.8.3","typescript":"^6.0.2","@types/node":"^25.5.2","@types/js-yaml":"^4.0.9","@vitest/coverage-v8":"^4.1.4"},"_npmOperationalInternal":{"tmp":"tmp/node-monitoring_1.1.3_1777913488919_0.13704051722171018","host":"s3://npm-registry-packages-npm-production"}},"1.2.0":{"name":"@cobui/node-monitoring","version":"1.2.0","description":"A lightweight monitoring library for Node.js","author":{"name":"Dennis Zerihun"},"license":"MIT","type":"commonjs","main":"dist/index.js","types":"dist/index.d.ts","repository":{"type":"git","url":"git+https://github.com/cobui/node-monitoring.git"},"keywords":["monitoring","metrics","influxdb","counter","gauge","histogram","nodejs"],"engines":{"node":">=18"},"scripts":{"build":"tsc -p tsconfig.build.json","test":"vitest run","test:coverage":"vitest run --coverage","test:watch":"vitest","docs":"typedoc"},"dependencies":{"js-yaml":"^4.1.1","lru-cache":"^11.3.0"},"devDependencies":{"@types/js-yaml":"^4.0.9","@types/node":"^25.5.2","@vitest/coverage-v8":"^4.1.4","prettier":"^3.8.3","tsx":"^4.21.0","typedoc":"^0.28.18","typescript":"^6.0.2","vitest":"^4.1.3"},"_id":"@cobui/node-monitoring@1.2.0","gitHead":"d9a0dc0c7364dfb7b86eab5da97bf0980d75cc2d","bugs":{"url":"https://github.com/cobui/node-monitoring/issues"},"homepage":"https://github.com/cobui/node-monitoring#readme","_nodeVersion":"22.21.0","_npmVersion":"10.9.4","dist":{"integrity":"sha512-NX+uNPE3Eo8XatQNqFtnyRwo8win70/Xm4cYNhnS14tZRGDFeBSW7CVIGUXfUOqTIoCClFCvFKQ4pxMwzJW8lw==","shasum":"81a1a904a85911c00767dba2397c88cf339efa9f","tarball":"https://registry.npmjs.org/@cobui/node-monitoring/-/node-monitoring-1.2.0.tgz","fileCount":60,"unpackedSize":173566,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIC7+ruE94/K0nlXuzppClrhHaJnztcyOYqX83NpOE7NFAiAi9HuabZjs8bzSzchXSa5Kz/E2ptM/WYOeLR18YzhCTg=="}]},"_npmUser":{"name":"cobui","email":"dennis.zerihun@mailbox.org"},"directories":{},"maintainers":[{"name":"cobui","email":"dennis.zerihun@mailbox.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/node-monitoring_1.2.0_1777993691381_0.48285569414702145"},"_hasShrinkwrap":false}},"time":{"created":"2026-04-21T09:19:23.958Z","modified":"2026-05-05T15:08:11.740Z","1.0.0":"2026-04-21T09:19:24.214Z","1.0.1":"2026-04-22T10:10:36.180Z","1.1.0":"2026-04-27T08:56:23.230Z","1.1.1":"2026-04-27T12:12:05.558Z","1.1.2":"2026-04-27T12:17:26.999Z","1.1.3":"2026-05-04T16:51:29.059Z","1.2.0":"2026-05-05T15:08:11.583Z"},"bugs":{"url":"https://github.com/cobui/node-monitoring/issues"},"author":{"name":"Dennis Zerihun"},"license":"MIT","homepage":"https://github.com/cobui/node-monitoring#readme","keywords":["monitoring","metrics","influxdb","counter","gauge","histogram","nodejs"],"repository":{"type":"git","url":"git+https://github.com/cobui/node-monitoring.git"},"description":"A lightweight monitoring library for Node.js","maintainers":[{"name":"cobui","email":"dennis.zerihun@mailbox.org"}],"readme":"# node-monitoring\n\nLightweight monitoring for Node.js. Define metrics in YAML, drop sensors in your code, data goes to InfluxDB.\n\n---\n\n## Quick start\n\nParse your config file and pass it directly to `monitoring.add()`\n\n```ts\nimport { Monitoring, loadConfig, Counter, Gauge, Histogram } from \"@cobui/node-monitoring\";\n\nconst config = loadConfig(\"monitoring.yml\") as any;\nconst monitoring = new Monitoring();\n\nmonitoring.add(config);\n\n// Sensors can be created anywhere — no reference to `monitoring` needed\nconst requests = Counter.create(\"http.requests\", \"app\");\nconst latency = Histogram.create(\"http.latency\", \"app\");\nconst memory = Gauge.create(\"process.mem\", \"app\");\n\n// In your request handler:\nrequests.increment(1, { route: \"/api/users\", method: \"GET\" });\nlatency.record(42, { route: \"/api/users\" });\nmemory.set(process.memoryUsage().heapUsed / 1024 / 1024);\n\n// Before process exit: flush(), then destroy().\n// flush() resolves only after all data is sent; destroy() clears remaining handles.\nawait monitoring.flush();\nmonitoring.destroy();\n```\n\nSee [`config.example.yml`](config.example.yml) for a full annotated config file.\n\n---\n\n## Sensors\n\nSensors are the primary recording API.\n\n```ts\nimport { Counter, Gauge, Histogram } from \"@cobui/node-monitoring\";\n\nconst hits = Counter.create(\"http.requests\", \"app\");\nconst memory = Gauge.create(\"process.mem\", \"app\");\nconst latency = Histogram.create(\"http.latency\", \"app\");\n```\n\n| Sensor      | Metric type | Method                     | Use for                                           |\n| ----------- | ----------- | -------------------------- | ------------------------------------------------- |\n| `Counter`   | counter     | `increment(delta?, tags?)` | Events (requests, errors, cache hits)             |\n| `Gauge`     | gauge       | `set(value, tags?)`        | Current values (memory, queue depth, connections) |\n| `Histogram` | histogram   | `record(value, tags?)`     | Distributions (latencies, sizes, durations)       |\n\n```ts\nhits.increment(); // +1\nhits.increment(5); // +5\nhits.increment({ route: \"/api\" }); // +1 with tags (shorthand)\n\nmemory.set(process.memoryUsage().heapUsed);\n\nlatency.record(42, { route: \"/api\", status: \"200\" });\n```\n\n> If a sensor fires before its namespace is active, or the URI doesn't match a registered metric, a warning is emitted once per sensor. See [Warnings](#warnings) below.\n\n---\n\n## Metric types\n\n| Type        | `reset` default                        |\n| ----------- | -------------------------------------- |\n| `counter`   | `true` (per-interval rate)             |\n| `histogram` | `true` (per-interval distribution)     |\n| `gauge`     | `false` (current value, never cleared) |\n\nCounter and histogram reset after each collection cycle because you typically want per-interval rates and distributions, not cumulative totals. Gauge never resets because it represents an instantaneous value, when clearing it would produce a gap until the next `set()` call.\n\nSet `reset: false` on a counter to get a monotonic total (diff/rate at query time).\n\n---\n\n## MetricConfig\n\n```ts\n{\n  uri:      string;          // identifier unique to namespace, e.g. \"http.requests\"\n  type:     \"counter\" | \"gauge\" | \"histogram\";\n  interval: number;          // collection interval in milliseconds\n\n  // Optional\n  reset?:    boolean;        // defaults: counter/histogram=true, gauge=false\n  enabled?:  boolean;        // default: true\n  tags?:     Record<string, string | number | boolean>;  // added to every data point\n  exclude?:  string[];       // strip these tag keys before hashing to reduce cardinality\n  cache?:    { max?: number }; // max distinct tag combinations to track (default: 1000)\n}\n```\n\n---\n\n## Lifecycle\n\n```ts\nconst monitoring = new Monitoring();\n\n// Add a namespace — starts immediately when enabled: true (default)\nmonitoring.add([{ namespace: \"app\", transporter: ..., metrics: [...] }]);\n\n// Start / pause all enabled namespaces\nmonitoring.start();\nmonitoring.stop();\n\n// Per-namespace control\nmonitoring.setNamespaceEnabled(\"app\", false);  // pause\nmonitoring.setNamespaceEnabled(\"app\", true);   // resume\nmonitoring.isEnabled(\"app\");          // → boolean\n\n// Per-metric control\nmonitoring.setMetricEnabled(\"http.requests\", false);\nmonitoring.reschedule(\"http.requests\", 30_000);\n\n// Before process exit: flush buffered data, then destroy.\n// flush() waits until every queued item has been sent (or exhausted retries),\n// but it does NOT close all handles — the loss-reporting timer inside the\n// transport queue stays alive until destroy() is called. Always pair them.\nawait monitoring.flush();\nmonitoring.destroy();\n```\n\n---\n\n## Transporter config — InfluxDB\n\n### InfluxDB v2 (InfluxDB Cloud / OSS 2.x)\n\n```yaml\ntransporter:\n  type: influx\n  version: 2\n  key:\n    influx # default: \"influx\". Namespaces sharing the same key share one queue\n    # and rate limit. Give each transporter its own key when you want\n    # independent queues (e.g. different InfluxDB hosts or rate limits).\n  host: influxdb.example.com\n  port: 8086 # default: 8086\n  protocol: https # default: https\n  org: my-org\n  bucket: app-metrics\n  token: \"YOUR_TOKEN\"\n\n  rateLimit: 20 # requests per second (default: 10)\n  measurementStrategy: uri # \"uri\" (default) or \"namespace\" (see below)\n\n  retry:\n    retries: 3 # attempts after the first (default: 3)\n    minTimeout: 1000 # ms before first retry (default: 1000)\n    maxTimeout: 30000 # upper bound on backoff (default: 30000)\n    factor: 2 # exponential multiplier (default: 2)\n\n  queue:\n    maxSize: 10000 # drop incoming when queue exceeds this (default: unlimited)\n    lossInterval: 300000 # ms between loss-record flushes (default: 5 min)\n```\n\n### InfluxDB v3\n\nWorks for both InfluxDB 3 Core (self-hosted OSS) and InfluxDB Cloud Serverless. The write endpoint and auth format are identical — only the connection details differ.\n\n**Core (self-hosted):**\n```yaml\ntransporter:\n  type: influx\n  version: 3\n  host: localhost\n  port: 8181     # Core default — must be set explicitly\n  protocol: http # default: http — use https in production\n  database: app-metrics\n  token: \"YOUR_TOKEN\"\n```\n\n**Cloud Serverless:**\n```yaml\ntransporter:\n  type: influx\n  version: 3\n  host: eu-central-1-1.aws.cloud2.influxdata.com\n  protocol: https # default: http, so set this explicitly for Cloud\n  # port omitted → Node uses 443 for https automatically\n  database: app-metrics\n  token: \"YOUR_TOKEN\"\n```\n\n`measurementStrategy`, `includeNamespaceTag`, `rateLimit`, `retry`, and `queue` apply to v3 in the same way as v2.\n\n### InfluxDB v1 (InfluxDB OSS 1.x)\n\n```yaml\ntransporter:\n  type: influx\n  version: 1\n  key: influx # default: \"influx\" — see note in v2 section above\n  host: influx-legacy.internal\n  port: 8086\n  protocol: http # default: http\n  database: app-metrics\n  retentionPolicy: 90d # optional\n  username: monitor # optional -> omit both username and password for unauthenticated instances\n  password: \"YOUR_PASSWORD\" # optional -> must be provided together with username\n```\n\n### Measurement strategy\n\n| Strategy        | Measurement name                      | When to use                                       |\n| --------------- | ------------------------------------- | ------------------------------------------------- |\n| `uri` (default) | The metric URI (e.g. `http.requests`) | Each metric has its own schema                    |\n| `namespace`     | The namespace (e.g. `app`)            | All metrics in one place; URI kept as a `uri` tag |\n\n### Namespace tag (`includeNamespaceTag`)\n\nBy default the `namespace` value is **not** added as a tag on every data point. For most setups this is the right choice — with `measurementStrategy: namespace` the namespace is already the measurement name, and with `measurementStrategy: uri` and a single namespace it would just be a constant on every row.\n\nSet `includeNamespaceTag: true` on the **transporter config** when you use `measurementStrategy: uri` with multiple namespaces sharing the same transporter. This lets you filter by namespace in InfluxDB without it being the measurement name.\n\n```yaml\n- namespace: app\n  transporter:\n    type: influx\n    measurementStrategy: uri\n    includeNamespaceTag: true   # stamps namespace: \"app\" on every aggregate\n    ...\n```\n\n### Sharing a transporter across namespaces\n\nWhen multiple namespaces write to the same InfluxDB instance, define the full transporter config once and reference it by key in subsequent namespaces:\n\n```yaml\n- namespace: app\n  transporter:\n    type: influx\n    key: influx          # full config defined here\n    host: influxdb.example.com\n    ...\n\n- namespace: debug\n  transporter:\n    key: influx          # reuses the queue defined above — no duplicate config\n```\n\nThe second namespace reuses the same rate-limited queue. The referenced key must appear before the ref in the config array.\n\n---\n\n## Cluster mode\n\n### Data plane (automatic)\n\nOn worker processes, aggregates are automatically forwarded to the primary via IPC. The primary consolidates them in a shared rate-limited queue and sends them to InfluxDB. No setup is required on the worker side — the package handles this transparently.\n\n**The primary must have a Monitor registered with a matching transporter key.** The IPC listener on the primary routes incoming aggregates by transporter key. If no Monitor on the primary has registered that key, messages are silently dropped. In a typical cluster setup the primary naturally runs a Monitor alongside its workers. In setups where the primary does nothing except fork workers (e.g. PM2 cluster mode, separate primary/worker files), the primary must still instantiate a `Monitoring` to anchor the queue.\n\n### Control plane (application responsibility)\n\nThe package's IPC support is one-directional: **worker → primary** for metric data. Runtime control operations — `start()`, `stop()`, `setNamespaceEnabled()`, `reschedule()` — are **local to the calling process**. In a cluster, calling `monitoring.stop()` inside a request handler only stops the monitor on whichever worker handled that request; the other workers are unaffected.\n\nIf your application needs runtime monitoring control to propagate across all workers (e.g. via an admin UI), this must be coordinated at the application layer. The recommended patterns are:\n\n- **Put admin endpoints on the primary** (e.g. a separate port like `:9090`). The primary is a single stable process — changes made there apply exactly once.\n- **Broadcast via IPC** — the primary receives the admin command and forwards it to each worker with `worker.send(command)`.\n\nThe package deliberately does not provide a control-plane broadcast mechanism, as the application layer owns decisions about acknowledgement, ordering, and error handling.\n\n### Per-process namespace constraint\n\nEach namespace may only be active once per process. Registering the same namespace in two `Monitoring` instances within the same process throws an error. This constraint is per-process — workers, cron jobs, and separate containers each have independent memory and are unaffected by each other.\n\n---\n\n## Warnings\n\nSensors emit a typed warning event the first time an issue is detected. By default warnings fall through to `console.warn`. Subscribe to any category to route them to your own logger or suppress them entirely:\n\n```ts\nimport { warnings } from \"@cobui/node-monitoring\";\n\nwarnings.on(\"sensor:inactive\", ({ uri, namespace }) => {\n  /* namespace not started */\n});\nwarnings.on(\"sensor:not-found\", ({ uri, namespace, type }) => {\n  /* URI not registered */\n});\nwarnings.on(\"sensor:ambiguous\", ({ uri, namespaces }) => {\n  /* multiple active namespaces, no explicit ns */\n});\nwarnings.on(\"transport:loss\", ({ uri, namespaces }) => {\n  /* queue dropped measurements after last failed retry */\n});\n```\n\nEach sensor warning fires at most once per sensor instance.\n\n---\n\n## Design notes\n\n**No silent failures.** Sensors emit a one-time warning if the namespace is not active or the URI is not found, so misconfigurations surface immediately without spamming logs.\n\n**No TTL on metric cache.** TTL causes implicit counter resets and breaks rate/diff queries. Metrics accumulate until a collection cycle runs; `reset: true` clears them after.\n\n**Tag ordering.** Tags are sorted alphabetically before sending to the backend to improve Influx performance.\n\n**Loss records.** When the queue is full or retries are exhausted, lost items are counted per namespace and flushed as a `monitoring.loss` aggregate at a configurable interval. This lets you track dropped metrics without flooding the queue.\n","readmeFilename":"README.md"}