-
-
Notifications
You must be signed in to change notification settings - Fork 28
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #766 from SquirrelCorporation/feature-db-servers-s…
…tatuses [FEAT] Add server stats endpoints and client integration
- Loading branch information
Showing
8 changed files
with
369 additions
and
3 deletions.
There are no files selected for viewing
121 changes: 119 additions & 2 deletions
121
client/src/pages/Admin/Settings/components/Information.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
import mongoose from 'mongoose'; | ||
import { API } from 'ssm-shared-lib'; | ||
import { getRedisClient } from '../../../data/cache'; | ||
import { prometheusServerStats } from '../../../data/statistics/server-stats'; | ||
import { parseRedisInfo } from '../../../helpers/redis/redis-info'; | ||
import logger from '../../../logger'; | ||
import { SuccessResponse } from '../../../middlewares/api/ApiResponse'; | ||
|
||
export const getMongoDBServerStats = async (req, res) => { | ||
const serverStatus = await mongoose.connection.db?.admin().serverStatus(); | ||
try { | ||
const data: API.MongoDBServerStats = { | ||
// Memory metrics | ||
memory: { | ||
resident: serverStatus?.mem?.resident, // Resident memory in MB | ||
virtual: serverStatus?.mem?.virtual, // Virtual memory in MB | ||
mapped: serverStatus?.mem?.mapped, // Memory mapped size | ||
}, | ||
|
||
// Connections | ||
connections: serverStatus?.connections, // Current, available, total connections | ||
|
||
// CPU metrics | ||
cpu: { | ||
userPercent: serverStatus?.cpu?.user, | ||
systemPercent: serverStatus?.cpu?.sys, | ||
idlePercent: serverStatus?.cpu?.idle, | ||
}, | ||
|
||
// Operations metrics | ||
operations: serverStatus?.opcounters, // Insert, query, update, delete counts | ||
}; | ||
new SuccessResponse(`Got MongoDB server stats`, data).send(res); | ||
} catch (error) { | ||
logger.error(error); | ||
throw error; | ||
} | ||
}; | ||
|
||
// Get detailed database storage stats | ||
export const getStorageStats = async (req, res) => { | ||
const dbStats = await mongoose.connection.db?.stats(); | ||
const data = { | ||
dataSize: dbStats?.dataSize, // Size of all documents | ||
storageSize: dbStats?.storageSize, // Total storage allocated | ||
indexSize: dbStats?.indexSize, // Total size of all indexes | ||
totalSize: dbStats?.totalSize, // Total size (data + indexes) | ||
scaleFactor: dbStats?.scaleFactor, // Scaling factor for sizes | ||
}; | ||
new SuccessResponse(`Got MongoDB server storage stats`, data).send(res); | ||
}; | ||
|
||
export const getRedisServerStats = async (req, res) => { | ||
const client = await getRedisClient(); | ||
|
||
const memory = await client.info('memory'); | ||
const cpu = await client.info('cpu'); | ||
const stats = await client.info('stats'); | ||
const server = await client.info('server'); | ||
const data = { | ||
memory: parseRedisInfo(memory), // Memory usage, peak memory, etc. | ||
cpu: parseRedisInfo(cpu), // CPU statistics | ||
stats: parseRedisInfo(stats), // General statistics | ||
server: parseRedisInfo(server), // Server information | ||
}; | ||
|
||
new SuccessResponse(`Got Redis server stats`, data).send(res); | ||
}; | ||
|
||
export const getPrometheusServerStats = async (req, res) => { | ||
const data = await prometheusServerStats(); | ||
new SuccessResponse(`Got Prometheus server stats`, data).send(res); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import axios from 'axios'; | ||
import { prometheusConf } from '../../config'; | ||
import logger from '../../logger'; | ||
|
||
export async function prometheusServerStats() { | ||
const { host, baseURL, user, password } = prometheusConf; | ||
const auth = { username: user, password: password }; | ||
|
||
try { | ||
// Get runtime information and build information | ||
const runtimeInfo = await axios.get(`${host}${baseURL}/status/runtimeinfo`, { auth }); | ||
const buildInfo = await axios.get(`${host}${baseURL}/status/buildinfo`, { auth }); | ||
|
||
// Get targets status (up/down) | ||
const targets = await axios.get(`${host}${baseURL}/targets`, { auth }); | ||
|
||
// Get TSDB stats (time series database statistics) | ||
const tsdbStats = await axios.get(`${host}${baseURL}/status/tsdb`, { auth }); | ||
|
||
return { | ||
runtime: runtimeInfo.data.data, | ||
build: buildInfo.data.data, | ||
targets: targets.data.data, | ||
tsdb: tsdbStats.data.data, | ||
}; | ||
} catch (error) { | ||
logger.error(error, 'Failed to fetch Prometheus stats'); | ||
throw error; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
// Helper to parse Redis INFO output into an object | ||
export function parseRedisInfo(info: string) { | ||
return info | ||
.split('\n') | ||
.filter((line) => line && !line.startsWith('#')) | ||
.reduce( | ||
(acc, line) => { | ||
const [key, value] = line.split(':'); | ||
if (key && value) { | ||
acc[key.trim()] = value.trim(); | ||
} | ||
return acc; | ||
}, | ||
{} as Record<string, string>, | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.