@sonde/packs 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +6 -0
- package/.turbo/turbo-test.log +814 -0
- package/.turbo/turbo-typecheck.log +4 -0
- package/CHANGELOG.md +10 -0
- package/dist/index.d.ts +16 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +40 -2
- package/dist/index.js.map +1 -1
- package/dist/integrations/citrix.d.ts +13 -0
- package/dist/integrations/citrix.d.ts.map +1 -0
- package/dist/integrations/citrix.js +420 -0
- package/dist/integrations/citrix.js.map +1 -0
- package/dist/integrations/citrix.test.d.ts +2 -0
- package/dist/integrations/citrix.test.d.ts.map +1 -0
- package/dist/integrations/citrix.test.js +464 -0
- package/dist/integrations/citrix.test.js.map +1 -0
- package/dist/integrations/graph.d.ts +9 -0
- package/dist/integrations/graph.d.ts.map +1 -0
- package/dist/integrations/graph.js +290 -0
- package/dist/integrations/graph.js.map +1 -0
- package/dist/integrations/graph.test.d.ts +2 -0
- package/dist/integrations/graph.test.d.ts.map +1 -0
- package/dist/integrations/graph.test.js +356 -0
- package/dist/integrations/graph.test.js.map +1 -0
- package/dist/integrations/httpbin.d.ts +3 -0
- package/dist/integrations/httpbin.d.ts.map +1 -0
- package/dist/integrations/httpbin.js +70 -0
- package/dist/integrations/httpbin.js.map +1 -0
- package/dist/integrations/nutanix.d.ts +18 -0
- package/dist/integrations/nutanix.d.ts.map +1 -0
- package/dist/integrations/nutanix.js +1121 -0
- package/dist/integrations/nutanix.js.map +1 -0
- package/dist/integrations/nutanix.test.d.ts +2 -0
- package/dist/integrations/nutanix.test.d.ts.map +1 -0
- package/dist/integrations/nutanix.test.js +978 -0
- package/dist/integrations/nutanix.test.js.map +1 -0
- package/dist/integrations/proxmox.d.ts +12 -0
- package/dist/integrations/proxmox.d.ts.map +1 -0
- package/dist/integrations/proxmox.js +733 -0
- package/dist/integrations/proxmox.js.map +1 -0
- package/dist/integrations/proxmox.test.d.ts +2 -0
- package/dist/integrations/proxmox.test.d.ts.map +1 -0
- package/dist/integrations/proxmox.test.js +697 -0
- package/dist/integrations/proxmox.test.js.map +1 -0
- package/dist/integrations/servicenow.d.ts +3 -0
- package/dist/integrations/servicenow.d.ts.map +1 -0
- package/dist/integrations/servicenow.js +257 -0
- package/dist/integrations/servicenow.js.map +1 -0
- package/dist/integrations/servicenow.test.d.ts +2 -0
- package/dist/integrations/servicenow.test.d.ts.map +1 -0
- package/dist/integrations/servicenow.test.js +217 -0
- package/dist/integrations/servicenow.test.js.map +1 -0
- package/dist/integrations/splunk.d.ts +9 -0
- package/dist/integrations/splunk.d.ts.map +1 -0
- package/dist/integrations/splunk.js +242 -0
- package/dist/integrations/splunk.js.map +1 -0
- package/dist/integrations/splunk.test.d.ts +2 -0
- package/dist/integrations/splunk.test.d.ts.map +1 -0
- package/dist/integrations/splunk.test.js +323 -0
- package/dist/integrations/splunk.test.js.map +1 -0
- package/dist/mysql/index.d.ts +3 -0
- package/dist/mysql/index.d.ts.map +1 -0
- package/dist/mysql/index.js +13 -0
- package/dist/mysql/index.js.map +1 -0
- package/dist/mysql/manifest.d.ts +3 -0
- package/dist/mysql/manifest.d.ts.map +1 -0
- package/dist/mysql/manifest.js +69 -0
- package/dist/mysql/manifest.js.map +1 -0
- package/dist/mysql/probes/databases-list.d.ts +13 -0
- package/dist/mysql/probes/databases-list.d.ts.map +1 -0
- package/dist/mysql/probes/databases-list.js +31 -0
- package/dist/mysql/probes/databases-list.js.map +1 -0
- package/dist/mysql/probes/databases-list.test.d.ts +2 -0
- package/dist/mysql/probes/databases-list.test.d.ts.map +1 -0
- package/dist/mysql/probes/databases-list.test.js +54 -0
- package/dist/mysql/probes/databases-list.test.js.map +1 -0
- package/dist/mysql/probes/processlist.d.ts +18 -0
- package/dist/mysql/probes/processlist.d.ts.map +1 -0
- package/dist/mysql/probes/processlist.js +36 -0
- package/dist/mysql/probes/processlist.js.map +1 -0
- package/dist/mysql/probes/processlist.test.d.ts +2 -0
- package/dist/mysql/probes/processlist.test.d.ts.map +1 -0
- package/dist/mysql/probes/processlist.test.js +41 -0
- package/dist/mysql/probes/processlist.test.js.map +1 -0
- package/dist/mysql/probes/status.d.ts +14 -0
- package/dist/mysql/probes/status.d.ts.map +1 -0
- package/dist/mysql/probes/status.js +40 -0
- package/dist/mysql/probes/status.js.map +1 -0
- package/dist/mysql/probes/status.test.d.ts +2 -0
- package/dist/mysql/probes/status.test.d.ts.map +1 -0
- package/dist/mysql/probes/status.test.js +43 -0
- package/dist/mysql/probes/status.test.js.map +1 -0
- package/dist/nginx/index.d.ts +3 -0
- package/dist/nginx/index.d.ts.map +1 -0
- package/dist/nginx/index.js +13 -0
- package/dist/nginx/index.js.map +1 -0
- package/dist/nginx/manifest.d.ts +3 -0
- package/dist/nginx/manifest.d.ts.map +1 -0
- package/dist/nginx/manifest.js +68 -0
- package/dist/nginx/manifest.js.map +1 -0
- package/dist/nginx/probes/access-log-tail.d.ts +9 -0
- package/dist/nginx/probes/access-log-tail.d.ts.map +1 -0
- package/dist/nginx/probes/access-log-tail.js +14 -0
- package/dist/nginx/probes/access-log-tail.js.map +1 -0
- package/dist/nginx/probes/access-log-tail.test.d.ts +2 -0
- package/dist/nginx/probes/access-log-tail.test.d.ts.map +1 -0
- package/dist/nginx/probes/access-log-tail.test.js +40 -0
- package/dist/nginx/probes/access-log-tail.test.js.map +1 -0
- package/dist/nginx/probes/config-test.d.ts +8 -0
- package/dist/nginx/probes/config-test.d.ts.map +1 -0
- package/dist/nginx/probes/config-test.js +18 -0
- package/dist/nginx/probes/config-test.js.map +1 -0
- package/dist/nginx/probes/config-test.test.d.ts +2 -0
- package/dist/nginx/probes/config-test.test.d.ts.map +1 -0
- package/dist/nginx/probes/config-test.test.js +35 -0
- package/dist/nginx/probes/config-test.test.js.map +1 -0
- package/dist/nginx/probes/error-log-tail.d.ts +9 -0
- package/dist/nginx/probes/error-log-tail.d.ts.map +1 -0
- package/dist/nginx/probes/error-log-tail.js +14 -0
- package/dist/nginx/probes/error-log-tail.js.map +1 -0
- package/dist/nginx/probes/error-log-tail.test.d.ts +2 -0
- package/dist/nginx/probes/error-log-tail.test.d.ts.map +1 -0
- package/dist/nginx/probes/error-log-tail.test.js +34 -0
- package/dist/nginx/probes/error-log-tail.test.js.map +1 -0
- package/dist/postgres/index.d.ts +3 -0
- package/dist/postgres/index.d.ts.map +1 -0
- package/dist/postgres/index.js +13 -0
- package/dist/postgres/index.js.map +1 -0
- package/dist/postgres/manifest.d.ts +3 -0
- package/dist/postgres/manifest.d.ts.map +1 -0
- package/dist/postgres/manifest.js +90 -0
- package/dist/postgres/manifest.js.map +1 -0
- package/dist/postgres/probes/connections-active.d.ts +17 -0
- package/dist/postgres/probes/connections-active.d.ts.map +1 -0
- package/dist/postgres/probes/connections-active.js +37 -0
- package/dist/postgres/probes/connections-active.js.map +1 -0
- package/dist/postgres/probes/connections-active.test.d.ts +2 -0
- package/dist/postgres/probes/connections-active.test.d.ts.map +1 -0
- package/dist/postgres/probes/connections-active.test.js +36 -0
- package/dist/postgres/probes/connections-active.test.js.map +1 -0
- package/dist/postgres/probes/databases-list.d.ts +14 -0
- package/dist/postgres/probes/databases-list.d.ts.map +1 -0
- package/dist/postgres/probes/databases-list.js +34 -0
- package/dist/postgres/probes/databases-list.js.map +1 -0
- package/dist/postgres/probes/databases-list.test.d.ts +2 -0
- package/dist/postgres/probes/databases-list.test.d.ts.map +1 -0
- package/dist/postgres/probes/databases-list.test.js +49 -0
- package/dist/postgres/probes/databases-list.test.js.map +1 -0
- package/dist/postgres/probes/query-slow.d.ts +17 -0
- package/dist/postgres/probes/query-slow.d.ts.map +1 -0
- package/dist/postgres/probes/query-slow.js +37 -0
- package/dist/postgres/probes/query-slow.js.map +1 -0
- package/dist/postgres/probes/query-slow.test.d.ts +2 -0
- package/dist/postgres/probes/query-slow.test.d.ts.map +1 -0
- package/dist/postgres/probes/query-slow.test.js +30 -0
- package/dist/postgres/probes/query-slow.test.js.map +1 -0
- package/dist/proxmox/index.d.ts +3 -0
- package/dist/proxmox/index.d.ts.map +1 -0
- package/dist/proxmox/index.js +23 -0
- package/dist/proxmox/index.js.map +1 -0
- package/dist/proxmox/manifest.d.ts +3 -0
- package/dist/proxmox/manifest.d.ts.map +1 -0
- package/dist/proxmox/manifest.js +75 -0
- package/dist/proxmox/manifest.js.map +1 -0
- package/dist/proxmox/probes/ceph-status.d.ts +36 -0
- package/dist/proxmox/probes/ceph-status.d.ts.map +1 -0
- package/dist/proxmox/probes/ceph-status.js +71 -0
- package/dist/proxmox/probes/ceph-status.js.map +1 -0
- package/dist/proxmox/probes/ceph-status.test.d.ts +2 -0
- package/dist/proxmox/probes/ceph-status.test.d.ts.map +1 -0
- package/dist/proxmox/probes/ceph-status.test.js +115 -0
- package/dist/proxmox/probes/ceph-status.test.js.map +1 -0
- package/dist/proxmox/probes/cluster-config.d.ts +31 -0
- package/dist/proxmox/probes/cluster-config.d.ts.map +1 -0
- package/dist/proxmox/probes/cluster-config.js +72 -0
- package/dist/proxmox/probes/cluster-config.js.map +1 -0
- package/dist/proxmox/probes/cluster-config.test.d.ts +2 -0
- package/dist/proxmox/probes/cluster-config.test.d.ts.map +1 -0
- package/dist/proxmox/probes/cluster-config.test.js +107 -0
- package/dist/proxmox/probes/cluster-config.test.js.map +1 -0
- package/dist/proxmox/probes/ha-status.d.ts +18 -0
- package/dist/proxmox/probes/ha-status.d.ts.map +1 -0
- package/dist/proxmox/probes/ha-status.js +38 -0
- package/dist/proxmox/probes/ha-status.js.map +1 -0
- package/dist/proxmox/probes/ha-status.test.d.ts +2 -0
- package/dist/proxmox/probes/ha-status.test.d.ts.map +1 -0
- package/dist/proxmox/probes/ha-status.test.js +66 -0
- package/dist/proxmox/probes/ha-status.test.js.map +1 -0
- package/dist/proxmox/probes/lvm.d.ts +35 -0
- package/dist/proxmox/probes/lvm.d.ts.map +1 -0
- package/dist/proxmox/probes/lvm.js +75 -0
- package/dist/proxmox/probes/lvm.js.map +1 -0
- package/dist/proxmox/probes/lvm.test.d.ts +2 -0
- package/dist/proxmox/probes/lvm.test.d.ts.map +1 -0
- package/dist/proxmox/probes/lvm.test.js +128 -0
- package/dist/proxmox/probes/lvm.test.js.map +1 -0
- package/dist/proxmox/probes/lxc-config.d.ts +29 -0
- package/dist/proxmox/probes/lxc-config.d.ts.map +1 -0
- package/dist/proxmox/probes/lxc-config.js +67 -0
- package/dist/proxmox/probes/lxc-config.js.map +1 -0
- package/dist/proxmox/probes/lxc-config.test.d.ts +2 -0
- package/dist/proxmox/probes/lxc-config.test.d.ts.map +1 -0
- package/dist/proxmox/probes/lxc-config.test.js +77 -0
- package/dist/proxmox/probes/lxc-config.test.js.map +1 -0
- package/dist/proxmox/probes/lxc-list.d.ts +20 -0
- package/dist/proxmox/probes/lxc-list.d.ts.map +1 -0
- package/dist/proxmox/probes/lxc-list.js +49 -0
- package/dist/proxmox/probes/lxc-list.js.map +1 -0
- package/dist/proxmox/probes/lxc-list.test.d.ts +2 -0
- package/dist/proxmox/probes/lxc-list.test.d.ts.map +1 -0
- package/dist/proxmox/probes/lxc-list.test.js +51 -0
- package/dist/proxmox/probes/lxc-list.test.js.map +1 -0
- package/dist/proxmox/probes/vm-config.d.ts +21 -0
- package/dist/proxmox/probes/vm-config.d.ts.map +1 -0
- package/dist/proxmox/probes/vm-config.js +58 -0
- package/dist/proxmox/probes/vm-config.js.map +1 -0
- package/dist/proxmox/probes/vm-config.test.d.ts +2 -0
- package/dist/proxmox/probes/vm-config.test.d.ts.map +1 -0
- package/dist/proxmox/probes/vm-config.test.js +80 -0
- package/dist/proxmox/probes/vm-config.test.js.map +1 -0
- package/dist/proxmox/probes/vm-locks.d.ts +16 -0
- package/dist/proxmox/probes/vm-locks.d.ts.map +1 -0
- package/dist/proxmox/probes/vm-locks.js +35 -0
- package/dist/proxmox/probes/vm-locks.js.map +1 -0
- package/dist/proxmox/probes/vm-locks.test.d.ts +2 -0
- package/dist/proxmox/probes/vm-locks.test.d.ts.map +1 -0
- package/dist/proxmox/probes/vm-locks.test.js +54 -0
- package/dist/proxmox/probes/vm-locks.test.js.map +1 -0
- package/dist/redis/index.d.ts +3 -0
- package/dist/redis/index.d.ts.map +1 -0
- package/dist/redis/index.js +13 -0
- package/dist/redis/index.js.map +1 -0
- package/dist/redis/manifest.d.ts +3 -0
- package/dist/redis/manifest.d.ts.map +1 -0
- package/dist/redis/manifest.js +51 -0
- package/dist/redis/manifest.js.map +1 -0
- package/dist/redis/probes/info.d.ts +15 -0
- package/dist/redis/probes/info.d.ts.map +1 -0
- package/dist/redis/probes/info.js +32 -0
- package/dist/redis/probes/info.js.map +1 -0
- package/dist/redis/probes/info.test.d.ts +2 -0
- package/dist/redis/probes/info.test.d.ts.map +1 -0
- package/dist/redis/probes/info.test.js +64 -0
- package/dist/redis/probes/info.test.js.map +1 -0
- package/dist/redis/probes/keys-count.d.ts +13 -0
- package/dist/redis/probes/keys-count.d.ts.map +1 -0
- package/dist/redis/probes/keys-count.js +24 -0
- package/dist/redis/probes/keys-count.js.map +1 -0
- package/dist/redis/probes/keys-count.test.d.ts +2 -0
- package/dist/redis/probes/keys-count.test.d.ts.map +1 -0
- package/dist/redis/probes/keys-count.test.js +37 -0
- package/dist/redis/probes/keys-count.test.js.map +1 -0
- package/dist/redis/probes/memory-usage.d.ts +16 -0
- package/dist/redis/probes/memory-usage.d.ts.map +1 -0
- package/dist/redis/probes/memory-usage.js +31 -0
- package/dist/redis/probes/memory-usage.js.map +1 -0
- package/dist/redis/probes/memory-usage.test.d.ts +2 -0
- package/dist/redis/probes/memory-usage.test.d.ts.map +1 -0
- package/dist/redis/probes/memory-usage.test.js +48 -0
- package/dist/redis/probes/memory-usage.test.js.map +1 -0
- package/dist/runbooks/nutanix.d.ts +3 -0
- package/dist/runbooks/nutanix.d.ts.map +1 -0
- package/dist/runbooks/nutanix.js +619 -0
- package/dist/runbooks/nutanix.js.map +1 -0
- package/dist/runbooks/nutanix.test.d.ts +2 -0
- package/dist/runbooks/nutanix.test.d.ts.map +1 -0
- package/dist/runbooks/nutanix.test.js +971 -0
- package/dist/runbooks/nutanix.test.js.map +1 -0
- package/dist/runbooks/proxmox.d.ts +3 -0
- package/dist/runbooks/proxmox.d.ts.map +1 -0
- package/dist/runbooks/proxmox.js +451 -0
- package/dist/runbooks/proxmox.js.map +1 -0
- package/dist/runbooks/proxmox.test.d.ts +2 -0
- package/dist/runbooks/proxmox.test.d.ts.map +1 -0
- package/dist/runbooks/proxmox.test.js +700 -0
- package/dist/runbooks/proxmox.test.js.map +1 -0
- package/dist/signatures.d.ts +2 -0
- package/dist/signatures.d.ts.map +1 -0
- package/dist/signatures.js +2 -0
- package/dist/signatures.js.map +1 -0
- package/dist/types.d.ts +53 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/validation.d.ts +6 -1
- package/dist/validation.d.ts.map +1 -1
- package/dist/validation.js +10 -1
- package/dist/validation.js.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +60 -6
- package/src/integrations/citrix.test.ts +592 -0
- package/src/integrations/citrix.ts +557 -0
- package/src/integrations/graph.test.ts +478 -0
- package/src/integrations/graph.ts +413 -0
- package/src/integrations/httpbin.ts +72 -0
- package/src/integrations/nutanix.test.ts +1508 -0
- package/src/integrations/nutanix.ts +1460 -0
- package/src/integrations/proxmox.test.ts +1020 -0
- package/src/integrations/proxmox.ts +989 -0
- package/src/integrations/servicenow.test.ts +314 -0
- package/src/integrations/servicenow.ts +285 -0
- package/src/integrations/splunk.test.ts +440 -0
- package/src/integrations/splunk.ts +356 -0
- package/src/mysql/index.ts +14 -0
- package/src/mysql/manifest.ts +70 -0
- package/src/mysql/probes/databases-list.test.ts +62 -0
- package/src/mysql/probes/databases-list.ts +45 -0
- package/src/mysql/probes/processlist.test.ts +47 -0
- package/src/mysql/probes/processlist.ts +55 -0
- package/src/mysql/probes/status.test.ts +50 -0
- package/src/mysql/probes/status.ts +56 -0
- package/src/nginx/index.ts +14 -0
- package/src/nginx/manifest.ts +69 -0
- package/src/nginx/probes/access-log-tail.test.ts +51 -0
- package/src/nginx/probes/access-log-tail.ts +23 -0
- package/src/nginx/probes/config-test.test.ts +47 -0
- package/src/nginx/probes/config-test.ts +24 -0
- package/src/nginx/probes/error-log-tail.test.ts +44 -0
- package/src/nginx/probes/error-log-tail.ts +23 -0
- package/src/postgres/index.ts +14 -0
- package/src/postgres/manifest.ts +91 -0
- package/src/postgres/probes/connections-active.test.ts +42 -0
- package/src/postgres/probes/connections-active.ts +55 -0
- package/src/postgres/probes/databases-list.test.ts +57 -0
- package/src/postgres/probes/databases-list.ts +49 -0
- package/src/postgres/probes/query-slow.test.ts +37 -0
- package/src/postgres/probes/query-slow.ts +55 -0
- package/src/proxmox/index.ts +24 -0
- package/src/proxmox/manifest.ts +76 -0
- package/src/proxmox/probes/ceph-status.test.ts +126 -0
- package/src/proxmox/probes/ceph-status.ts +116 -0
- package/src/proxmox/probes/cluster-config.test.ts +118 -0
- package/src/proxmox/probes/cluster-config.ts +97 -0
- package/src/proxmox/probes/ha-status.test.ts +76 -0
- package/src/proxmox/probes/ha-status.ts +56 -0
- package/src/proxmox/probes/lvm.test.ts +140 -0
- package/src/proxmox/probes/lvm.ts +121 -0
- package/src/proxmox/probes/lxc-config.test.ts +89 -0
- package/src/proxmox/probes/lxc-config.ts +90 -0
- package/src/proxmox/probes/lxc-list.test.ts +60 -0
- package/src/proxmox/probes/lxc-list.ts +67 -0
- package/src/proxmox/probes/vm-config.test.ts +93 -0
- package/src/proxmox/probes/vm-config.ts +77 -0
- package/src/proxmox/probes/vm-locks.test.ts +63 -0
- package/src/proxmox/probes/vm-locks.ts +49 -0
- package/src/redis/index.ts +14 -0
- package/src/redis/manifest.ts +52 -0
- package/src/redis/probes/info.test.ts +73 -0
- package/src/redis/probes/info.ts +46 -0
- package/src/redis/probes/keys-count.test.ts +44 -0
- package/src/redis/probes/keys-count.ts +38 -0
- package/src/redis/probes/memory-usage.test.ts +54 -0
- package/src/redis/probes/memory-usage.ts +46 -0
- package/src/runbooks/nutanix.test.ts +1138 -0
- package/src/runbooks/nutanix.ts +941 -0
- package/src/runbooks/proxmox.test.ts +838 -0
- package/src/runbooks/proxmox.ts +626 -0
- package/src/signatures.ts +1 -0
- package/src/types.ts +62 -0
- package/src/validation.ts +21 -1
- package/tsconfig.tsbuildinfo +1 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { accessLogTail, parseLogTail } from './access-log-tail.js';
|
|
3
|
+
const SAMPLE_LOG = `192.168.1.1 - - [15/Jan/2024:10:30:00 +0000] "GET / HTTP/1.1" 200 612
|
|
4
|
+
192.168.1.2 - - [15/Jan/2024:10:30:01 +0000] "GET /api HTTP/1.1" 200 1234
|
|
5
|
+
192.168.1.1 - - [15/Jan/2024:10:30:02 +0000] "POST /login HTTP/1.1" 302 0
|
|
6
|
+
`;
|
|
7
|
+
describe('parseLogTail', () => {
|
|
8
|
+
it('parses log lines correctly', () => {
|
|
9
|
+
const result = parseLogTail('/var/log/nginx/access.log', SAMPLE_LOG);
|
|
10
|
+
expect(result.logPath).toBe('/var/log/nginx/access.log');
|
|
11
|
+
expect(result.lineCount).toBe(3);
|
|
12
|
+
expect(result.lines[0]).toContain('GET / HTTP/1.1');
|
|
13
|
+
});
|
|
14
|
+
it('handles empty log', () => {
|
|
15
|
+
const result = parseLogTail('/var/log/nginx/access.log', '');
|
|
16
|
+
expect(result.lineCount).toBe(0);
|
|
17
|
+
expect(result.lines).toEqual([]);
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
describe('accessLogTail handler', () => {
|
|
21
|
+
it('uses default path and line count', async () => {
|
|
22
|
+
const mockExec = async (cmd, args) => {
|
|
23
|
+
expect(cmd).toBe('tail');
|
|
24
|
+
expect(args).toEqual(['-n', '100', '/var/log/nginx/access.log']);
|
|
25
|
+
return SAMPLE_LOG;
|
|
26
|
+
};
|
|
27
|
+
const result = (await accessLogTail(undefined, mockExec));
|
|
28
|
+
expect(result.lineCount).toBe(3);
|
|
29
|
+
});
|
|
30
|
+
it('uses custom path and lines', async () => {
|
|
31
|
+
const mockExec = async (cmd, args) => {
|
|
32
|
+
expect(cmd).toBe('tail');
|
|
33
|
+
expect(args).toEqual(['-n', '50', '/custom/access.log']);
|
|
34
|
+
return SAMPLE_LOG;
|
|
35
|
+
};
|
|
36
|
+
const result = (await accessLogTail({ logPath: '/custom/access.log', lines: 50 }, mockExec));
|
|
37
|
+
expect(result.logPath).toBe('/custom/access.log');
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
//# sourceMappingURL=access-log-tail.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"access-log-tail.test.js","sourceRoot":"","sources":["../../../src/nginx/probes/access-log-tail.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAG9C,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEnE,MAAM,UAAU,GAAG;;;CAGlB,CAAC;AAEF,QAAQ,CAAC,cAAc,EAAE,GAAG,EAAE;IAC5B,EAAE,CAAC,4BAA4B,EAAE,GAAG,EAAE;QACpC,MAAM,MAAM,GAAG,YAAY,CAAC,2BAA2B,EAAE,UAAU,CAAC,CAAC;QACrE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;QACzD,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACjC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;IACtD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mBAAmB,EAAE,GAAG,EAAE;QAC3B,MAAM,MAAM,GAAG,YAAY,CAAC,2BAA2B,EAAE,EAAE,CAAC,CAAC;QAC7D,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACjC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACnC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,uBAAuB,EAAE,GAAG,EAAE;IACrC,EAAE,CAAC,kCAAkC,EAAE,KAAK,IAAI,EAAE;QAChD,MAAM,QAAQ,GAAW,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;YAC3C,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACzB,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,2BAA2B,CAAC,CAAC,CAAC;YACjE,OAAO,UAAU,CAAC;QACpB,CAAC,CAAC;QAEF,MAAM,MAAM,GAAG,CAAC,MAAM,aAAa,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAwB,CAAC;QACjF,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACnC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4BAA4B,EAAE,KAAK,IAAI,EAAE;QAC1C,MAAM,QAAQ,GAAW,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;YAC3C,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACzB,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,oBAAoB,CAAC,CAAC,CAAC;YACzD,OAAO,UAAU,CAAC;QACpB,CAAC,CAAC;QAEF,MAAM,MAAM,GAAG,CAAC,MAAM,aAAa,CACjC,EAAE,OAAO,EAAE,oBAAoB,EAAE,KAAK,EAAE,EAAE,EAAE,EAC5C,QAAQ,CACT,CAAwB,CAAC;QAC1B,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ProbeHandler } from '../../types.js';
|
|
2
|
+
export interface ConfigTestResult {
|
|
3
|
+
valid: boolean;
|
|
4
|
+
output: string;
|
|
5
|
+
}
|
|
6
|
+
export declare const configTest: ProbeHandler;
|
|
7
|
+
export declare function parseConfigTest(output: string, valid: boolean): ConfigTestResult;
|
|
8
|
+
//# sourceMappingURL=config-test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-test.d.ts","sourceRoot":"","sources":["../../../src/nginx/probes/config-test.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEnD,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,eAAO,MAAM,UAAU,EAAE,YASxB,CAAC;AAEF,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,gBAAgB,CAKhF"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export const configTest = async (_params, exec) => {
|
|
2
|
+
try {
|
|
3
|
+
const stdout = await exec('nginx', ['-t']);
|
|
4
|
+
return parseConfigTest(stdout, true);
|
|
5
|
+
}
|
|
6
|
+
catch (err) {
|
|
7
|
+
// nginx -t writes to stderr and exits non-zero on failure
|
|
8
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
9
|
+
return parseConfigTest(message, false);
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
export function parseConfigTest(output, valid) {
|
|
13
|
+
return {
|
|
14
|
+
valid,
|
|
15
|
+
output: output.trim(),
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=config-test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-test.js","sourceRoot":"","sources":["../../../src/nginx/probes/config-test.ts"],"names":[],"mappings":"AAOA,MAAM,CAAC,MAAM,UAAU,GAAiB,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE;IAC9D,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;QAC3C,OAAO,eAAe,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IACvC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,0DAA0D;QAC1D,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACjE,OAAO,eAAe,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IACzC,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,UAAU,eAAe,CAAC,MAAc,EAAE,KAAc;IAC5D,OAAO;QACL,KAAK;QACL,MAAM,EAAE,MAAM,CAAC,IAAI,EAAE;KACtB,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-test.test.d.ts","sourceRoot":"","sources":["../../../src/nginx/probes/config-test.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { configTest, parseConfigTest } from './config-test.js';
|
|
3
|
+
const SUCCESS_OUTPUT = 'nginx: the configuration file /etc/nginx/nginx.conf syntax is ok\nnginx: configuration file /etc/nginx/nginx.conf test is successful';
|
|
4
|
+
describe('parseConfigTest', () => {
|
|
5
|
+
it('parses successful config test', () => {
|
|
6
|
+
const result = parseConfigTest(SUCCESS_OUTPUT, true);
|
|
7
|
+
expect(result.valid).toBe(true);
|
|
8
|
+
expect(result.output).toContain('syntax is ok');
|
|
9
|
+
});
|
|
10
|
+
it('parses failed config test', () => {
|
|
11
|
+
const result = parseConfigTest('nginx: [emerg] unexpected "}" in /etc/nginx/nginx.conf:42', false);
|
|
12
|
+
expect(result.valid).toBe(false);
|
|
13
|
+
expect(result.output).toContain('unexpected');
|
|
14
|
+
});
|
|
15
|
+
});
|
|
16
|
+
describe('configTest handler', () => {
|
|
17
|
+
it('calls nginx -t and returns success', async () => {
|
|
18
|
+
const mockExec = async (cmd, args) => {
|
|
19
|
+
expect(cmd).toBe('nginx');
|
|
20
|
+
expect(args).toEqual(['-t']);
|
|
21
|
+
return SUCCESS_OUTPUT;
|
|
22
|
+
};
|
|
23
|
+
const result = (await configTest(undefined, mockExec));
|
|
24
|
+
expect(result.valid).toBe(true);
|
|
25
|
+
});
|
|
26
|
+
it('handles config error gracefully', async () => {
|
|
27
|
+
const mockExec = async () => {
|
|
28
|
+
throw new Error('nginx: [emerg] unknown directive');
|
|
29
|
+
};
|
|
30
|
+
const result = (await configTest(undefined, mockExec));
|
|
31
|
+
expect(result.valid).toBe(false);
|
|
32
|
+
expect(result.output).toContain('unknown directive');
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
//# sourceMappingURL=config-test.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-test.test.js","sourceRoot":"","sources":["../../../src/nginx/probes/config-test.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAG9C,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAE/D,MAAM,cAAc,GAClB,sIAAsI,CAAC;AAEzI,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;IAC/B,EAAE,CAAC,+BAA+B,EAAE,GAAG,EAAE;QACvC,MAAM,MAAM,GAAG,eAAe,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC;QACrD,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAChC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2BAA2B,EAAE,GAAG,EAAE;QACnC,MAAM,MAAM,GAAG,eAAe,CAC5B,2DAA2D,EAC3D,KAAK,CACN,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACjC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;IAChD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,oBAAoB,EAAE,GAAG,EAAE;IAClC,EAAE,CAAC,oCAAoC,EAAE,KAAK,IAAI,EAAE;QAClD,MAAM,QAAQ,GAAW,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;YAC3C,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAC1B,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;YAC7B,OAAO,cAAc,CAAC;QACxB,CAAC,CAAC;QAEF,MAAM,MAAM,GAAG,CAAC,MAAM,UAAU,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAqB,CAAC;QAC3E,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAClC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iCAAiC,EAAE,KAAK,IAAI,EAAE;QAC/C,MAAM,QAAQ,GAAW,KAAK,IAAI,EAAE;YAClC,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;QACtD,CAAC,CAAC;QAEF,MAAM,MAAM,GAAG,CAAC,MAAM,UAAU,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAqB,CAAC;QAC3E,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACjC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAC;IACvD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ProbeHandler } from '../../types.js';
|
|
2
|
+
export interface ErrorLogTailResult {
|
|
3
|
+
logPath: string;
|
|
4
|
+
lines: string[];
|
|
5
|
+
lineCount: number;
|
|
6
|
+
}
|
|
7
|
+
export declare const errorLogTail: ProbeHandler;
|
|
8
|
+
export declare function parseErrorLogTail(logPath: string, stdout: string): ErrorLogTailResult;
|
|
9
|
+
//# sourceMappingURL=error-log-tail.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-log-tail.d.ts","sourceRoot":"","sources":["../../../src/nginx/probes/error-log-tail.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEnD,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,eAAO,MAAM,YAAY,EAAE,YAM1B,CAAC;AAEF,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,kBAAkB,CAMrF"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export const errorLogTail = async (params, exec) => {
|
|
2
|
+
const logPath = params?.logPath ?? '/var/log/nginx/error.log';
|
|
3
|
+
const lines = params?.lines ?? 100;
|
|
4
|
+
const stdout = await exec('tail', ['-n', String(lines), logPath]);
|
|
5
|
+
return parseErrorLogTail(logPath, stdout);
|
|
6
|
+
};
|
|
7
|
+
export function parseErrorLogTail(logPath, stdout) {
|
|
8
|
+
const lines = stdout.split('\n');
|
|
9
|
+
if (lines.length > 0 && lines[lines.length - 1] === '') {
|
|
10
|
+
lines.pop();
|
|
11
|
+
}
|
|
12
|
+
return { logPath, lines, lineCount: lines.length };
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=error-log-tail.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-log-tail.js","sourceRoot":"","sources":["../../../src/nginx/probes/error-log-tail.ts"],"names":[],"mappings":"AAQA,MAAM,CAAC,MAAM,YAAY,GAAiB,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE;IAC/D,MAAM,OAAO,GAAI,MAAM,EAAE,OAAkB,IAAI,0BAA0B,CAAC;IAC1E,MAAM,KAAK,GAAI,MAAM,EAAE,KAAgB,IAAI,GAAG,CAAC;IAE/C,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;IAClE,OAAO,iBAAiB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;AAC5C,CAAC,CAAC;AAEF,MAAM,UAAU,iBAAiB,CAAC,OAAe,EAAE,MAAc;IAC/D,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACjC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC;QACvD,KAAK,CAAC,GAAG,EAAE,CAAC;IACd,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC;AACrD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-log-tail.test.d.ts","sourceRoot":"","sources":["../../../src/nginx/probes/error-log-tail.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { errorLogTail, parseErrorLogTail } from './error-log-tail.js';
|
|
3
|
+
const SAMPLE_ERROR_LOG = `2024/01/15 10:30:00 [error] 1234#1234: *5 open() "/usr/share/nginx/html/favicon.ico" failed (2: No such file or directory)
|
|
4
|
+
2024/01/15 10:30:01 [warn] 1234#1234: conflicting server name "example.com"
|
|
5
|
+
`;
|
|
6
|
+
describe('parseErrorLogTail', () => {
|
|
7
|
+
it('parses error log lines', () => {
|
|
8
|
+
const result = parseErrorLogTail('/var/log/nginx/error.log', SAMPLE_ERROR_LOG);
|
|
9
|
+
expect(result.logPath).toBe('/var/log/nginx/error.log');
|
|
10
|
+
expect(result.lineCount).toBe(2);
|
|
11
|
+
expect(result.lines[0]).toContain('[error]');
|
|
12
|
+
});
|
|
13
|
+
});
|
|
14
|
+
describe('errorLogTail handler', () => {
|
|
15
|
+
it('uses default path and line count', async () => {
|
|
16
|
+
const mockExec = async (cmd, args) => {
|
|
17
|
+
expect(cmd).toBe('tail');
|
|
18
|
+
expect(args).toEqual(['-n', '100', '/var/log/nginx/error.log']);
|
|
19
|
+
return SAMPLE_ERROR_LOG;
|
|
20
|
+
};
|
|
21
|
+
const result = (await errorLogTail(undefined, mockExec));
|
|
22
|
+
expect(result.lineCount).toBe(2);
|
|
23
|
+
});
|
|
24
|
+
it('uses custom parameters', async () => {
|
|
25
|
+
const mockExec = async (cmd, args) => {
|
|
26
|
+
expect(cmd).toBe('tail');
|
|
27
|
+
expect(args).toEqual(['-n', '25', '/custom/error.log']);
|
|
28
|
+
return SAMPLE_ERROR_LOG;
|
|
29
|
+
};
|
|
30
|
+
const result = (await errorLogTail({ logPath: '/custom/error.log', lines: 25 }, mockExec));
|
|
31
|
+
expect(result.logPath).toBe('/custom/error.log');
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
//# sourceMappingURL=error-log-tail.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-log-tail.test.js","sourceRoot":"","sources":["../../../src/nginx/probes/error-log-tail.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAG9C,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAEtE,MAAM,gBAAgB,GAAG;;CAExB,CAAC;AAEF,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;IACjC,EAAE,CAAC,wBAAwB,EAAE,GAAG,EAAE;QAChC,MAAM,MAAM,GAAG,iBAAiB,CAAC,0BAA0B,EAAE,gBAAgB,CAAC,CAAC;QAC/E,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;QACxD,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACjC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,sBAAsB,EAAE,GAAG,EAAE;IACpC,EAAE,CAAC,kCAAkC,EAAE,KAAK,IAAI,EAAE;QAChD,MAAM,QAAQ,GAAW,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;YAC3C,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACzB,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,0BAA0B,CAAC,CAAC,CAAC;YAChE,OAAO,gBAAgB,CAAC;QAC1B,CAAC,CAAC;QAEF,MAAM,MAAM,GAAG,CAAC,MAAM,YAAY,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAuB,CAAC;QAC/E,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACnC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wBAAwB,EAAE,KAAK,IAAI,EAAE;QACtC,MAAM,QAAQ,GAAW,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;YAC3C,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACzB,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,mBAAmB,CAAC,CAAC,CAAC;YACxD,OAAO,gBAAgB,CAAC;QAC1B,CAAC,CAAC;QAEF,MAAM,MAAM,GAAG,CAAC,MAAM,YAAY,CAChC,EAAE,OAAO,EAAE,mBAAmB,EAAE,KAAK,EAAE,EAAE,EAAE,EAC3C,QAAQ,CACT,CAAuB,CAAC;QACzB,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;IACnD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/postgres/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAMxC,eAAO,MAAM,YAAY,EAAE,IAO1B,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { postgresManifest } from './manifest.js';
|
|
2
|
+
import { connectionsActive } from './probes/connections-active.js';
|
|
3
|
+
import { databasesList } from './probes/databases-list.js';
|
|
4
|
+
import { querySlow } from './probes/query-slow.js';
|
|
5
|
+
export const postgresPack = {
|
|
6
|
+
manifest: postgresManifest,
|
|
7
|
+
handlers: {
|
|
8
|
+
'postgres.databases.list': databasesList,
|
|
9
|
+
'postgres.connections.active': connectionsActive,
|
|
10
|
+
'postgres.query.slow': querySlow,
|
|
11
|
+
},
|
|
12
|
+
};
|
|
13
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/postgres/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AACnE,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAEnD,MAAM,CAAC,MAAM,YAAY,GAAS;IAChC,QAAQ,EAAE,gBAAgB;IAC1B,QAAQ,EAAE;QACR,yBAAyB,EAAE,aAAa;QACxC,6BAA6B,EAAE,iBAAiB;QAChD,qBAAqB,EAAE,SAAS;KACjC;CACF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../src/postgres/manifest.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAElD,eAAO,MAAM,gBAAgB,EAAE,YAwF9B,CAAC"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
export const postgresManifest = {
|
|
2
|
+
name: 'postgres',
|
|
3
|
+
version: '0.1.0',
|
|
4
|
+
description: 'PostgreSQL probes: database listing, active connections, slow queries',
|
|
5
|
+
requires: {
|
|
6
|
+
groups: [],
|
|
7
|
+
files: [],
|
|
8
|
+
commands: ['psql'],
|
|
9
|
+
},
|
|
10
|
+
probes: [
|
|
11
|
+
{
|
|
12
|
+
name: 'databases.list',
|
|
13
|
+
description: 'List all PostgreSQL databases with sizes',
|
|
14
|
+
capability: 'observe',
|
|
15
|
+
params: {
|
|
16
|
+
host: {
|
|
17
|
+
type: 'string',
|
|
18
|
+
description: 'Database host',
|
|
19
|
+
required: false,
|
|
20
|
+
default: 'localhost',
|
|
21
|
+
},
|
|
22
|
+
port: { type: 'number', description: 'Database port', required: false, default: 5432 },
|
|
23
|
+
user: {
|
|
24
|
+
type: 'string',
|
|
25
|
+
description: 'Database user',
|
|
26
|
+
required: false,
|
|
27
|
+
default: 'postgres',
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
timeout: 15_000,
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
name: 'connections.active',
|
|
34
|
+
description: 'List active PostgreSQL connections',
|
|
35
|
+
capability: 'observe',
|
|
36
|
+
params: {
|
|
37
|
+
host: {
|
|
38
|
+
type: 'string',
|
|
39
|
+
description: 'Database host',
|
|
40
|
+
required: false,
|
|
41
|
+
default: 'localhost',
|
|
42
|
+
},
|
|
43
|
+
port: { type: 'number', description: 'Database port', required: false, default: 5432 },
|
|
44
|
+
user: {
|
|
45
|
+
type: 'string',
|
|
46
|
+
description: 'Database user',
|
|
47
|
+
required: false,
|
|
48
|
+
default: 'postgres',
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
timeout: 15_000,
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
name: 'query.slow',
|
|
55
|
+
description: 'List currently running slow queries (> threshold)',
|
|
56
|
+
capability: 'observe',
|
|
57
|
+
params: {
|
|
58
|
+
host: {
|
|
59
|
+
type: 'string',
|
|
60
|
+
description: 'Database host',
|
|
61
|
+
required: false,
|
|
62
|
+
default: 'localhost',
|
|
63
|
+
},
|
|
64
|
+
port: { type: 'number', description: 'Database port', required: false, default: 5432 },
|
|
65
|
+
user: {
|
|
66
|
+
type: 'string',
|
|
67
|
+
description: 'Database user',
|
|
68
|
+
required: false,
|
|
69
|
+
default: 'postgres',
|
|
70
|
+
},
|
|
71
|
+
thresholdMs: {
|
|
72
|
+
type: 'number',
|
|
73
|
+
description: 'Slow query threshold in ms',
|
|
74
|
+
required: false,
|
|
75
|
+
default: 1000,
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
timeout: 15_000,
|
|
79
|
+
},
|
|
80
|
+
],
|
|
81
|
+
runbook: {
|
|
82
|
+
category: 'postgres',
|
|
83
|
+
probes: ['databases.list', 'connections.active', 'query.slow'],
|
|
84
|
+
parallel: true,
|
|
85
|
+
},
|
|
86
|
+
detect: {
|
|
87
|
+
commands: ['psql'],
|
|
88
|
+
},
|
|
89
|
+
};
|
|
90
|
+
//# sourceMappingURL=manifest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../src/postgres/manifest.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,gBAAgB,GAAiB;IAC5C,IAAI,EAAE,UAAU;IAChB,OAAO,EAAE,OAAO;IAChB,WAAW,EAAE,uEAAuE;IACpF,QAAQ,EAAE;QACR,MAAM,EAAE,EAAE;QACV,KAAK,EAAE,EAAE;QACT,QAAQ,EAAE,CAAC,MAAM,CAAC;KACnB;IACD,MAAM,EAAE;QACN;YACE,IAAI,EAAE,gBAAgB;YACtB,WAAW,EAAE,0CAA0C;YACvD,UAAU,EAAE,SAAS;YACrB,MAAM,EAAE;gBACN,IAAI,EAAE;oBACJ,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,eAAe;oBAC5B,QAAQ,EAAE,KAAK;oBACf,OAAO,EAAE,WAAW;iBACrB;gBACD,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,eAAe,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE;gBACtF,IAAI,EAAE;oBACJ,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,eAAe;oBAC5B,QAAQ,EAAE,KAAK;oBACf,OAAO,EAAE,UAAU;iBACpB;aACF;YACD,OAAO,EAAE,MAAM;SAChB;QACD;YACE,IAAI,EAAE,oBAAoB;YAC1B,WAAW,EAAE,oCAAoC;YACjD,UAAU,EAAE,SAAS;YACrB,MAAM,EAAE;gBACN,IAAI,EAAE;oBACJ,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,eAAe;oBAC5B,QAAQ,EAAE,KAAK;oBACf,OAAO,EAAE,WAAW;iBACrB;gBACD,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,eAAe,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE;gBACtF,IAAI,EAAE;oBACJ,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,eAAe;oBAC5B,QAAQ,EAAE,KAAK;oBACf,OAAO,EAAE,UAAU;iBACpB;aACF;YACD,OAAO,EAAE,MAAM;SAChB;QACD;YACE,IAAI,EAAE,YAAY;YAClB,WAAW,EAAE,mDAAmD;YAChE,UAAU,EAAE,SAAS;YACrB,MAAM,EAAE;gBACN,IAAI,EAAE;oBACJ,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,eAAe;oBAC5B,QAAQ,EAAE,KAAK;oBACf,OAAO,EAAE,WAAW;iBACrB;gBACD,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,eAAe,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE;gBACtF,IAAI,EAAE;oBACJ,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,eAAe;oBAC5B,QAAQ,EAAE,KAAK;oBACf,OAAO,EAAE,UAAU;iBACpB;gBACD,WAAW,EAAE;oBACX,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,4BAA4B;oBACzC,QAAQ,EAAE,KAAK;oBACf,OAAO,EAAE,IAAI;iBACd;aACF;YACD,OAAO,EAAE,MAAM;SAChB;KACF;IACD,OAAO,EAAE;QACP,QAAQ,EAAE,UAAU;QACpB,MAAM,EAAE,CAAC,gBAAgB,EAAE,oBAAoB,EAAE,YAAY,CAAC;QAC9D,QAAQ,EAAE,IAAI;KACf;IACD,MAAM,EAAE;QACN,QAAQ,EAAE,CAAC,MAAM,CAAC;KACnB;CACF,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { ProbeHandler } from '../../types.js';
|
|
2
|
+
export interface ConnectionInfo {
|
|
3
|
+
pid: number;
|
|
4
|
+
database: string;
|
|
5
|
+
user: string;
|
|
6
|
+
clientAddr: string;
|
|
7
|
+
state: string;
|
|
8
|
+
query: string;
|
|
9
|
+
backendStart: string;
|
|
10
|
+
}
|
|
11
|
+
export interface ConnectionsActiveResult {
|
|
12
|
+
connections: ConnectionInfo[];
|
|
13
|
+
total: number;
|
|
14
|
+
}
|
|
15
|
+
export declare const connectionsActive: ProbeHandler;
|
|
16
|
+
export declare function parseConnectionsActive(stdout: string): ConnectionsActiveResult;
|
|
17
|
+
//# sourceMappingURL=connections-active.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connections-active.d.ts","sourceRoot":"","sources":["../../../src/postgres/probes/connections-active.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEnD,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,uBAAuB;IACtC,WAAW,EAAE,cAAc,EAAE,CAAC;IAC9B,KAAK,EAAE,MAAM,CAAC;CACf;AAED,eAAO,MAAM,iBAAiB,EAAE,YAoB/B,CAAC;AAEF,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,GAAG,uBAAuB,CAe9E"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export const connectionsActive = async (params, exec) => {
|
|
2
|
+
const host = params?.host ?? 'localhost';
|
|
3
|
+
const port = String(params?.port ?? 5432);
|
|
4
|
+
const user = params?.user ?? 'postgres';
|
|
5
|
+
const stdout = await exec('psql', [
|
|
6
|
+
'-h',
|
|
7
|
+
host,
|
|
8
|
+
'-p',
|
|
9
|
+
port,
|
|
10
|
+
'-U',
|
|
11
|
+
user,
|
|
12
|
+
'-t',
|
|
13
|
+
'-A',
|
|
14
|
+
'-F',
|
|
15
|
+
'\t',
|
|
16
|
+
'-c',
|
|
17
|
+
'SELECT pid, datname, usename, client_addr, state, LEFT(query, 200), backend_start FROM pg_stat_activity WHERE state IS NOT NULL AND pid <> pg_backend_pid() ORDER BY backend_start DESC',
|
|
18
|
+
]);
|
|
19
|
+
return parseConnectionsActive(stdout);
|
|
20
|
+
};
|
|
21
|
+
export function parseConnectionsActive(stdout) {
|
|
22
|
+
const lines = stdout.trim().split('\n').filter(Boolean);
|
|
23
|
+
const connections = lines.map((line) => {
|
|
24
|
+
const parts = line.split('\t');
|
|
25
|
+
return {
|
|
26
|
+
pid: Number(parts[0]) || 0,
|
|
27
|
+
database: parts[1] ?? '',
|
|
28
|
+
user: parts[2] ?? '',
|
|
29
|
+
clientAddr: parts[3] ?? '',
|
|
30
|
+
state: parts[4] ?? '',
|
|
31
|
+
query: parts[5] ?? '',
|
|
32
|
+
backendStart: parts[6] ?? '',
|
|
33
|
+
};
|
|
34
|
+
});
|
|
35
|
+
return { connections, total: connections.length };
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=connections-active.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connections-active.js","sourceRoot":"","sources":["../../../src/postgres/probes/connections-active.ts"],"names":[],"mappings":"AAiBA,MAAM,CAAC,MAAM,iBAAiB,GAAiB,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE;IACpE,MAAM,IAAI,GAAI,MAAM,EAAE,IAAe,IAAI,WAAW,CAAC;IACrD,MAAM,IAAI,GAAG,MAAM,CAAE,MAAM,EAAE,IAAe,IAAI,IAAI,CAAC,CAAC;IACtD,MAAM,IAAI,GAAI,MAAM,EAAE,IAAe,IAAI,UAAU,CAAC;IAEpD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,EAAE;QAChC,IAAI;QACJ,IAAI;QACJ,IAAI;QACJ,IAAI;QACJ,IAAI;QACJ,IAAI;QACJ,IAAI;QACJ,IAAI;QACJ,IAAI;QACJ,IAAI;QACJ,IAAI;QACJ,yLAAyL;KAC1L,CAAC,CAAC;IACH,OAAO,sBAAsB,CAAC,MAAM,CAAC,CAAC;AACxC,CAAC,CAAC;AAEF,MAAM,UAAU,sBAAsB,CAAC,MAAc;IACnD,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACxD,MAAM,WAAW,GAAqB,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QACvD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC/B,OAAO;YACL,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YAC1B,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE;YACxB,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE;YACpB,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE;YAC1B,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE;YACrB,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE;YACrB,YAAY,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE;SAC7B,CAAC;IACJ,CAAC,CAAC,CAAC;IACH,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,CAAC;AACpD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connections-active.test.d.ts","sourceRoot":"","sources":["../../../src/postgres/probes/connections-active.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { connectionsActive, parseConnectionsActive } from './connections-active.js';
|
|
3
|
+
const SAMPLE_OUTPUT = `1234\tmyapp\tappuser\t192.168.1.10\tactive\tSELECT * FROM users\t2024-01-15 10:30:00
|
|
4
|
+
5678\tpostgres\tpostgres\t\tidle\t\t2024-01-15 09:00:00`;
|
|
5
|
+
describe('parseConnectionsActive', () => {
|
|
6
|
+
it('parses connections output', () => {
|
|
7
|
+
const result = parseConnectionsActive(SAMPLE_OUTPUT);
|
|
8
|
+
expect(result.total).toBe(2);
|
|
9
|
+
expect(result.connections[0]).toEqual({
|
|
10
|
+
pid: 1234,
|
|
11
|
+
database: 'myapp',
|
|
12
|
+
user: 'appuser',
|
|
13
|
+
clientAddr: '192.168.1.10',
|
|
14
|
+
state: 'active',
|
|
15
|
+
query: 'SELECT * FROM users',
|
|
16
|
+
backendStart: '2024-01-15 10:30:00',
|
|
17
|
+
});
|
|
18
|
+
});
|
|
19
|
+
it('handles empty output', () => {
|
|
20
|
+
const result = parseConnectionsActive('');
|
|
21
|
+
expect(result.total).toBe(0);
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
describe('connectionsActive handler', () => {
|
|
25
|
+
it('calls psql with correct args', async () => {
|
|
26
|
+
const mockExec = async (cmd, args) => {
|
|
27
|
+
expect(cmd).toBe('psql');
|
|
28
|
+
expect(args).toContain('-t');
|
|
29
|
+
expect(args).toContain('-A');
|
|
30
|
+
return SAMPLE_OUTPUT;
|
|
31
|
+
};
|
|
32
|
+
const result = (await connectionsActive(undefined, mockExec));
|
|
33
|
+
expect(result.total).toBe(2);
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
//# sourceMappingURL=connections-active.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connections-active.test.js","sourceRoot":"","sources":["../../../src/postgres/probes/connections-active.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAG9C,OAAO,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AAEpF,MAAM,aAAa,GAAG;wDACkC,CAAC;AAEzD,QAAQ,CAAC,wBAAwB,EAAE,GAAG,EAAE;IACtC,EAAE,CAAC,2BAA2B,EAAE,GAAG,EAAE;QACnC,MAAM,MAAM,GAAG,sBAAsB,CAAC,aAAa,CAAC,CAAC;QACrD,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC7B,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;YACpC,GAAG,EAAE,IAAI;YACT,QAAQ,EAAE,OAAO;YACjB,IAAI,EAAE,SAAS;YACf,UAAU,EAAE,cAAc;YAC1B,KAAK,EAAE,QAAQ;YACf,KAAK,EAAE,qBAAqB;YAC5B,YAAY,EAAE,qBAAqB;SACpC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sBAAsB,EAAE,GAAG,EAAE;QAC9B,MAAM,MAAM,GAAG,sBAAsB,CAAC,EAAE,CAAC,CAAC;QAC1C,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC/B,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,2BAA2B,EAAE,GAAG,EAAE;IACzC,EAAE,CAAC,8BAA8B,EAAE,KAAK,IAAI,EAAE;QAC5C,MAAM,QAAQ,GAAW,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;YAC3C,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACzB,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;YAC7B,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;YAC7B,OAAO,aAAa,CAAC;QACvB,CAAC,CAAC;QAEF,MAAM,MAAM,GAAG,CAAC,MAAM,iBAAiB,CAAC,SAAS,EAAE,QAAQ,CAAC,CAA4B,CAAC;QACzF,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC/B,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ProbeHandler } from '../../types.js';
|
|
2
|
+
export interface DatabaseInfo {
|
|
3
|
+
name: string;
|
|
4
|
+
owner: string;
|
|
5
|
+
encoding: string;
|
|
6
|
+
sizePretty: string;
|
|
7
|
+
}
|
|
8
|
+
export interface DatabasesListResult {
|
|
9
|
+
databases: DatabaseInfo[];
|
|
10
|
+
count: number;
|
|
11
|
+
}
|
|
12
|
+
export declare const databasesList: ProbeHandler;
|
|
13
|
+
export declare function parseDatabasesList(stdout: string): DatabasesListResult;
|
|
14
|
+
//# sourceMappingURL=databases-list.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"databases-list.d.ts","sourceRoot":"","sources":["../../../src/postgres/probes/databases-list.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEnD,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,YAAY,EAAE,CAAC;IAC1B,KAAK,EAAE,MAAM,CAAC;CACf;AAED,eAAO,MAAM,aAAa,EAAE,YAoB3B,CAAC;AAEF,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,mBAAmB,CAYtE"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export const databasesList = async (params, exec) => {
|
|
2
|
+
const host = params?.host ?? 'localhost';
|
|
3
|
+
const port = String(params?.port ?? 5432);
|
|
4
|
+
const user = params?.user ?? 'postgres';
|
|
5
|
+
const stdout = await exec('psql', [
|
|
6
|
+
'-h',
|
|
7
|
+
host,
|
|
8
|
+
'-p',
|
|
9
|
+
port,
|
|
10
|
+
'-U',
|
|
11
|
+
user,
|
|
12
|
+
'-t',
|
|
13
|
+
'-A',
|
|
14
|
+
'-F',
|
|
15
|
+
'\t',
|
|
16
|
+
'-c',
|
|
17
|
+
'SELECT datname, pg_catalog.pg_get_userbyid(datdba), pg_catalog.pg_encoding_to_char(encoding), pg_catalog.pg_size_pretty(pg_catalog.pg_database_size(datname)) FROM pg_catalog.pg_database WHERE datistemplate = false ORDER BY datname',
|
|
18
|
+
]);
|
|
19
|
+
return parseDatabasesList(stdout);
|
|
20
|
+
};
|
|
21
|
+
export function parseDatabasesList(stdout) {
|
|
22
|
+
const lines = stdout.trim().split('\n').filter(Boolean);
|
|
23
|
+
const databases = lines.map((line) => {
|
|
24
|
+
const [name, owner, encoding, sizePretty] = line.split('\t');
|
|
25
|
+
return {
|
|
26
|
+
name: name ?? '',
|
|
27
|
+
owner: owner ?? '',
|
|
28
|
+
encoding: encoding ?? '',
|
|
29
|
+
sizePretty: sizePretty ?? '',
|
|
30
|
+
};
|
|
31
|
+
});
|
|
32
|
+
return { databases, count: databases.length };
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=databases-list.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"databases-list.js","sourceRoot":"","sources":["../../../src/postgres/probes/databases-list.ts"],"names":[],"mappings":"AAcA,MAAM,CAAC,MAAM,aAAa,GAAiB,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE;IAChE,MAAM,IAAI,GAAI,MAAM,EAAE,IAAe,IAAI,WAAW,CAAC;IACrD,MAAM,IAAI,GAAG,MAAM,CAAE,MAAM,EAAE,IAAe,IAAI,IAAI,CAAC,CAAC;IACtD,MAAM,IAAI,GAAI,MAAM,EAAE,IAAe,IAAI,UAAU,CAAC;IAEpD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,EAAE;QAChC,IAAI;QACJ,IAAI;QACJ,IAAI;QACJ,IAAI;QACJ,IAAI;QACJ,IAAI;QACJ,IAAI;QACJ,IAAI;QACJ,IAAI;QACJ,IAAI;QACJ,IAAI;QACJ,wOAAwO;KACzO,CAAC,CAAC;IACH,OAAO,kBAAkB,CAAC,MAAM,CAAC,CAAC;AACpC,CAAC,CAAC;AAEF,MAAM,UAAU,kBAAkB,CAAC,MAAc;IAC/C,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACxD,MAAM,SAAS,GAAmB,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QACnD,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,UAAU,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC7D,OAAO;YACL,IAAI,EAAE,IAAI,IAAI,EAAE;YAChB,KAAK,EAAE,KAAK,IAAI,EAAE;YAClB,QAAQ,EAAE,QAAQ,IAAI,EAAE;YACxB,UAAU,EAAE,UAAU,IAAI,EAAE;SAC7B,CAAC;IACJ,CAAC,CAAC,CAAC;IACH,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,CAAC,MAAM,EAAE,CAAC;AAChD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"databases-list.test.d.ts","sourceRoot":"","sources":["../../../src/postgres/probes/databases-list.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { databasesList, parseDatabasesList } from './databases-list.js';
|
|
3
|
+
const SAMPLE_OUTPUT = `postgres\tpostgres\tUTF8\t8537 kB
|
|
4
|
+
myapp\tappuser\tUTF8\t156 MB
|
|
5
|
+
analytics\tanalyst\tUTF8\t2345 MB`;
|
|
6
|
+
describe('parseDatabasesList', () => {
|
|
7
|
+
it('parses psql output into structured data', () => {
|
|
8
|
+
const result = parseDatabasesList(SAMPLE_OUTPUT);
|
|
9
|
+
expect(result.count).toBe(3);
|
|
10
|
+
expect(result.databases[0]).toEqual({
|
|
11
|
+
name: 'postgres',
|
|
12
|
+
owner: 'postgres',
|
|
13
|
+
encoding: 'UTF8',
|
|
14
|
+
sizePretty: '8537 kB',
|
|
15
|
+
});
|
|
16
|
+
expect(result.databases[1]?.name).toBe('myapp');
|
|
17
|
+
});
|
|
18
|
+
it('handles empty output', () => {
|
|
19
|
+
const result = parseDatabasesList('');
|
|
20
|
+
expect(result.count).toBe(0);
|
|
21
|
+
expect(result.databases).toEqual([]);
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
describe('databasesList handler', () => {
|
|
25
|
+
it('calls psql with default params', async () => {
|
|
26
|
+
const mockExec = async (cmd, args) => {
|
|
27
|
+
expect(cmd).toBe('psql');
|
|
28
|
+
expect(args).toContain('-h');
|
|
29
|
+
expect(args).toContain('localhost');
|
|
30
|
+
expect(args).toContain('-p');
|
|
31
|
+
expect(args).toContain('5432');
|
|
32
|
+
expect(args).toContain('-U');
|
|
33
|
+
expect(args).toContain('postgres');
|
|
34
|
+
return SAMPLE_OUTPUT;
|
|
35
|
+
};
|
|
36
|
+
const result = (await databasesList(undefined, mockExec));
|
|
37
|
+
expect(result.count).toBe(3);
|
|
38
|
+
});
|
|
39
|
+
it('passes custom host/port/user', async () => {
|
|
40
|
+
const mockExec = async (cmd, args) => {
|
|
41
|
+
expect(args).toContain('db.example.com');
|
|
42
|
+
expect(args).toContain('5433');
|
|
43
|
+
expect(args).toContain('admin');
|
|
44
|
+
return SAMPLE_OUTPUT;
|
|
45
|
+
};
|
|
46
|
+
await databasesList({ host: 'db.example.com', port: 5433, user: 'admin' }, mockExec);
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
//# sourceMappingURL=databases-list.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"databases-list.test.js","sourceRoot":"","sources":["../../../src/postgres/probes/databases-list.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAG9C,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAExE,MAAM,aAAa,GAAG;;kCAEY,CAAC;AAEnC,QAAQ,CAAC,oBAAoB,EAAE,GAAG,EAAE;IAClC,EAAE,CAAC,yCAAyC,EAAE,GAAG,EAAE;QACjD,MAAM,MAAM,GAAG,kBAAkB,CAAC,aAAa,CAAC,CAAC;QACjD,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC7B,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;YAClC,IAAI,EAAE,UAAU;YAChB,KAAK,EAAE,UAAU;YACjB,QAAQ,EAAE,MAAM;YAChB,UAAU,EAAE,SAAS;SACtB,CAAC,CAAC;QACH,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sBAAsB,EAAE,GAAG,EAAE;QAC9B,MAAM,MAAM,GAAG,kBAAkB,CAAC,EAAE,CAAC,CAAC;QACtC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC7B,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,uBAAuB,EAAE,GAAG,EAAE;IACrC,EAAE,CAAC,gCAAgC,EAAE,KAAK,IAAI,EAAE;QAC9C,MAAM,QAAQ,GAAW,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;YAC3C,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACzB,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;YAC7B,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;YACpC,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;YAC7B,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;YAC/B,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;YAC7B,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;YACnC,OAAO,aAAa,CAAC;QACvB,CAAC,CAAC;QAEF,MAAM,MAAM,GAAG,CAAC,MAAM,aAAa,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAwB,CAAC;QACjF,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC/B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8BAA8B,EAAE,KAAK,IAAI,EAAE;QAC5C,MAAM,QAAQ,GAAW,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;YAC3C,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;YACzC,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;YAC/B,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;YAChC,OAAO,aAAa,CAAC;QACvB,CAAC,CAAC;QAEF,MAAM,aAAa,CAAC,EAAE,IAAI,EAAE,gBAAgB,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,QAAQ,CAAC,CAAC;IACvF,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { ProbeHandler } from '../../types.js';
|
|
2
|
+
export interface SlowQueryInfo {
|
|
3
|
+
pid: number;
|
|
4
|
+
database: string;
|
|
5
|
+
user: string;
|
|
6
|
+
durationMs: number;
|
|
7
|
+
state: string;
|
|
8
|
+
query: string;
|
|
9
|
+
}
|
|
10
|
+
export interface QuerySlowResult {
|
|
11
|
+
queries: SlowQueryInfo[];
|
|
12
|
+
count: number;
|
|
13
|
+
thresholdMs: number;
|
|
14
|
+
}
|
|
15
|
+
export declare const querySlow: ProbeHandler;
|
|
16
|
+
export declare function parseQuerySlow(stdout: string, thresholdMs: number): QuerySlowResult;
|
|
17
|
+
//# sourceMappingURL=query-slow.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query-slow.d.ts","sourceRoot":"","sources":["../../../src/postgres/probes/query-slow.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEnD,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,aAAa,EAAE,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,eAAO,MAAM,SAAS,EAAE,YAqBvB,CAAC;AAEF,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,eAAe,CAcnF"}
|