修复图表时间和查询区间不匹配问题
This commit is contained in:
96
backend/internal/collector/agent.go
Normal file
96
backend/internal/collector/agent.go
Normal file
@@ -0,0 +1,96 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
// AgentCollector Agent采集器
|
||||
type AgentCollector struct {
|
||||
agentURL string
|
||||
client *http.Client
|
||||
}
|
||||
|
||||
// AgentMetrics Agent返回的监控指标
|
||||
type AgentMetrics struct {
|
||||
CPU float64 `json:"cpu"`
|
||||
Memory float64 `json:"memory"`
|
||||
Disk float64 `json:"disk"`
|
||||
Network struct {
|
||||
BytesSent uint64 `json:"bytes_sent"`
|
||||
BytesReceived uint64 `json:"bytes_received"`
|
||||
} `json:"network"`
|
||||
}
|
||||
|
||||
// NewAgentCollector 创建新的Agent采集器
|
||||
func NewAgentCollector(agentURL string) *AgentCollector {
|
||||
return &AgentCollector{
|
||||
agentURL: agentURL,
|
||||
client: &http.Client{
|
||||
Timeout: 10 * time.Second,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// GetMetrics 获取Agent监控指标
|
||||
func (c *AgentCollector) GetMetrics() (*AgentMetrics, error) {
|
||||
// 发送HTTP请求到Agent
|
||||
resp, err := c.client.Get(fmt.Sprintf("%s/metrics", c.agentURL))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
// 检查响应状态码
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return nil, fmt.Errorf("agent returned status code %d", resp.StatusCode)
|
||||
}
|
||||
|
||||
// 读取响应体
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 解析JSON响应
|
||||
var metrics AgentMetrics
|
||||
if err := json.Unmarshal(body, &metrics); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &metrics, nil
|
||||
}
|
||||
|
||||
// GetCPUUsage 获取CPU使用率
|
||||
func (c *AgentCollector) GetCPUUsage() (float64, error) {
|
||||
metrics, err := c.GetMetrics()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return metrics.CPU, nil
|
||||
}
|
||||
|
||||
// GetMemoryUsage 获取内存使用率
|
||||
func (c *AgentCollector) GetMemoryUsage() (float64, error) {
|
||||
metrics, err := c.GetMetrics()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return metrics.Memory, nil
|
||||
}
|
||||
|
||||
// GetDiskUsage 获取磁盘使用率
|
||||
func (c *AgentCollector) GetDiskUsage(partition string) (float64, error) {
|
||||
metrics, err := c.GetMetrics()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
// 目前Agent只返回整体磁盘使用率,忽略partition参数
|
||||
return metrics.Disk, nil
|
||||
}
|
||||
89
backend/internal/collector/snmp.go
Normal file
89
backend/internal/collector/snmp.go
Normal file
@@ -0,0 +1,89 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"github.com/gosnmp/gosnmp"
|
||||
)
|
||||
|
||||
// SNMPCollector SNMP采集器
|
||||
type SNMPCollector struct {
|
||||
client *gosnmp.GoSNMP
|
||||
}
|
||||
|
||||
// NewSNMPCollector 创建新的SNMP采集器
|
||||
func NewSNMPCollector(target, community string, version gosnmp.SnmpVersion) (*SNMPCollector, error) {
|
||||
client := &gosnmp.GoSNMP{
|
||||
Target: target,
|
||||
Community: community,
|
||||
Version: version,
|
||||
Port: 161,
|
||||
}
|
||||
|
||||
// 连接SNMP设备
|
||||
if err := client.Connect(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &SNMPCollector{
|
||||
client: client,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Close 关闭SNMP连接
|
||||
func (c *SNMPCollector) Close() error {
|
||||
return c.client.Conn.Close()
|
||||
}
|
||||
|
||||
// GetCPUUsage 获取CPU使用率
|
||||
func (c *SNMPCollector) GetCPUUsage() (float64, error) {
|
||||
// 这里使用UCD-SNMP-MIB::ssCpuIdle.0 OID来获取CPU空闲率
|
||||
// 实际使用时需要根据设备类型和SNMP MIB进行调整
|
||||
oids := []string{"1.3.6.1.4.1.2021.11.11.0"}
|
||||
|
||||
result, err := c.client.Get(oids)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
// CPU使用率 = 100 - 空闲率
|
||||
idle := float64(result.Variables[0].Value.(uint))
|
||||
return 100 - idle, nil
|
||||
}
|
||||
|
||||
// GetMemoryUsage 获取内存使用率
|
||||
func (c *SNMPCollector) GetMemoryUsage() (float64, error) {
|
||||
// 这里使用UCD-SNMP-MIB::memTotalReal.0和memAvailReal.0 OID来获取内存使用情况
|
||||
oids := []string{
|
||||
"1.3.6.1.4.1.2021.4.5.0", // 总内存
|
||||
"1.3.6.1.4.1.2021.4.6.0", // 可用内存
|
||||
}
|
||||
|
||||
result, err := c.client.Get(oids)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
total := float64(result.Variables[0].Value.(uint))
|
||||
available := float64(result.Variables[1].Value.(uint))
|
||||
|
||||
return ((total - available) / total) * 100, nil
|
||||
}
|
||||
|
||||
// GetDiskUsage 获取磁盘使用率
|
||||
func (c *SNMPCollector) GetDiskUsage(partition string) (float64, error) {
|
||||
// 这里使用UCD-SNMP-MIB::dskTotal和dskAvail OID来获取磁盘使用情况
|
||||
// 实际使用时需要根据分区索引进行调整
|
||||
oids := []string{
|
||||
"1.3.6.1.4.1.2021.9.1.6.1", // 总磁盘空间
|
||||
"1.3.6.1.4.1.2021.9.1.7.1", // 可用磁盘空间
|
||||
}
|
||||
|
||||
result, err := c.client.Get(oids)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
total := float64(result.Variables[0].Value.(uint))
|
||||
available := float64(result.Variables[1].Value.(uint))
|
||||
|
||||
return ((total - available) / total) * 100, nil
|
||||
}
|
||||
131
backend/internal/collector/ssh.go
Normal file
131
backend/internal/collector/ssh.go
Normal file
@@ -0,0 +1,131 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"golang.org/x/crypto/ssh"
|
||||
)
|
||||
|
||||
// SSHCollector SSH采集器
|
||||
type SSHCollector struct {
|
||||
client *ssh.Client
|
||||
}
|
||||
|
||||
// SSHConfig SSH连接配置
|
||||
type SSHConfig struct {
|
||||
Host string
|
||||
Port int
|
||||
Username string
|
||||
Password string
|
||||
KeyPath string
|
||||
}
|
||||
|
||||
// NewSSHCollector 创建新的SSH采集器
|
||||
func NewSSHCollector(cfg *SSHConfig) (*SSHCollector, error) {
|
||||
// 构建SSH客户端配置
|
||||
sshConfig := &ssh.ClientConfig{
|
||||
User: cfg.Username,
|
||||
Auth: []ssh.AuthMethod{},
|
||||
HostKeyCallback: ssh.InsecureIgnoreHostKey(), // 生产环境中应该使用更安全的HostKeyCallback
|
||||
}
|
||||
|
||||
// 添加认证方式
|
||||
if cfg.Password != "" {
|
||||
sshConfig.Auth = append(sshConfig.Auth, ssh.Password(cfg.Password))
|
||||
}
|
||||
|
||||
// 连接SSH服务器
|
||||
addr := fmt.Sprintf("%s:%d", cfg.Host, cfg.Port)
|
||||
client, err := ssh.Dial("tcp", addr, sshConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &SSHCollector{
|
||||
client: client,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Close 关闭SSH连接
|
||||
func (c *SSHCollector) Close() error {
|
||||
return c.client.Close()
|
||||
}
|
||||
|
||||
// executeCommand 执行SSH命令
|
||||
func (c *SSHCollector) executeCommand(cmd string) (string, error) {
|
||||
// 创建SSH会话
|
||||
session, err := c.client.NewSession()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer session.Close()
|
||||
|
||||
// 执行命令并获取输出
|
||||
var stdout bytes.Buffer
|
||||
session.Stdout = &stdout
|
||||
|
||||
if err := session.Run(cmd); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return stdout.String(), nil
|
||||
}
|
||||
|
||||
// GetCPUUsage 获取CPU使用率
|
||||
func (c *SSHCollector) GetCPUUsage() (float64, error) {
|
||||
// 使用top命令获取CPU使用率
|
||||
cmd := "top -bn1 | grep 'Cpu(s)' | awk '{print $2 + $4}'"
|
||||
|
||||
output, err := c.executeCommand(cmd)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
// 解析输出
|
||||
usage, err := strconv.ParseFloat(output, 64)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return usage, nil
|
||||
}
|
||||
|
||||
// GetMemoryUsage 获取内存使用率
|
||||
func (c *SSHCollector) GetMemoryUsage() (float64, error) {
|
||||
// 使用free命令获取内存使用情况
|
||||
cmd := "free | grep Mem | awk '{print ($3/$2)*100}'"
|
||||
|
||||
output, err := c.executeCommand(cmd)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
// 解析输出
|
||||
usage, err := strconv.ParseFloat(output, 64)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return usage, nil
|
||||
}
|
||||
|
||||
// GetDiskUsage 获取磁盘使用率
|
||||
func (c *SSHCollector) GetDiskUsage(partition string) (float64, error) {
|
||||
// 使用df命令获取磁盘使用情况
|
||||
cmd := fmt.Sprintf("df -h %s | tail -1 | awk '{print $5}' | sed 's/%%//'", partition)
|
||||
|
||||
output, err := c.executeCommand(cmd)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
// 解析输出
|
||||
usage, err := strconv.ParseFloat(output, 64)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return usage, nil
|
||||
}
|
||||
Reference in New Issue
Block a user