mirror of
https://github.com/Syngnat/GoNavi.git
synced 2026-05-22 08:45:04 +08:00
- 后端新增监控会话管理,支持启动、停止和历史查询 - JMX、Endpoint、Agent Provider 补齐监控快照采集能力 - JMX helper 增加内存、GC、线程、类加载采样并更新内嵌运行时 - 生成 Wails 监控接口绑定并补充后端回归测试
154 lines
4.1 KiB
Go
154 lines
4.1 KiB
Go
package jvm
|
|
|
|
import (
|
|
"context"
|
|
"net/http"
|
|
"net/url"
|
|
"time"
|
|
|
|
"GoNavi-Wails/internal/connection"
|
|
)
|
|
|
|
type AgentProvider struct{}
|
|
|
|
func NewAgentProvider() Provider { return &AgentProvider{} }
|
|
|
|
func (p *AgentProvider) Mode() string { return ModeAgent }
|
|
|
|
func (p *AgentProvider) TestConnection(ctx context.Context, cfg connection.ConnectionConfig) error {
|
|
runtime, err := newAgentRuntime(cfg)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
resp, err := doContractProbe(ctx, runtime.contractRuntime, http.MethodHead)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if resp.StatusCode == http.StatusMethodNotAllowed || resp.StatusCode == http.StatusNotImplemented {
|
|
_ = resp.Body.Close()
|
|
resp, err = doContractProbe(ctx, runtime.contractRuntime, http.MethodGet)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
defer resp.Body.Close()
|
|
if isReachableStatus(resp.StatusCode) {
|
|
return nil
|
|
}
|
|
return buildContractStatusError("agent", "probe", resp)
|
|
}
|
|
|
|
func (p *AgentProvider) ProbeCapabilities(_ context.Context, cfg connection.ConnectionConfig) ([]Capability, error) {
|
|
if _, err := newAgentRuntime(cfg); err != nil {
|
|
return nil, err
|
|
}
|
|
readOnly := cfg.JVM.ReadOnly != nil && *cfg.JVM.ReadOnly
|
|
return []Capability{{
|
|
Mode: ModeAgent,
|
|
CanBrowse: true,
|
|
CanWrite: !readOnly,
|
|
CanPreview: true,
|
|
DisplayLabel: "Agent",
|
|
Reason: func() string {
|
|
if readOnly {
|
|
return "当前连接只读"
|
|
}
|
|
return ""
|
|
}(),
|
|
}}, nil
|
|
}
|
|
|
|
func (p *AgentProvider) ListResources(ctx context.Context, cfg connection.ConnectionConfig, parentPath string) ([]ResourceSummary, error) {
|
|
runtime, err := newAgentRuntime(cfg)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
query := url.Values{}
|
|
query.Set("parentPath", parentPath)
|
|
|
|
var resources []ResourceSummary
|
|
if err := runtime.doJSON(ctx, http.MethodGet, "list resources", "resources", query, nil, &resources); err != nil {
|
|
return nil, err
|
|
}
|
|
return resources, nil
|
|
}
|
|
|
|
func (p *AgentProvider) GetValue(ctx context.Context, cfg connection.ConnectionConfig, resourcePath string) (ValueSnapshot, error) {
|
|
runtime, err := newAgentRuntime(cfg)
|
|
if err != nil {
|
|
return ValueSnapshot{}, err
|
|
}
|
|
|
|
query := url.Values{}
|
|
query.Set("resourcePath", resourcePath)
|
|
|
|
var snapshot ValueSnapshot
|
|
if err := runtime.doJSON(ctx, http.MethodGet, "get value", "value", query, nil, &snapshot); err != nil {
|
|
return ValueSnapshot{}, err
|
|
}
|
|
return snapshot, nil
|
|
}
|
|
|
|
func (p *AgentProvider) GetMonitoringSnapshot(ctx context.Context, cfg connection.ConnectionConfig, previous *JVMMonitoringPoint) (JVMMonitoringSnapshot, error) {
|
|
runtime, err := newAgentRuntime(cfg)
|
|
if err != nil {
|
|
return JVMMonitoringSnapshot{}, err
|
|
}
|
|
|
|
var snapshot JVMMonitoringSnapshot
|
|
if err := runtime.doJSON(ctx, http.MethodGet, "get monitoring snapshot", "metrics", nil, nil, &snapshot); err != nil {
|
|
return JVMMonitoringSnapshot{}, err
|
|
}
|
|
finalizeMonitoringSnapshot(&snapshot, previous)
|
|
return snapshot, nil
|
|
}
|
|
|
|
func (p *AgentProvider) PreviewChange(ctx context.Context, cfg connection.ConnectionConfig, req ChangeRequest) (ChangePreview, error) {
|
|
runtime, err := newAgentRuntime(cfg)
|
|
if err != nil {
|
|
return ChangePreview{}, err
|
|
}
|
|
|
|
var preview ChangePreview
|
|
if err := runtime.doJSON(ctx, http.MethodPost, "preview change", "preview", nil, req, &preview); err != nil {
|
|
return ChangePreview{}, err
|
|
}
|
|
return preview, nil
|
|
}
|
|
|
|
func (p *AgentProvider) ApplyChange(ctx context.Context, cfg connection.ConnectionConfig, req ChangeRequest) (ApplyResult, error) {
|
|
runtime, err := newAgentRuntime(cfg)
|
|
if err != nil {
|
|
return ApplyResult{}, err
|
|
}
|
|
|
|
var result ApplyResult
|
|
if err := runtime.doJSON(ctx, http.MethodPost, "apply change", "apply", nil, req, &result); err != nil {
|
|
return ApplyResult{}, err
|
|
}
|
|
return result, nil
|
|
}
|
|
|
|
type agentRuntime struct {
|
|
contractRuntime
|
|
}
|
|
|
|
func newAgentRuntime(cfg connection.ConnectionConfig) (agentRuntime, error) {
|
|
timeout := time.Duration(cfg.JVM.Agent.TimeoutSeconds) * time.Second
|
|
if timeout <= 0 {
|
|
timeout = time.Duration(cfg.Timeout) * time.Second
|
|
}
|
|
runtime, err := newContractRuntime(
|
|
cfg.JVM.Agent.BaseURL,
|
|
cfg.JVM.Agent.APIKey,
|
|
timeout,
|
|
"agent",
|
|
)
|
|
if err != nil {
|
|
return agentRuntime{}, err
|
|
}
|
|
return agentRuntime{contractRuntime: runtime}, nil
|
|
}
|