增加操作系统显示,以及磁盘信息显示

This commit is contained in:
Alex Yang
2025-12-06 23:30:58 +08:00
parent 8a5ca62793
commit 667e370f79
23 changed files with 366 additions and 4744 deletions

View File

@@ -94,12 +94,16 @@ type ProcessMetrics struct {
// DiskDetailMetrics 磁盘详细信息
type DiskDetailMetrics struct {
ID string `json:"id"` // 磁盘唯一ID数字序列
Path string `json:"path"` // 设备路径
Status string `json:"status"` // 设备状态
Type string `json:"type"` // 设备类型
SizeGB float64 `json:"size_gb"` // 设备大小(GB)
Model string `json:"model"` // 设备型号
Vendor string `json:"vendor"` // 设备厂商
InterfaceType string `json:"interface_type"` // 接口类型
FileSystem string `json:"file_system"` // 文件系统
DiskUUID string `json:"disk_uuid"` // 磁盘UUID
Description string `json:"description"` // 设备描述
}
@@ -147,6 +151,7 @@ type MemoryInfo struct {
// NetworkHardwareInfo 网卡硬件信息
type NetworkHardwareInfo struct {
ID string `json:"id"` // 网卡唯一ID数字序列
Name string `json:"name"` // 网卡名称
MAC string `json:"mac"` // MAC地址
IPAddresses []string `json:"ip_addresses"` // IP地址列表
@@ -367,7 +372,7 @@ func HandleMetricsPost(c *gin.Context) {
// 写入磁盘详细信息
for _, diskDetail := range req.DiskDetails {
if err := globalStorage.WriteDiskDetailMetric(writeCtx, deviceID, diskDetail.Path, 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.Vendor, diskDetail.InterfaceType, diskDetail.FileSystem, diskDetail.DiskUUID, diskDetail.Description, baseTags); err != nil {
// 只记录警告,不影响后续指标处理
log.Printf("Warning: Failed to write disk details for device %s: %v", diskDetail.Path, err)
}
@@ -421,12 +426,16 @@ func HandleMetricsPost(c *gin.Context) {
// 磁盘详细信息
for i, diskDetail := range req.Hardware.DiskDetails {
diskData := map[string]interface{}{
"id": diskDetail.ID,
"path": diskDetail.Path,
"status": diskDetail.Status,
"type": diskDetail.Type,
"size_gb": diskDetail.SizeGB,
"model": diskDetail.Model,
"vendor": diskDetail.Vendor,
"interface_type": diskDetail.InterfaceType,
"file_system": diskDetail.FileSystem,
"disk_uuid": diskDetail.DiskUUID,
"description": diskDetail.Description,
"index": i,
}
@@ -438,6 +447,7 @@ func HandleMetricsPost(c *gin.Context) {
// 网络网卡信息
for i, netCard := range req.Hardware.NetworkCards {
netData := map[string]interface{}{
"id": netCard.ID,
"name": netCard.Name,
"mac": netCard.MAC,
"mtu": netCard.MTU,
@@ -1362,12 +1372,16 @@ func GetHardwareMetrics(c *gin.Context) {
diskDetails := []map[string]interface{}{}
for _, diskData := range diskDataList {
diskDetail := map[string]interface{}{
"id": diskData["id"],
"path": diskData["path"],
"status": diskData["status"],
"type": diskData["type"],
"size_gb": diskData["size_gb"],
"model": diskData["model"],
"vendor": diskData["vendor"],
"interface_type": diskData["interface_type"],
"file_system": diskData["file_system"],
"disk_uuid": diskData["disk_uuid"],
"description": diskData["description"],
}
diskDetails = append(diskDetails, diskDetail)
@@ -1377,12 +1391,16 @@ func GetHardwareMetrics(c *gin.Context) {
// 如果是单个磁盘
diskDetails := []map[string]interface{}{
{
"id": diskData["id"],
"path": diskData["path"],
"status": diskData["status"],
"type": diskData["type"],
"size_gb": diskData["size_gb"],
"model": diskData["model"],
"vendor": diskData["vendor"],
"interface_type": diskData["interface_type"],
"file_system": diskData["file_system"],
"disk_uuid": diskData["disk_uuid"],
"description": diskData["description"],
},
}
@@ -1405,6 +1423,7 @@ func GetHardwareMetrics(c *gin.Context) {
}
networkCard := map[string]interface{}{
"id": networkData["id"],
"name": networkData["name"],
"mac": networkData["mac"],
"ip_addresses": ipAddresses,
@@ -1428,6 +1447,7 @@ func GetHardwareMetrics(c *gin.Context) {
}
networkCard := map[string]interface{}{
"id": networkData["id"],
"name": networkData["name"],
"mac": networkData["mac"],
"ip_addresses": ipAddresses,

View File

@@ -210,7 +210,7 @@ func (s *Storage) WriteProcessMetric(ctx context.Context, deviceID string, proce
}
// WriteDiskDetailMetric 写入磁盘详细信息
func (s *Storage) WriteDiskDetailMetric(ctx context.Context, deviceID, diskPath, status, diskType string, sizeGB float64, model, interfaceType, description string, tags map[string]string) error {
func (s *Storage) WriteDiskDetailMetric(ctx context.Context, deviceID, diskPath, status, diskType string, sizeGB float64, model, vendor, interfaceType, fileSystem, diskUUID, description string, tags map[string]string) error {
// 创建标签映射,合并原有标签和新标签
allTags := make(map[string]string)
// 复制原有标签
@@ -224,11 +224,14 @@ func (s *Storage) WriteDiskDetailMetric(ctx context.Context, deviceID, diskPath,
allTags["status"] = status
allTags["type"] = diskType
allTags["model"] = model
allTags["vendor"] = vendor
allTags["interface_type"] = interfaceType
allTags["file_system"] = fileSystem
// 创建字段映射
fields := map[string]interface{}{
"size_gb": sizeGB,
"disk_uuid": diskUUID,
"description": description,
}
@@ -476,13 +479,24 @@ func (s *Storage) QueryHardwareMetrics(ctx context.Context, deviceID string) (ma
// 为每个硬件类型单独查询,避免类型冲突
for _, hardwareType := range hardwareTypes {
// 构建查询语句,获取设备最新的特定类型硬件信息
query := `from(bucket: "` + s.bucket + `")
|> range(start: -24h)
|> filter(fn: (r) => r["_measurement"] == "hardware")
|> filter(fn: (r) => r["device_id"] == "` + deviceID + `")
|> filter(fn: (r) => r["type"] == "` + hardwareType + `")
|> last()`
// 构建查询语句
var query string
if hardwareType == "os" || hardwareType == "cpu" || hardwareType == "memory" {
// 对于os、cpu、memory类型我们只需要一个结果
query = `from(bucket: "` + s.bucket + `")
|> range(start: -24h)
|> filter(fn: (r) => r["_measurement"] == "hardware")
|> filter(fn: (r) => r["device_id"] == "` + deviceID + `")
|> filter(fn: (r) => r["type"] == "` + hardwareType + `")
|> last()`
} else {
// 对于disk和network类型我们需要获取所有设备的所有字段记录
query = `from(bucket: "` + s.bucket + `")
|> range(start: -24h)
|> filter(fn: (r) => r["_measurement"] == "hardware")
|> filter(fn: (r) => r["device_id"] == "` + deviceID + `")
|> filter(fn: (r) => r["type"] == "` + hardwareType + `")`
}
// 执行查询
queryResult, err := queryAPI.Query(ctx, query)
@@ -511,10 +525,12 @@ func (s *Storage) QueryHardwareMetrics(ctx context.Context, deviceID string) (ma
hardwareInfo[hardwareType] = fieldMap
}
} else {
// 对于disk和network类型我们可能有多个结果
// 我们需要收集所有结果并按index排序
// 使用map来去重
resultMap := make(map[string]map[string]interface{})
// 对于disk和network类型我们可能有多个结果,每个字段作为单独的行返回
var allResults []map[string]interface{}
// 创建一个map来存储每个设备的所有字段值
// key是设备ID或index
deviceFields := make(map[string]map[string]interface{})
// 遍历所有结果行,收集所有结果
for queryResult.Next() {
@@ -525,35 +541,57 @@ func (s *Storage) QueryHardwareMetrics(ctx context.Context, deviceID string) (ma
fieldName := record.Field()
fieldValue := record.Value()
// 获取硬件ID用于去重
hardwareID := "unknown"
if hardwareType == "disk" {
// 对于磁盘使用device_id作为唯一标识
if devID, ok := record.ValueByKey("device_id").(string); ok {
hardwareID = devID
}
// 获取设备唯一标识
deviceKey := ""
// 优先使用id字段作为设备标识
if id, isString := fieldValue.(string); fieldName == "id" && isString {
deviceKey = id
// 创建设备字段映射
deviceFields[deviceKey] = make(map[string]interface{})
deviceFields[deviceKey]["id"] = id
} else {
// 对于网卡使用name作为唯一标识
if name, ok := record.ValueByKey("name").(string); ok {
hardwareID = name
// 否则,查找已存在的设备映射
// 遍历所有设备映射,查找当前记录对应的设备
for key, fields := range deviceFields {
// 如果设备映射中没有id字段或者id字段为空跳过
if id, ok := fields["id"].(string); ok && id != "" {
// 假设当前记录属于该设备
deviceKey = key
break
}
}
}
// 获取或创建硬件数据映射
if _, ok := resultMap[hardwareID]; !ok {
resultMap[hardwareID] = make(map[string]interface{})
// 如果没有找到设备标识使用index作为设备标识
if deviceKey == "" {
index := 0
if idx, ok := record.ValueByKey("index").(int); ok {
index = idx
}
deviceKey = fmt.Sprintf("%d", index)
// 创建设备字段映射
deviceFields[deviceKey] = make(map[string]interface{})
}
// 添加字段值
resultMap[hardwareID][fieldName] = fieldValue
// 添加字段值到设备字段映射中
deviceFields[deviceKey][fieldName] = fieldValue
}
// 将去重后的结果转换为切片
var allResults []map[string]interface{}
for _, result := range resultMap {
allResults = append(allResults, result)
// 将deviceFields转换为切片
for _, fields := range deviceFields {
allResults = append(allResults, fields)
}
// 按id排序
sort.Slice(allResults, func(i, j int) bool {
iID, iOk := allResults[i]["id"].(string)
jID, jOk := allResults[j]["id"].(string)
if iOk && jOk {
return iID < jID
}
return false
})
// 如果有结果,添加到硬件信息结果中
if len(allResults) > 0 {
hardwareInfo[hardwareType] = allResults
@@ -827,7 +865,9 @@ func (s *Storage) QueryDiskDetails(ctx context.Context, deviceID string, startTi
"type": record.ValueByKey("type"),
"size_gb": record.ValueByKey("size_gb"),
"model": record.ValueByKey("model"),
"vendor": record.ValueByKey("vendor"),
"interface_type": record.ValueByKey("interface_type"),
"file_system": record.ValueByKey("file_system"),
"description": record.ValueByKey("description"),
"agent_name": record.ValueByKey("agent_name"),
}