14
This commit is contained in:
@@ -55,6 +55,9 @@ class MetricsController extends Base
|
||||
// Redis指标
|
||||
$metrics[] = $this->getRedisMetrics();
|
||||
|
||||
// MongoDB指标
|
||||
$metrics[] = $this->getMongoDBMetrics();
|
||||
|
||||
// HTTP请求指标
|
||||
$metrics[] = $this->getHttpMetrics();
|
||||
|
||||
@@ -183,7 +186,9 @@ class MetricsController extends Base
|
||||
|
||||
// 尝试获取数据库状态
|
||||
$db = \think\facade\Db::connect();
|
||||
$status = $db->query('SHOW STATUS');
|
||||
|
||||
// 1. 全局状态指标
|
||||
$status = $db->query('SHOW GLOBAL STATUS');
|
||||
$statusMap = [];
|
||||
foreach ($status as $item) {
|
||||
$statusMap[$item['Variable_name']] = $item['Value'];
|
||||
@@ -205,6 +210,60 @@ class MetricsController extends Base
|
||||
if (isset($statusMap['Uptime'])) {
|
||||
$metrics[] = $this->formatCounter('webman_db_uptime_seconds', 'Database uptime in seconds', [], (int)$statusMap['Uptime']);
|
||||
}
|
||||
if (isset($statusMap['Innodb_buffer_pool_pages_data'])) {
|
||||
$metrics[] = $this->formatGauge('webman_db_innodb_buffer_pool_pages_data', 'Number of pages containing data', [], (int)$statusMap['Innodb_buffer_pool_pages_data']);
|
||||
}
|
||||
if (isset($statusMap['Innodb_buffer_pool_pages_free'])) {
|
||||
$metrics[] = $this->formatGauge('webman_db_innodb_buffer_pool_pages_free', 'Number of free pages', [], (int)$statusMap['Innodb_buffer_pool_pages_free']);
|
||||
}
|
||||
if (isset($statusMap['Innodb_buffer_pool_pages_total'])) {
|
||||
$metrics[] = $this->formatGauge('webman_db_innodb_buffer_pool_pages_total', 'Total number of pages', [], (int)$statusMap['Innodb_buffer_pool_pages_total']);
|
||||
}
|
||||
if (isset($statusMap['Innodb_row_reads'])) {
|
||||
$metrics[] = $this->formatCounter('webman_db_innodb_row_reads_total', 'Number of rows read', [], (int)$statusMap['Innodb_row_reads']);
|
||||
}
|
||||
if (isset($statusMap['Innodb_row_writes'])) {
|
||||
$metrics[] = $this->formatCounter('webman_db_innodb_row_writes_total', 'Number of rows written', [], (int)$statusMap['Innodb_row_writes']);
|
||||
}
|
||||
if (isset($statusMap['Com_select'])) {
|
||||
$metrics[] = $this->formatCounter('webman_db_com_select_total', 'Number of SELECT statements', [], (int)$statusMap['Com_select']);
|
||||
}
|
||||
if (isset($statusMap['Com_insert'])) {
|
||||
$metrics[] = $this->formatCounter('webman_db_com_insert_total', 'Number of INSERT statements', [], (int)$statusMap['Com_insert']);
|
||||
}
|
||||
if (isset($statusMap['Com_update'])) {
|
||||
$metrics[] = $this->formatCounter('webman_db_com_update_total', 'Number of UPDATE statements', [], (int)$statusMap['Com_update']);
|
||||
}
|
||||
if (isset($statusMap['Com_delete'])) {
|
||||
$metrics[] = $this->formatCounter('webman_db_com_delete_total', 'Number of DELETE statements', [], (int)$statusMap['Com_delete']);
|
||||
}
|
||||
|
||||
// 2. 数据库大小
|
||||
$databases = $db->query('SHOW DATABASES WHERE `Database` NOT IN ("information_schema", "mysql", "performance_schema", "sys")');
|
||||
foreach ($databases as $dbInfo) {
|
||||
$dbName = $dbInfo['Database'];
|
||||
$sizeResult = $db->query("SELECT table_schema AS 'database', SUM(data_length + index_length) AS 'size_bytes' FROM information_schema.tables WHERE table_schema = '{$dbName}' GROUP BY table_schema");
|
||||
if (isset($sizeResult[0]['size_bytes'])) {
|
||||
$metrics[] = $this->formatGauge('webman_db_database_size_bytes', 'Database size in bytes', [
|
||||
'database' => $dbName
|
||||
], (int)$sizeResult[0]['size_bytes']);
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 表状态
|
||||
$tables = $db->query('SHOW TABLE STATUS FROM `' . ($dbConfig['database'] ?? 'test') . '`');
|
||||
foreach ($tables as $table) {
|
||||
$tableName = $table['Name'];
|
||||
$metrics[] = $this->formatGauge('webman_db_table_rows', 'Number of rows in table', [
|
||||
'table' => $tableName
|
||||
], (int)$table['Rows']);
|
||||
$metrics[] = $this->formatGauge('webman_db_table_data_length_bytes', 'Data length of table', [
|
||||
'table' => $tableName
|
||||
], (int)$table['Data_length']);
|
||||
$metrics[] = $this->formatGauge('webman_db_table_index_length_bytes', 'Index length of table', [
|
||||
'table' => $tableName
|
||||
], (int)$table['Index_length']);
|
||||
}
|
||||
|
||||
} catch (\Exception $e) {
|
||||
// 数据库连接失败,记录错误
|
||||
@@ -242,16 +301,31 @@ class MetricsController extends Base
|
||||
if (isset($info['used_memory_peak'])) {
|
||||
$metrics[] = $this->formatGauge('webman_redis_memory_peak_bytes', 'Redis peak memory used in bytes', [], (int)$info['used_memory_peak']);
|
||||
}
|
||||
if (isset($info['used_memory_rss'])) {
|
||||
$metrics[] = $this->formatGauge('webman_redis_memory_rss_bytes', 'Redis RSS memory used in bytes', [], (int)$info['used_memory_rss']);
|
||||
}
|
||||
if (isset($info['mem_fragmentation_ratio'])) {
|
||||
$metrics[] = $this->formatGauge('webman_redis_memory_fragmentation_ratio', 'Redis memory fragmentation ratio', [], (float)$info['mem_fragmentation_ratio']);
|
||||
}
|
||||
|
||||
// 连接数
|
||||
if (isset($info['connected_clients'])) {
|
||||
$metrics[] = $this->formatGauge('webman_redis_connected_clients', 'Number of connected clients', [], (int)$info['connected_clients']);
|
||||
}
|
||||
if (isset($info['client_recent_max_input_buffer'])) {
|
||||
$metrics[] = $this->formatGauge('webman_redis_client_max_input_buffer_bytes', 'Maximum input buffer size', [], (int)$info['client_recent_max_input_buffer']);
|
||||
}
|
||||
if (isset($info['client_recent_max_output_buffer'])) {
|
||||
$metrics[] = $this->formatGauge('webman_redis_client_max_output_buffer_bytes', 'Maximum output buffer size', [], (int)$info['client_recent_max_output_buffer']);
|
||||
}
|
||||
|
||||
// 命令统计
|
||||
if (isset($info['total_commands_processed'])) {
|
||||
$metrics[] = $this->formatCounter('webman_redis_commands_processed_total', 'Total commands processed', [], (int)$info['total_commands_processed']);
|
||||
}
|
||||
if (isset($info['instantaneous_ops_per_sec'])) {
|
||||
$metrics[] = $this->formatGauge('webman_redis_instantaneous_ops_per_sec', 'Instantaneous operations per second', [], (int)$info['instantaneous_ops_per_sec']);
|
||||
}
|
||||
|
||||
// 键数量
|
||||
if (isset($info['db0'])) {
|
||||
@@ -266,6 +340,29 @@ class MetricsController extends Base
|
||||
$metrics[] = $this->formatCounter('webman_redis_uptime_seconds', 'Redis uptime in seconds', [], (int)$info['uptime_in_seconds']);
|
||||
}
|
||||
|
||||
// 过期键
|
||||
if (isset($info['expired_keys'])) {
|
||||
$metrics[] = $this->formatCounter('webman_redis_expired_keys_total', 'Total number of expired keys', [], (int)$info['expired_keys']);
|
||||
}
|
||||
if (isset($info['evicted_keys'])) {
|
||||
$metrics[] = $this->formatCounter('webman_redis_evicted_keys_total', 'Total number of evicted keys', [], (int)$info['evicted_keys']);
|
||||
}
|
||||
|
||||
// 命中和未命中
|
||||
if (isset($info['keyspace_hits'])) {
|
||||
$metrics[] = $this->formatCounter('webman_redis_keyspace_hits_total', 'Total number of keyspace hits', [], (int)$info['keyspace_hits']);
|
||||
}
|
||||
if (isset($info['keyspace_misses'])) {
|
||||
$metrics[] = $this->formatCounter('webman_redis_keyspace_misses_total', 'Total number of keyspace misses', [], (int)$info['keyspace_misses']);
|
||||
}
|
||||
|
||||
// 复制状态
|
||||
if (isset($info['role'])) {
|
||||
$metrics[] = $this->formatGauge('webman_redis_role', 'Redis role (master=1, slave=2)', [
|
||||
'role' => $info['role']
|
||||
], $info['role'] === 'master' ? 1 : 2);
|
||||
}
|
||||
|
||||
} catch (\Exception $e) {
|
||||
$metrics[] = $this->formatGauge('webman_redis_up', 'Redis connection status', [], 0);
|
||||
}
|
||||
@@ -273,6 +370,114 @@ class MetricsController extends Base
|
||||
return implode("\n", $metrics);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取MongoDB指标
|
||||
*/
|
||||
protected function getMongoDBMetrics(): string
|
||||
{
|
||||
$metrics = [];
|
||||
|
||||
try {
|
||||
// 检查MongoDB扩展是否安装
|
||||
if (!class_exists('MongoDB\\Client')) {
|
||||
$metrics[] = $this->formatGauge('webman_mongodb_up', 'MongoDB connection status', [], 0);
|
||||
$metrics[] = $this->formatGauge('webman_mongodb_error', 'MongoDB error', [
|
||||
'error' => 'extension_not_installed'
|
||||
], 1);
|
||||
return implode("\n", $metrics);
|
||||
}
|
||||
|
||||
// 尝试连接MongoDB
|
||||
$mongoClient = new \MongoDB\Client('mongodb://localhost:27017');
|
||||
|
||||
// MongoDB连接状态
|
||||
$metrics[] = $this->formatGauge('webman_mongodb_up', 'MongoDB connection status', [], 1);
|
||||
|
||||
// 获取服务器状态
|
||||
$serverStatus = $mongoClient->selectDatabase('admin')->command(['serverStatus' => 1]);
|
||||
$status = $serverStatus->toArray()[0];
|
||||
|
||||
// 版本信息
|
||||
if (isset($status['version'])) {
|
||||
$metrics[] = $this->formatGauge('webman_mongodb_version_info', 'MongoDB version information', [
|
||||
'version' => $status['version']
|
||||
], 1);
|
||||
}
|
||||
|
||||
// 连接数
|
||||
if (isset($status['connections'])) {
|
||||
$metrics[] = $this->formatGauge('webman_mongodb_connections_current', 'Current number of connections', [], (int)$status['connections']['current']);
|
||||
$metrics[] = $this->formatGauge('webman_mongodb_connections_available', 'Available number of connections', [], (int)$status['connections']['available']);
|
||||
}
|
||||
|
||||
// 内存使用
|
||||
if (isset($status['mem'])) {
|
||||
if (isset($status['mem']['resident'])) {
|
||||
$metrics[] = $this->formatGauge('webman_mongodb_memory_resident_bytes', 'Resident memory usage in bytes', [], (int)$status['mem']['resident'] * 1024 * 1024);
|
||||
}
|
||||
if (isset($status['mem']['virtual'])) {
|
||||
$metrics[] = $this->formatGauge('webman_mongodb_memory_virtual_bytes', 'Virtual memory usage in bytes', [], (int)$status['mem']['virtual'] * 1024 * 1024);
|
||||
}
|
||||
}
|
||||
|
||||
// 操作统计
|
||||
if (isset($status['opcounters'])) {
|
||||
if (isset($status['opcounters']['insert'])) {
|
||||
$metrics[] = $this->formatCounter('webman_mongodb_ops_insert_total', 'Total insert operations', [], (int)$status['opcounters']['insert']);
|
||||
}
|
||||
if (isset($status['opcounters']['query'])) {
|
||||
$metrics[] = $this->formatCounter('webman_mongodb_ops_query_total', 'Total query operations', [], (int)$status['opcounters']['query']);
|
||||
}
|
||||
if (isset($status['opcounters']['update'])) {
|
||||
$metrics[] = $this->formatCounter('webman_mongodb_ops_update_total', 'Total update operations', [], (int)$status['opcounters']['update']);
|
||||
}
|
||||
if (isset($status['opcounters']['delete'])) {
|
||||
$metrics[] = $this->formatCounter('webman_mongodb_ops_delete_total', 'Total delete operations', [], (int)$status['opcounters']['delete']);
|
||||
}
|
||||
}
|
||||
|
||||
// 集合和数据库统计
|
||||
$databases = $mongoClient->listDatabases();
|
||||
foreach ($databases as $dbInfo) {
|
||||
$dbName = $dbInfo->getName();
|
||||
if (!in_array($dbName, ['admin', 'local', 'config'])) {
|
||||
$db = $mongoClient->selectDatabase($dbName);
|
||||
$collections = $db->listCollections();
|
||||
$collectionCount = 0;
|
||||
foreach ($collections as $collection) {
|
||||
$collectionCount++;
|
||||
$collectionName = $collection->getName();
|
||||
$stats = $db->command(['collStats' => $collectionName]);
|
||||
$collStats = $stats->toArray()[0];
|
||||
if (isset($collStats['count'])) {
|
||||
$metrics[] = $this->formatGauge('webman_mongodb_collection_documents', 'Number of documents in collection', [
|
||||
'database' => $dbName,
|
||||
'collection' => $collectionName
|
||||
], (int)$collStats['count']);
|
||||
}
|
||||
if (isset($collStats['size'])) {
|
||||
$metrics[] = $this->formatGauge('webman_mongodb_collection_size_bytes', 'Size of collection in bytes', [
|
||||
'database' => $dbName,
|
||||
'collection' => $collectionName
|
||||
], (int)$collStats['size']);
|
||||
}
|
||||
}
|
||||
$metrics[] = $this->formatGauge('webman_mongodb_database_collections', 'Number of collections in database', [
|
||||
'database' => $dbName
|
||||
], $collectionCount);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (\Exception $e) {
|
||||
$metrics[] = $this->formatGauge('webman_mongodb_up', 'MongoDB connection status', [], 0);
|
||||
$metrics[] = $this->formatGauge('webman_mongodb_error', 'MongoDB error', [
|
||||
'error' => 'connection_failed'
|
||||
], 1);
|
||||
}
|
||||
|
||||
return implode("\n", $metrics);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取HTTP请求指标
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user