53 lines
2.1 KiB
Go
53 lines
2.1 KiB
Go
package sqlserverproxy
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
mssql "github.com/microsoft/go-mssqldb"
|
|
"github.com/microsoft/go-mssqldb/msdsn"
|
|
"linkport/internal/model"
|
|
"linkport/internal/protocol/transport"
|
|
"net"
|
|
"strconv"
|
|
"time"
|
|
)
|
|
|
|
func (h *Handler) Monitor(ctx context.Context, p model.Proxy, dial model.DialFunc) (model.DatabaseMonitoring, error) {
|
|
out := model.DatabaseMonitoring{Metrics: []model.ServerMetric{}, Notices: []string{}}
|
|
if err := p.CheckTargetCredential(); err != nil {
|
|
return out, err
|
|
}
|
|
tls, err := transport.TLSConfig(p)
|
|
if err != nil {
|
|
return out, err
|
|
}
|
|
encryption := msdsn.Encryption(msdsn.EncryptionDisabled)
|
|
if p.TargetTLS {
|
|
encryption = msdsn.EncryptionRequired
|
|
}
|
|
c := mssql.NewConnectorConfig(msdsn.Config{Host: p.TargetHost, Port: uint64(p.TargetPort), User: p.TargetUser, Password: p.TargetPassword, Database: p.AuthSource, Encryption: encryption, TLSConfig: tls, Protocols: []string{"tcp"}, DisableRetry: true})
|
|
c.Dialer = fixedDialer{dial, net.JoinHostPort(p.TargetHost, strconv.Itoa(p.TargetPort))}
|
|
db := sql.OpenDB(c)
|
|
defer db.Close()
|
|
if err = db.PingContext(ctx); err != nil {
|
|
return out, err
|
|
}
|
|
for _, query := range []string{
|
|
"SELECT 'user_sessions', COUNT_BIG(*) FROM sys.dm_exec_sessions WHERE is_user_process = 1",
|
|
"SELECT 'active_requests', COUNT_BIG(*) FROM sys.dm_exec_requests WHERE session_id > 50",
|
|
"SELECT 'runnable_tasks', SUM(CONVERT(bigint,runnable_tasks_count)) FROM sys.dm_os_schedulers WHERE status = 'VISIBLE ONLINE'",
|
|
"SELECT 'physical_memory_in_use_kb', physical_memory_in_use_kb FROM sys.dm_os_process_memory",
|
|
} {
|
|
var name string
|
|
var value float64
|
|
if err = db.QueryRowContext(ctx, query).Scan(&name, &value); err != nil {
|
|
out.Notices = append(out.Notices, "SQL Server 部分 DMV 指标不可用,需要 VIEW SERVER STATE 或 VIEW SERVER PERFORMANCE STATE")
|
|
continue
|
|
}
|
|
out.Metrics = append(out.Metrics, model.ServerMetric{Name: name, Value: value})
|
|
}
|
|
out.Notices = append(out.Notices, "会话、请求和调度队列表示数据库压力,不等同于宿主机 CPU 百分比;未读取 Query Store 或上游慢日志。")
|
|
out.CheckedAt = time.Now().UTC()
|
|
return out, nil
|
|
}
|