mirror of
https://github.com/pockethost/pockethost.git
synced 2025-11-24 06:25:48 +00:00
pockethost: add live stats script
This commit is contained in:
parent
890049295d
commit
2540959c77
116
packages/pockethost/src/livestats.ts
Normal file
116
packages/pockethost/src/livestats.ts
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
import { execSync } from 'child_process'
|
||||||
|
|
||||||
|
interface PsRow {
|
||||||
|
id: string
|
||||||
|
names: string
|
||||||
|
runtime: string
|
||||||
|
ports: string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tracks last printed snapshot to avoid duplicate outputs
|
||||||
|
let lastSnapshotKey: string | null = null
|
||||||
|
|
||||||
|
function getDockerPs(): PsRow[] {
|
||||||
|
try {
|
||||||
|
// Run docker ps with format to get id, names, runtime, and ports
|
||||||
|
const output = execSync('docker ps --format "{{.ID}}\t{{.Names}}\t{{.RunningFor}}\t{{.Ports}}"', {
|
||||||
|
encoding: 'utf-8',
|
||||||
|
})
|
||||||
|
// Split output into lines and parse into structured rows
|
||||||
|
const lines = output
|
||||||
|
.trim()
|
||||||
|
.split('\n')
|
||||||
|
.filter((line) => line)
|
||||||
|
return lines.map((line) => {
|
||||||
|
const [id, names, runtime, ports] = line.split('\t')
|
||||||
|
return { id: id || '', names: names || '', runtime: runtime || '', ports: ports || '' }
|
||||||
|
})
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error running docker ps. Is Docker running?', error)
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getBaseName(name: string): string {
|
||||||
|
// Remove timestamp suffix like -20231201-143022
|
||||||
|
return name.replace(/-\d+$/, '')
|
||||||
|
}
|
||||||
|
|
||||||
|
function displaySortedPs(): void {
|
||||||
|
const psData = getDockerPs()
|
||||||
|
if (psData.length === 0) {
|
||||||
|
// Compute a stable key for the empty state
|
||||||
|
const snapshotKey = 'empty'
|
||||||
|
if (snapshotKey === lastSnapshotKey) return
|
||||||
|
lastSnapshotKey = snapshotKey
|
||||||
|
console.log('\n' + '─'.repeat(80))
|
||||||
|
console.log(`Monitoring duplicate containers - ${new Date().toLocaleTimeString()}`)
|
||||||
|
console.log('No containers found or error occurred.')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Group containers by base name (ignoring timestamp)
|
||||||
|
const groupedContainers = new Map<string, PsRow[]>()
|
||||||
|
|
||||||
|
psData.forEach((row) => {
|
||||||
|
const baseName = getBaseName(row.names)
|
||||||
|
// console.log(baseName)
|
||||||
|
if (!groupedContainers.has(baseName)) {
|
||||||
|
groupedContainers.set(baseName, [])
|
||||||
|
}
|
||||||
|
groupedContainers.get(baseName)!.push(row)
|
||||||
|
})
|
||||||
|
|
||||||
|
// Filter to only show groups with duplicates
|
||||||
|
const duplicateGroups = Array.from(groupedContainers.entries())
|
||||||
|
.filter(([baseName, containers]) => containers.length > 1)
|
||||||
|
.sort(([a], [b]) => a.localeCompare(b))
|
||||||
|
|
||||||
|
// Build a stable snapshot key that ignores runtime (which changes over time)
|
||||||
|
const snapshotKey = JSON.stringify(
|
||||||
|
duplicateGroups.map(([baseName, containers]) => ({
|
||||||
|
baseName,
|
||||||
|
items: containers
|
||||||
|
.slice()
|
||||||
|
.sort((a, b) => a.names.localeCompare(b.names) || a.id.localeCompare(b.id))
|
||||||
|
.map((c) => ({ id: c.id, name: c.names, ports: c.ports })),
|
||||||
|
}))
|
||||||
|
)
|
||||||
|
|
||||||
|
// If nothing changed since last print, skip output
|
||||||
|
if (snapshotKey === lastSnapshotKey) return
|
||||||
|
lastSnapshotKey = snapshotKey
|
||||||
|
|
||||||
|
// If there are no duplicates, print a single status line
|
||||||
|
if (duplicateGroups.length === 0) {
|
||||||
|
console.log('\n' + '─'.repeat(80))
|
||||||
|
console.log(`Monitoring duplicate containers - ${new Date().toLocaleTimeString()}`)
|
||||||
|
console.log('No duplicate containers found.')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print duplicate containers
|
||||||
|
console.log('\n' + '─'.repeat(80))
|
||||||
|
console.log(`Monitoring duplicate containers - ${new Date().toLocaleTimeString()}`)
|
||||||
|
console.log('CONTAINER ID'.padEnd(13) + 'CONTAINER NAME'.padEnd(30) + 'RUNTIME'.padEnd(20) + 'PORTS')
|
||||||
|
duplicateGroups.forEach(([baseName, containers]) => {
|
||||||
|
containers.sort((a, b) => a.names.localeCompare(b.names))
|
||||||
|
containers.forEach((row) => {
|
||||||
|
console.log(row.id.padEnd(13) + row.names.padEnd(30) + row.runtime.padEnd(20) + row.ports)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function main(): void {
|
||||||
|
console.log('Monitoring docker ps sorted by container names...')
|
||||||
|
// Run displaySortedPs every second
|
||||||
|
setInterval(displaySortedPs, 1000)
|
||||||
|
|
||||||
|
// Handle Ctrl+C gracefully
|
||||||
|
process.on('SIGINT', () => {
|
||||||
|
console.log('\nStopped monitoring.')
|
||||||
|
process.exit(0)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
main()
|
||||||
Loading…
x
Reference in New Issue
Block a user