feat: 删除不需要文件夹
This commit is contained in:
313
features/maintenance/maintenance.go
Normal file
313
features/maintenance/maintenance.go
Normal file
@@ -0,0 +1,313 @@
|
||||
package maintenance
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
"runtime"
|
||||
"time"
|
||||
|
||||
"ems.agt/lib/core/utils/ctx"
|
||||
"ems.agt/lib/dborm"
|
||||
"ems.agt/lib/log"
|
||||
"ems.agt/lib/services"
|
||||
"ems.agt/restagent/config"
|
||||
"github.com/shirou/gopsutil/cpu"
|
||||
"github.com/shirou/gopsutil/disk"
|
||||
"github.com/shirou/gopsutil/mem"
|
||||
)
|
||||
|
||||
// (1) OMC能够对相关的文件系统资源、内存、CPU资源、数据存储空间、数据库空间等系统指标进行监控管理;
|
||||
// 对于虚拟化部署OMC系统,能够对虚机内存、虚机CPU、虚拟存储空间、文件系统资源、数据库空间等指标进行监控,提供界面截图 ;
|
||||
|
||||
// (2) 系统监控指标的采样时间和阈值可由用户设定,超过阈值将产生不同级别的告警,提供界面截图 ;
|
||||
|
||||
// (3) OMC能够方便的查询数据库连接情况;并可手工干预数据库的连接,能方便的终结非法的数据库连接 ;
|
||||
|
||||
// (4) 用户能方便的查询系统进程、应用进程等的进程名、进程类型、开始时间、运行主机等信息,提供界面截图
|
||||
// (5) 用户能方便的对系统进程、应用进程等做中断或者启动操作,提供界面截图
|
||||
|
||||
// (6) 对于文件系统资源、内存、CPU资源、数据存储空间、数据库空间等系统指标数据,要求OMC能够保存至少3个月,提供界面截图 ;
|
||||
// (7) 用户可以按照需求自定义报表模板并生成OMC系统维护数据报表,提供界面截图 ;
|
||||
|
||||
// (8) OMC具备自身告警管理功能,对于传统OMC系统,如:服务器单电源告警,存储硬盘告警、OMC系统软件故障等;
|
||||
// 对于虚拟化OMC系统,如虚机告警、虚拟硬盘告警等,提供界面截图 。
|
||||
|
||||
var (
|
||||
// parameter config management
|
||||
Uri = config.UriPrefix + "/maintenance/{apiVersion}/zz"
|
||||
|
||||
// (1) OMC能够对相关的文件系统资源、内存、CPU资源、数据存储空间、数据库空间等系统指标进行监控管理;
|
||||
UriPref = config.UriPrefix + "/maintenance/{apiVersion}/pref"
|
||||
|
||||
// (6) 对于文件系统资源、内存、CPU资源、数据存储空间、数据库空间等系统指标数据,要求OMC能够保存至少3个月,提供界面截图 ;
|
||||
UriPrefLog = config.UriPrefix + "/maintenance/{apiVersion}/prefLog"
|
||||
|
||||
// (2) 系统监控指标的采样时间和阈值可由用户设定,超过阈值将产生不同级别的告警,提供界面截图 ;
|
||||
UriConfig = config.UriPrefix + "/maintenance/{apiVersion}/config"
|
||||
|
||||
// (3) OMC能够方便的查询数据库连接情况;并可手工干预数据库的连接,能方便的终结非法的数据库连接
|
||||
UriSqlClient = config.UriPrefix + "/maintenance/{apiVersion}/sqlClient"
|
||||
|
||||
// (4) 用户能方便的查询系统进程、应用进程等的进程名、进程类型、开始时间、运行主机等信息,提供界面截图
|
||||
// (5) 用户能方便的对系统进程、应用进程等做中断或者启动操作,提供界面截图
|
||||
UriTop = config.UriPrefix + "/maintenance/{apiVersion}/top"
|
||||
)
|
||||
|
||||
func init() {
|
||||
// 定時收集 TODO
|
||||
prefLogSave("")
|
||||
}
|
||||
|
||||
func List(w http.ResponseWriter, r *http.Request) {
|
||||
fmt.Println("zz List")
|
||||
services.ResponseStatusOK200Null(w)
|
||||
}
|
||||
|
||||
// 性能指標
|
||||
func prefInfo(dirName string) map[string]any {
|
||||
data := make(map[string]any)
|
||||
|
||||
// 显示文件資源目录
|
||||
dirPath := "D://"
|
||||
if runtime.GOOS == "linux" {
|
||||
dirPath = "/home"
|
||||
}
|
||||
// 訪問下級
|
||||
if dirName != "" {
|
||||
dirPath = path.Join(dirPath, dirName)
|
||||
}
|
||||
dir_list, e := os.ReadDir(dirPath)
|
||||
if e != nil {
|
||||
log.Error(e)
|
||||
}
|
||||
list := make([]map[string]any, 0)
|
||||
for _, v := range dir_list {
|
||||
o, err := v.Info()
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
list = append(list, map[string]any{
|
||||
"name": o.Name(),
|
||||
"size": o.Size(),
|
||||
"mode": o.Mode().String(),
|
||||
"modTime": o.ModTime().Format("2006-01-02 15:04:05"),
|
||||
"isDir": o.IsDir(),
|
||||
})
|
||||
}
|
||||
data["dirList"] = list
|
||||
|
||||
// 文件資源使用率
|
||||
u, _ := disk.Usage(dirPath)
|
||||
usedGB := int(u.Used) / (1024 * 1024 * 1024 * 1)
|
||||
data["dirUse"] = fmt.Sprintf("%d", usedGB)
|
||||
|
||||
// CPU使用率
|
||||
percent, err := cpu.Percent(time.Second, false)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
data["cpuUse"] = fmt.Sprintf("%.2f", percent[0])
|
||||
|
||||
// 内存使用率
|
||||
memInfo, err := mem.VirtualMemory()
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
data["memUse"] = memInfo.UsedPercent
|
||||
|
||||
// 獲取數據庫占用空間
|
||||
if dborm.DbClient.XEngine != nil {
|
||||
conf := config.GetYamlConfig()
|
||||
result, err := dborm.DbClient.XEngine.QueryString(`SELECT
|
||||
CONCAT(TRUNCATE(SUM(data_length)/1024/1024,2),'MB') AS data_size,
|
||||
CONCAT(TRUNCATE(SUM(max_data_length)/1024/1024,2),'MB') AS max_data_size,
|
||||
CONCAT(TRUNCATE(SUM(data_free)/1024/1024,2),'MB') AS data_free,
|
||||
CONCAT(TRUNCATE(SUM(index_length)/1024/1024,2),'MB') AS index_size
|
||||
FROM information_schema.tables WHERE TABLE_SCHEMA = ?;
|
||||
`, conf.Database.Name)
|
||||
if err == nil {
|
||||
data["dbInfo"] = result[0]
|
||||
} else {
|
||||
data["dbInfo"] = map[string]string{}
|
||||
}
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
// 性能指標存入數據庫
|
||||
func prefLogSave(dirName string) {
|
||||
if dborm.DbClient.XEngine != nil {
|
||||
data := prefInfo(dirName)
|
||||
|
||||
dirListByte, err := json.Marshal(data["dirList"])
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
dbInfoByte, err := json.Marshal(data["dbInfo"])
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
rse, err := dborm.DbClient.XEngine.Exec(`INSERT INTO sys_perf_data
|
||||
(id, create_time, dir_used, dir_list, db_info, mem_used, cpu_used)
|
||||
VALUES(NULL, NOW(), ?, ?, ?, ?, ?);
|
||||
`, data["dirUse"], string(dirListByte), string(dbInfoByte), data["memUse"], data["cpuUse"])
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
fmt.Println(rse.LastInsertId())
|
||||
}
|
||||
}
|
||||
|
||||
// GET http://192.168.21.183:3040/api/rest/maintenance/v1/pref?dir=true
|
||||
func Pref(w http.ResponseWriter, r *http.Request) {
|
||||
// 知道下級文件資源目录
|
||||
dirName := r.URL.Query().Get("dirName")
|
||||
data := prefInfo(dirName)
|
||||
services.ResponseWithJson(w, http.StatusOK, data)
|
||||
}
|
||||
|
||||
// POST http://192.168.21.183:3040/api/rest/maintenance/v1/config
|
||||
func Config(w http.ResponseWriter, r *http.Request) {
|
||||
// json 請求參數獲取
|
||||
var bodyArgs struct {
|
||||
Key string `json:"key"`
|
||||
Value string `json:"value"`
|
||||
}
|
||||
err := ctx.ShouldBindJSON(r, &bodyArgs)
|
||||
if err != nil {
|
||||
log.Error("io.ReadAll is failed:", err)
|
||||
services.ResponseNotFound404UriNotExist(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
// 進行值更新
|
||||
if dborm.DbClient.XEngine != nil {
|
||||
result, err := dborm.DbClient.XEngine.QueryString("SELECT * FROM information_schema.processlist")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
fmt.Println(result)
|
||||
rse, err := dborm.DbClient.XEngine.Exec("UPDATE sys_config SET value = ? where id = ?", "true", 100)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
fmt.Println(rse)
|
||||
}
|
||||
|
||||
services.ResponseStatusOK200Null(w)
|
||||
}
|
||||
|
||||
// http://192.168.21.183:3040/api/rest/maintenance/v1/sqlClient?type=close
|
||||
// http://192.168.21.183:3040/api/rest/maintenance/v1/sqlClient?type=connet
|
||||
// http://192.168.21.183:3040/api/rest/maintenance/v1/sqlClient?type=user
|
||||
func SqlClient(w http.ResponseWriter, r *http.Request) {
|
||||
// 关闭
|
||||
isClose := r.URL.Query().Get("type")
|
||||
if isClose == "close" && dborm.DbClient.XEngine != nil {
|
||||
dborm.DbClient.XEngine.Close()
|
||||
}
|
||||
|
||||
// 重连
|
||||
isConnet := r.URL.Query().Get("type")
|
||||
if isConnet == "connet" && dborm.DbClient.XEngine == nil {
|
||||
conf := config.GetYamlConfig()
|
||||
err := dborm.InitDbClient(conf.Database.Type, conf.Database.User, conf.Database.Password,
|
||||
conf.Database.Host, conf.Database.Port, conf.Database.Name)
|
||||
if err != nil {
|
||||
fmt.Println("dborm.initDbClient err:", err)
|
||||
services.ResponseInternalServerError500DatabaseOperationFailed(w)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 查询实例
|
||||
isUser := r.URL.Query().Get("type")
|
||||
if isUser == "user" && dborm.DbClient.XEngine != nil {
|
||||
result, err := dborm.DbClient.XEngine.QueryString("SELECT * FROM information_schema.processlist")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
fmt.Println(result)
|
||||
rse, err := dborm.DbClient.XEngine.Exec("KILL CONNECTION CONNECTION_ID()")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
fmt.Println(rse)
|
||||
}
|
||||
|
||||
// 进行连接测试
|
||||
err := dborm.DbClient.XEngine.Ping()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
services.ResponseStatusOK200Null(w)
|
||||
}
|
||||
|
||||
// GET http://192.168.21.183:3040/api/rest/maintenance/v1/top?grep=
|
||||
func Top(w http.ResponseWriter, r *http.Request) {
|
||||
// 過濾命令
|
||||
grep := r.URL.Query().Get("grep")
|
||||
// 命令拼接
|
||||
var cmd *exec.Cmd
|
||||
switch runtime.GOOS {
|
||||
case "linux":
|
||||
command := "ps -ef "
|
||||
if grep != "" {
|
||||
command += grep
|
||||
}
|
||||
cmd = exec.Command(command)
|
||||
case "windows":
|
||||
command := "wmic process list brief "
|
||||
if grep != "" {
|
||||
command += grep
|
||||
}
|
||||
cmd = exec.Command("cmd", "/C", command)
|
||||
}
|
||||
|
||||
out, err := cmd.CombinedOutput()
|
||||
fmt.Println(string(out))
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
services.ResponseWithJson(w, http.StatusOK, string(out))
|
||||
}
|
||||
|
||||
// PATCH http://192.168.21.183:3040/api/rest/maintenance/v1/top?ops=&name=
|
||||
func TopOps(w http.ResponseWriter, r *http.Request) {
|
||||
// json 請求參數獲取
|
||||
var bodyArgs struct {
|
||||
Ops string `json:"ops"`
|
||||
Pid string `json:"pid"`
|
||||
}
|
||||
err := ctx.ShouldBindJSON(r, &bodyArgs)
|
||||
if err != nil {
|
||||
log.Error("io.ReadAll is failed:", err)
|
||||
services.ResponseNotFound404UriNotExist(w, r)
|
||||
return
|
||||
}
|
||||
// 命令拼接
|
||||
var cmd *exec.Cmd
|
||||
switch runtime.GOOS {
|
||||
case "linux":
|
||||
switch bodyArgs.Ops {
|
||||
case "kill":
|
||||
cmd = exec.Command("kill", "-9", bodyArgs.Pid)
|
||||
}
|
||||
case "windows":
|
||||
switch bodyArgs.Ops {
|
||||
case "kill":
|
||||
cmd = exec.Command("cmd", "/C", "taskkill", "-PID", bodyArgs.Pid, "-F")
|
||||
}
|
||||
}
|
||||
|
||||
out, err := cmd.CombinedOutput()
|
||||
fmt.Println(string(out))
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
services.ResponseWithJson(w, http.StatusOK, string(out))
|
||||
}
|
||||
Reference in New Issue
Block a user