增加更多采集指标
This commit is contained in:
@@ -5,10 +5,12 @@ import (
|
||||
"crypto/rand"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
@@ -45,6 +47,7 @@ func RegisterRoutes(r *gin.Engine) {
|
||||
metrics.GET("/processes", GetProcessMetrics) // 添加进程信息查询端点
|
||||
metrics.GET("/disk_details", GetDiskDetails) // 添加磁盘详细信息查询端点
|
||||
metrics.GET("/logs", GetLogs) // 添加系统日志查询端点
|
||||
metrics.GET("/hardware", GetHardwareMetrics) // 添加硬件信息查询端点
|
||||
// 添加POST端点,接收Agent发送的指标数据
|
||||
metrics.POST("/", HandleMetricsPost)
|
||||
}
|
||||
@@ -91,7 +94,7 @@ type ProcessMetrics struct {
|
||||
|
||||
// DiskDetailMetrics 磁盘详细信息
|
||||
type DiskDetailMetrics struct {
|
||||
DeviceID string `json:"device_id"` // 设备ID
|
||||
Path string `json:"path"` // 设备路径
|
||||
Status string `json:"status"` // 设备状态
|
||||
Type string `json:"type"` // 设备类型
|
||||
SizeGB float64 `json:"size_gb"` // 设备大小(GB)
|
||||
@@ -115,6 +118,52 @@ type NetworkInterfaceMetrics struct {
|
||||
RxBytes uint64 `json:"rx_bytes"` // 累计接收字节数
|
||||
}
|
||||
|
||||
// OSInfo 操作系统信息
|
||||
type OSInfo struct {
|
||||
Name string `json:"name"` // 操作系统名称
|
||||
Version string `json:"version"` // 操作系统版本
|
||||
Arch string `json:"arch"` // 系统架构
|
||||
Fullname string `json:"fullname"` // 完整名称(Name+Version)
|
||||
}
|
||||
|
||||
// CPUInfo CPU详细信息
|
||||
type CPUInfo struct {
|
||||
Model string `json:"model"` // CPU型号
|
||||
Cores int `json:"cores"` // 核心数
|
||||
Threads int `json:"threads"` // 线程数
|
||||
MaxFreq float64 `json:"max_freq"` // 最大频率 (MHz)
|
||||
MinFreq float64 `json:"min_freq"` // 最小频率 (MHz)
|
||||
AvgFreq float64 `json:"avg_freq"` // 平均频率 (MHz)
|
||||
Usage float64 `json:"usage"` // 当前使用率
|
||||
}
|
||||
|
||||
// MemoryInfo 内存详细信息
|
||||
type MemoryInfo struct {
|
||||
Total uint64 `json:"total"` // 总容量 (bytes)
|
||||
Used uint64 `json:"used"` // 已使用 (bytes)
|
||||
Free uint64 `json:"free"` // 空闲 (bytes)
|
||||
UsedPercent float64 `json:"used_percent"` // 使用率百分比
|
||||
}
|
||||
|
||||
// NetworkHardwareInfo 网卡硬件信息
|
||||
type NetworkHardwareInfo struct {
|
||||
Name string `json:"name"` // 网卡名称
|
||||
MAC string `json:"mac"` // MAC地址
|
||||
IPAddresses []string `json:"ip_addresses"` // IP地址列表
|
||||
MTU int `json:"mtu"` // MTU值
|
||||
Speed int `json:"speed"` // 网卡速度 (Mbps)
|
||||
Up bool `json:"up"` // 是否启用
|
||||
}
|
||||
|
||||
// HardwareMetrics 硬件信息指标
|
||||
type HardwareMetrics struct {
|
||||
OS OSInfo `json:"os"` // 操作系统信息
|
||||
CPU CPUInfo `json:"cpu"` // CPU信息
|
||||
Memory MemoryInfo `json:"memory"` // 内存信息
|
||||
DiskDetails []DiskDetailMetrics `json:"disk_details"` // 磁盘硬件信息
|
||||
NetworkCards []NetworkHardwareInfo `json:"network_cards"` // 网卡硬件信息
|
||||
}
|
||||
|
||||
// LogEntry 系统日志条目
|
||||
type LogEntry struct {
|
||||
Sequence int `json:"sequence"` // 日志序号
|
||||
@@ -137,6 +186,8 @@ type MetricsRequest struct {
|
||||
TxTotal uint64 `json:"tx_total"` // 所有网卡累计发送字节数总和
|
||||
RxRate uint64 `json:"rx_rate"` // 所有网卡实时接收速率总和 (bytes/s)
|
||||
TxRate uint64 `json:"tx_rate"` // 所有网卡实时发送速率总和 (bytes/s)
|
||||
// 硬件信息
|
||||
Hardware HardwareMetrics `json:"hardware"` // 硬件详细信息
|
||||
}
|
||||
|
||||
// HandleMetricsPost 处理Agent发送的指标数据
|
||||
@@ -212,7 +263,8 @@ func HandleMetricsPost(c *gin.Context) {
|
||||
}
|
||||
|
||||
// 创建单独的上下文用于InfluxDB写入,避免HTTP请求结束时上下文被取消
|
||||
writeCtx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
// 增加超时时间到30秒,确保硬件信息能够被成功写入
|
||||
writeCtx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
||||
defer cancel()
|
||||
|
||||
// 处理所有指标
|
||||
@@ -315,9 +367,9 @@ func HandleMetricsPost(c *gin.Context) {
|
||||
|
||||
// 写入磁盘详细信息
|
||||
for _, diskDetail := range req.DiskDetails {
|
||||
if err := globalStorage.WriteDiskDetailMetric(writeCtx, deviceID, diskDetail.DeviceID, diskDetail.Status, diskDetail.Type, diskDetail.SizeGB, diskDetail.Model, diskDetail.InterfaceType, diskDetail.Description, baseTags); err != nil {
|
||||
if err := globalStorage.WriteDiskDetailMetric(writeCtx, deviceID, diskDetail.Path, diskDetail.Status, diskDetail.Type, diskDetail.SizeGB, diskDetail.Model, diskDetail.InterfaceType, diskDetail.Description, baseTags); err != nil {
|
||||
// 只记录警告,不影响后续指标处理
|
||||
log.Printf("Warning: Failed to write disk details for device %s: %v", diskDetail.DeviceID, err)
|
||||
log.Printf("Warning: Failed to write disk details for device %s: %v", diskDetail.Path, err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -329,6 +381,79 @@ func HandleMetricsPost(c *gin.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
// 写入硬件信息
|
||||
// 操作系统信息
|
||||
osData := map[string]interface{}{
|
||||
"name": req.Hardware.OS.Name,
|
||||
"version": req.Hardware.OS.Version,
|
||||
"arch": req.Hardware.OS.Arch,
|
||||
"fullname": req.Hardware.OS.Fullname,
|
||||
}
|
||||
if err := globalStorage.WriteHardwareMetric(writeCtx, deviceID, "os", osData, baseTags); err != nil {
|
||||
log.Printf("Warning: Failed to write OS info: %v", err)
|
||||
}
|
||||
|
||||
// CPU信息
|
||||
cpuData := map[string]interface{}{
|
||||
"model": req.Hardware.CPU.Model,
|
||||
"cores": req.Hardware.CPU.Cores,
|
||||
"threads": req.Hardware.CPU.Threads,
|
||||
"max_freq": req.Hardware.CPU.MaxFreq,
|
||||
"min_freq": req.Hardware.CPU.MinFreq,
|
||||
"avg_freq": req.Hardware.CPU.AvgFreq,
|
||||
"usage": req.Hardware.CPU.Usage,
|
||||
}
|
||||
if err := globalStorage.WriteHardwareMetric(writeCtx, deviceID, "cpu", cpuData, baseTags); err != nil {
|
||||
log.Printf("Warning: Failed to write CPU info: %v", err)
|
||||
}
|
||||
|
||||
// 内存信息
|
||||
memoryData := map[string]interface{}{
|
||||
"total": req.Hardware.Memory.Total,
|
||||
"used": req.Hardware.Memory.Used,
|
||||
"free": req.Hardware.Memory.Free,
|
||||
"used_percent": req.Hardware.Memory.UsedPercent,
|
||||
}
|
||||
if err := globalStorage.WriteHardwareMetric(writeCtx, deviceID, "memory", memoryData, baseTags); err != nil {
|
||||
log.Printf("Warning: Failed to write memory info: %v", err)
|
||||
}
|
||||
|
||||
// 磁盘详细信息
|
||||
for i, diskDetail := range req.Hardware.DiskDetails {
|
||||
diskData := map[string]interface{}{
|
||||
"path": diskDetail.Path,
|
||||
"status": diskDetail.Status,
|
||||
"type": diskDetail.Type,
|
||||
"size_gb": diskDetail.SizeGB,
|
||||
"model": diskDetail.Model,
|
||||
"interface_type": diskDetail.InterfaceType,
|
||||
"description": diskDetail.Description,
|
||||
"index": i,
|
||||
}
|
||||
if err := globalStorage.WriteHardwareMetric(writeCtx, deviceID, "disk", diskData, baseTags); err != nil {
|
||||
log.Printf("Warning: Failed to write disk info: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// 网络网卡信息
|
||||
for i, netCard := range req.Hardware.NetworkCards {
|
||||
netData := map[string]interface{}{
|
||||
"name": netCard.Name,
|
||||
"mac": netCard.MAC,
|
||||
"mtu": netCard.MTU,
|
||||
"speed": netCard.Speed,
|
||||
"up": netCard.Up,
|
||||
"index": i,
|
||||
}
|
||||
// 添加IP地址列表
|
||||
for j, ipAddr := range netCard.IPAddresses {
|
||||
netData[fmt.Sprintf("ip_address_%d", j)] = ipAddr
|
||||
}
|
||||
if err := globalStorage.WriteHardwareMetric(writeCtx, deviceID, "network", netData, baseTags); err != nil {
|
||||
log.Printf("Warning: Failed to write network card info: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// 广播指标更新消息,只广播最后一个指标
|
||||
if i == len(metricsList)-1 {
|
||||
// 准备广播的磁盘使用率数据(兼容旧格式)
|
||||
@@ -1119,3 +1244,211 @@ func GetLogs(c *gin.Context) {
|
||||
"logs": logs,
|
||||
})
|
||||
}
|
||||
|
||||
// GetHardwareMetrics 获取硬件信息指标
|
||||
func GetHardwareMetrics(c *gin.Context) {
|
||||
// 获取查询参数
|
||||
deviceID := c.Query("device_id") // 必须参数,不能为空
|
||||
if deviceID == "" {
|
||||
c.JSON(http.StatusBadRequest, gin.H{
|
||||
"error": "device_id is required",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// 从设备存储获取设备信息
|
||||
device, ok := deviceStorage.GetDevice(deviceID)
|
||||
if !ok {
|
||||
c.JSON(http.StatusNotFound, gin.H{
|
||||
"error": "Device not found",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// 从存储中查询硬件信息
|
||||
hardwareInfo, err := globalStorage.QueryHardwareMetrics(context.Background(), deviceID)
|
||||
if err != nil {
|
||||
log.Printf("Warning: Failed to query hardware metrics: %v", err)
|
||||
// 查询失败时,返回一个空的硬件信息对象
|
||||
hardwareInfo = make(map[string]interface{})
|
||||
}
|
||||
|
||||
// 为了确保返回的结构与前端期望的一致,我们需要将查询结果转换为期望的格式
|
||||
hardwareResponse := map[string]interface{}{
|
||||
"os": map[string]string{
|
||||
"name": "Unknown",
|
||||
"version": "Unknown",
|
||||
"arch": "Unknown",
|
||||
"fullname": "Unknown",
|
||||
},
|
||||
"cpu": map[string]interface{}{
|
||||
"model": "Unknown",
|
||||
"cores": 0,
|
||||
"threads": 0,
|
||||
"max_freq": 0,
|
||||
"min_freq": 0,
|
||||
"avg_freq": 0,
|
||||
"usage": 0,
|
||||
},
|
||||
"memory": map[string]interface{}{
|
||||
"total": 0,
|
||||
"used": 0,
|
||||
"free": 0,
|
||||
"used_percent": 0,
|
||||
},
|
||||
"disk_details": []map[string]interface{}{},
|
||||
"network_cards": []map[string]interface{}{},
|
||||
}
|
||||
|
||||
// 如果查询到了硬件信息,更新响应结构
|
||||
if osData, ok := hardwareInfo["os"].(map[string]interface{}); ok {
|
||||
osMap := hardwareResponse["os"].(map[string]string)
|
||||
if name, ok := osData["name"].(string); ok {
|
||||
osMap["name"] = name
|
||||
}
|
||||
if version, ok := osData["version"].(string); ok {
|
||||
osMap["version"] = version
|
||||
}
|
||||
if arch, ok := osData["arch"].(string); ok {
|
||||
osMap["arch"] = arch
|
||||
}
|
||||
if fullname, ok := osData["fullname"].(string); ok {
|
||||
osMap["fullname"] = fullname
|
||||
}
|
||||
}
|
||||
|
||||
if cpuData, ok := hardwareInfo["cpu"].(map[string]interface{}); ok {
|
||||
if model, ok := cpuData["model"].(string); ok {
|
||||
hardwareResponse["cpu"].(map[string]interface{})["model"] = model
|
||||
}
|
||||
if cores, ok := cpuData["cores"].(int); ok {
|
||||
hardwareResponse["cpu"].(map[string]interface{})["cores"] = cores
|
||||
}
|
||||
if threads, ok := cpuData["threads"].(int); ok {
|
||||
hardwareResponse["cpu"].(map[string]interface{})["threads"] = threads
|
||||
}
|
||||
if maxFreq, ok := cpuData["max_freq"].(float64); ok {
|
||||
hardwareResponse["cpu"].(map[string]interface{})["max_freq"] = maxFreq
|
||||
}
|
||||
if minFreq, ok := cpuData["min_freq"].(float64); ok {
|
||||
hardwareResponse["cpu"].(map[string]interface{})["min_freq"] = minFreq
|
||||
}
|
||||
if avgFreq, ok := cpuData["avg_freq"].(float64); ok {
|
||||
hardwareResponse["cpu"].(map[string]interface{})["avg_freq"] = avgFreq
|
||||
}
|
||||
if usage, ok := cpuData["usage"].(float64); ok {
|
||||
hardwareResponse["cpu"].(map[string]interface{})["usage"] = usage
|
||||
}
|
||||
}
|
||||
|
||||
if memoryData, ok := hardwareInfo["memory"].(map[string]interface{}); ok {
|
||||
if total, ok := memoryData["total"].(uint64); ok {
|
||||
hardwareResponse["memory"].(map[string]interface{})["total"] = total
|
||||
}
|
||||
if used, ok := memoryData["used"].(uint64); ok {
|
||||
hardwareResponse["memory"].(map[string]interface{})["used"] = used
|
||||
}
|
||||
if free, ok := memoryData["free"].(uint64); ok {
|
||||
hardwareResponse["memory"].(map[string]interface{})["free"] = free
|
||||
}
|
||||
if usedPercent, ok := memoryData["used_percent"].(float64); ok {
|
||||
hardwareResponse["memory"].(map[string]interface{})["used_percent"] = usedPercent
|
||||
}
|
||||
}
|
||||
|
||||
// 处理磁盘详细信息
|
||||
if diskDataList, ok := hardwareInfo["disk"].([]map[string]interface{}); ok {
|
||||
// 如果是磁盘列表
|
||||
diskDetails := []map[string]interface{}{}
|
||||
for _, diskData := range diskDataList {
|
||||
diskDetail := map[string]interface{}{
|
||||
"path": diskData["path"],
|
||||
"status": diskData["status"],
|
||||
"type": diskData["type"],
|
||||
"size_gb": diskData["size_gb"],
|
||||
"model": diskData["model"],
|
||||
"interface_type": diskData["interface_type"],
|
||||
"description": diskData["description"],
|
||||
}
|
||||
diskDetails = append(diskDetails, diskDetail)
|
||||
}
|
||||
hardwareResponse["disk_details"] = diskDetails
|
||||
} else if diskData, ok := hardwareInfo["disk"].(map[string]interface{}); ok {
|
||||
// 如果是单个磁盘
|
||||
diskDetails := []map[string]interface{}{
|
||||
{
|
||||
"path": diskData["path"],
|
||||
"status": diskData["status"],
|
||||
"type": diskData["type"],
|
||||
"size_gb": diskData["size_gb"],
|
||||
"model": diskData["model"],
|
||||
"interface_type": diskData["interface_type"],
|
||||
"description": diskData["description"],
|
||||
},
|
||||
}
|
||||
hardwareResponse["disk_details"] = diskDetails
|
||||
}
|
||||
|
||||
// 处理网卡信息
|
||||
if networkDataList, ok := hardwareInfo["network"].([]map[string]interface{}); ok {
|
||||
// 如果是网卡列表
|
||||
networkCards := []map[string]interface{}{}
|
||||
for _, networkData := range networkDataList {
|
||||
// 提取IP地址
|
||||
ipAddresses := []string{}
|
||||
for k, v := range networkData {
|
||||
if strings.HasPrefix(k, "ip_address_") {
|
||||
if ip, ok := v.(string); ok {
|
||||
ipAddresses = append(ipAddresses, ip)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
networkCard := map[string]interface{}{
|
||||
"name": networkData["name"],
|
||||
"mac": networkData["mac"],
|
||||
"ip_addresses": ipAddresses,
|
||||
"mtu": networkData["mtu"],
|
||||
"speed": networkData["speed"],
|
||||
"up": networkData["up"],
|
||||
}
|
||||
networkCards = append(networkCards, networkCard)
|
||||
}
|
||||
hardwareResponse["network_cards"] = networkCards
|
||||
} else if networkData, ok := hardwareInfo["network"].(map[string]interface{}); ok {
|
||||
// 如果是单个网卡
|
||||
// 提取IP地址
|
||||
ipAddresses := []string{}
|
||||
for k, v := range networkData {
|
||||
if strings.HasPrefix(k, "ip_address_") {
|
||||
if ip, ok := v.(string); ok {
|
||||
ipAddresses = append(ipAddresses, ip)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
networkCard := map[string]interface{}{
|
||||
"name": networkData["name"],
|
||||
"mac": networkData["mac"],
|
||||
"ip_addresses": ipAddresses,
|
||||
"mtu": networkData["mtu"],
|
||||
"speed": networkData["speed"],
|
||||
"up": networkData["up"],
|
||||
}
|
||||
hardwareResponse["network_cards"] = []map[string]interface{}{networkCard}
|
||||
}
|
||||
|
||||
// 确保OS的fullname字段被正确设置
|
||||
osMap := hardwareResponse["os"].(map[string]string)
|
||||
if osMap["fullname"] == "Unknown" && osMap["name"] != "Unknown" && osMap["version"] != "Unknown" {
|
||||
// 如果fullname是默认值,但name和version已经正确设置,那么构建fullname
|
||||
osMap["fullname"] = osMap["name"] + " " + osMap["version"]
|
||||
}
|
||||
|
||||
// 返回硬件信息
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"device_id": deviceID,
|
||||
"name": device.Name,
|
||||
"hardware": hardwareResponse,
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user