Инициализация проекта
Стабильный рабочий проект.
This commit is contained in:
46
Backend/admin/go/admin_server.go
Normal file
46
Backend/admin/go/admin_server.go
Normal file
@@ -0,0 +1,46 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
command "vServer/Backend/admin/go/command"
|
||||
config "vServer/Backend/config"
|
||||
tools "vServer/Backend/tools"
|
||||
)
|
||||
|
||||
var adminServer *http.Server
|
||||
|
||||
// Запуск Admin сервера
|
||||
func StartAdmin() {
|
||||
|
||||
// Получаем значения из конфига во время выполнения
|
||||
port_admin := config.ConfigData.Soft_Settings.Admin_port
|
||||
host_admin := config.ConfigData.Soft_Settings.Admin_host
|
||||
|
||||
if tools.Port_check("ADMIN", host_admin, port_admin) {
|
||||
return
|
||||
}
|
||||
|
||||
// Создаем оптимизированный мультиплексор для админ сервера
|
||||
mux := http.NewServeMux()
|
||||
|
||||
// Регистрируем специализированные обработчики (быстрая маршрутизация)
|
||||
mux.HandleFunc("/api/", command.ApiHandler) // API эндпоинты
|
||||
mux.HandleFunc("/json/", command.JsonHandler) // JSON данные
|
||||
mux.HandleFunc("/service/", command.ServiceHandler) // Сервисные команды POST
|
||||
mux.HandleFunc("/", command.StaticHandler) // Статические файлы
|
||||
|
||||
// Создаем Admin сервер (только localhost для безопасности)
|
||||
adminServer = &http.Server{
|
||||
Addr: host_admin + ":" + port_admin,
|
||||
Handler: mux,
|
||||
}
|
||||
|
||||
tools.Logs_file(0, "ADMIN", "🛠️ Admin панель запущена на порту "+port_admin, "logs_http.log", true)
|
||||
|
||||
if err := adminServer.ListenAndServe(); err != nil {
|
||||
// Игнорируем нормальную ошибку при остановке сервера
|
||||
if err.Error() != "http: Server closed" {
|
||||
tools.Logs_file(1, "ADMIN", "❌ Ошибка запуска админ сервера: "+err.Error(), "logs_http.log", true)
|
||||
}
|
||||
}
|
||||
}
|
122
Backend/admin/go/command/commands.go
Normal file
122
Backend/admin/go/command/commands.go
Normal file
@@ -0,0 +1,122 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"io/fs"
|
||||
"net/http"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
webserver "vServer/Backend/WebServer"
|
||||
admin "vServer/Backend/admin"
|
||||
json "vServer/Backend/admin/go/json"
|
||||
)
|
||||
|
||||
func SecurePost(w http.ResponseWriter, r *http.Request) bool {
|
||||
// Проверяем, что запрос POST (не GET из браузера)
|
||||
|
||||
if webserver.Secure_post {
|
||||
|
||||
if r.Method != "POST" {
|
||||
http.Error(w, "Метод не разрешен. Используйте POST", http.StatusMethodNotAllowed)
|
||||
return false
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// API обработчик для /api/*
|
||||
func ApiHandler(w http.ResponseWriter, r *http.Request) {
|
||||
path := r.URL.Path
|
||||
|
||||
switch path {
|
||||
case "/api/metrics":
|
||||
json.GetAllMetrics(w)
|
||||
default:
|
||||
http.NotFound(w, r)
|
||||
}
|
||||
}
|
||||
|
||||
// JSON обработчик для /json/*
|
||||
func JsonHandler(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
path := r.URL.Path
|
||||
|
||||
switch path {
|
||||
case "/json/server_status.json":
|
||||
w.Write(json.GetServerStatusJSON())
|
||||
case "/json/menu.json":
|
||||
w.Write(json.GetMenuJSON())
|
||||
default:
|
||||
http.NotFound(w, r)
|
||||
}
|
||||
}
|
||||
|
||||
// Обработчик сервисных команд для /service/*
|
||||
func ServiceHandler(w http.ResponseWriter, r *http.Request) {
|
||||
path := r.URL.Path
|
||||
|
||||
if !SecurePost(w, r) {
|
||||
return
|
||||
}
|
||||
|
||||
if SiteList(w, r, path) {
|
||||
return
|
||||
}
|
||||
|
||||
if site_add(w, path) {
|
||||
return
|
||||
}
|
||||
|
||||
if Service_Run(w, r, path) {
|
||||
return
|
||||
}
|
||||
http.NotFound(w, r)
|
||||
}
|
||||
|
||||
// Обработчик статических файлов из embed
|
||||
func StaticHandler(w http.ResponseWriter, r *http.Request) {
|
||||
path := r.URL.Path
|
||||
|
||||
// Убираем ведущий слэш
|
||||
path = strings.TrimPrefix(path, "/")
|
||||
|
||||
// Если пустой путь, показываем index.html
|
||||
if path == "" {
|
||||
path = "html/index.html"
|
||||
} else {
|
||||
path = "html/" + path
|
||||
}
|
||||
|
||||
// Читаем файл из файловой системы (embed или диск)
|
||||
fileSystem := admin.GetFileSystem()
|
||||
content, err := fs.ReadFile(fileSystem, path)
|
||||
if err != nil {
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
// Устанавливаем правильный Content-Type
|
||||
ext := filepath.Ext(path)
|
||||
switch ext {
|
||||
case ".css":
|
||||
w.Header().Set("Content-Type", "text/css")
|
||||
case ".js":
|
||||
w.Header().Set("Content-Type", "application/javascript")
|
||||
case ".json":
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
case ".html":
|
||||
w.Header().Set("Content-Type", "text/html")
|
||||
}
|
||||
|
||||
// Предотвращаем кеширование в режиме разработки (когда UseEmbedded = false)
|
||||
if !admin.UseEmbedded {
|
||||
w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
|
||||
w.Header().Set("Pragma", "no-cache")
|
||||
w.Header().Set("Expires", "0")
|
||||
}
|
||||
|
||||
// Отдаем файл
|
||||
w.Write(content)
|
||||
|
||||
}
|
57
Backend/admin/go/command/service_run.go
Normal file
57
Backend/admin/go/command/service_run.go
Normal file
@@ -0,0 +1,57 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
webserver "vServer/Backend/WebServer"
|
||||
json "vServer/Backend/admin/go/json"
|
||||
)
|
||||
|
||||
// Обработчик команд управления серверами
|
||||
func Service_Run(w http.ResponseWriter, r *http.Request, path string) bool {
|
||||
|
||||
switch path {
|
||||
case "/service/MySql_Stop":
|
||||
webserver.StopMySQLServer()
|
||||
json.UpdateServerStatus("MySQL Server", "stopped")
|
||||
return true
|
||||
|
||||
case "/service/MySql_Start":
|
||||
webserver.StartMySQLServer(false)
|
||||
json.UpdateServerStatus("MySQL Server", "running")
|
||||
return true
|
||||
|
||||
case "/service/Http_Stop":
|
||||
webserver.StopHTTPServer()
|
||||
json.UpdateServerStatus("HTTP Server", "stopped")
|
||||
return true
|
||||
|
||||
case "/service/Http_Start":
|
||||
go webserver.StartHTTP()
|
||||
json.UpdateServerStatus("HTTP Server", "running")
|
||||
return true
|
||||
|
||||
case "/service/Https_Stop":
|
||||
webserver.StopHTTPSServer()
|
||||
json.UpdateServerStatus("HTTPS Server", "stopped")
|
||||
return true
|
||||
|
||||
case "/service/Https_Start":
|
||||
go webserver.StartHTTPS()
|
||||
json.UpdateServerStatus("HTTPS Server", "running")
|
||||
return true
|
||||
|
||||
case "/service/Php_Start":
|
||||
webserver.PHP_Start()
|
||||
json.UpdateServerStatus("PHP Server", "running")
|
||||
return true
|
||||
|
||||
case "/service/Php_Stop":
|
||||
webserver.PHP_Stop()
|
||||
json.UpdateServerStatus("PHP Server", "stopped")
|
||||
return true
|
||||
|
||||
default:
|
||||
http.NotFound(w, r)
|
||||
return false // Команда не найдена
|
||||
}
|
||||
}
|
269
Backend/admin/go/command/site_list.go
Normal file
269
Backend/admin/go/command/site_list.go
Normal file
@@ -0,0 +1,269 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"os"
|
||||
"regexp"
|
||||
"strings"
|
||||
"vServer/Backend/config"
|
||||
"vServer/Backend/tools"
|
||||
)
|
||||
|
||||
var entries []os.DirEntry
|
||||
|
||||
func path_www() {
|
||||
|
||||
wwwPath, err := tools.AbsPath("WebServer/www")
|
||||
tools.Error_check(err, "Ошибка получения пути")
|
||||
|
||||
entries, err = os.ReadDir(wwwPath)
|
||||
tools.Error_check(err, "Ошибка чтения директории")
|
||||
|
||||
}
|
||||
|
||||
func site_type(entry os.DirEntry) string {
|
||||
|
||||
certPath, err := tools.AbsPath("WebServer/cert/" + entry.Name())
|
||||
if err == nil {
|
||||
if _, err := os.Stat(certPath); err == nil {
|
||||
return "https"
|
||||
}
|
||||
}
|
||||
return "http"
|
||||
}
|
||||
|
||||
func site_alliace(siteName string) []string {
|
||||
// Получаем абсолютный путь к config.json
|
||||
configPath, err := tools.AbsPath("WebServer/config.json")
|
||||
tools.Error_check(err, "Ошибка получения пути к config.json")
|
||||
|
||||
// Читаем содержимое config.json
|
||||
configData, err := os.ReadFile(configPath)
|
||||
tools.Error_check(err, "Ошибка чтения config.json")
|
||||
|
||||
// Структура для парсинга Site_www
|
||||
type SiteConfig struct {
|
||||
Name string `json:"name"`
|
||||
Host string `json:"host"`
|
||||
Alias []string `json:"alias"`
|
||||
Status string `json:"status"`
|
||||
}
|
||||
type Config struct {
|
||||
SiteWWW []SiteConfig `json:"Site_www"`
|
||||
}
|
||||
|
||||
var config Config
|
||||
err = json.Unmarshal(configData, &config)
|
||||
tools.Error_check(err, "Ошибка парсинга config.json")
|
||||
|
||||
// Ищем алиасы для конкретного сайта
|
||||
for _, site := range config.SiteWWW {
|
||||
if site.Host == siteName {
|
||||
return site.Alias
|
||||
}
|
||||
}
|
||||
|
||||
// Возвращаем пустой массив если сайт не найден
|
||||
return []string{}
|
||||
}
|
||||
|
||||
func site_status(siteName string) string {
|
||||
configPath := "WebServer/config.json"
|
||||
|
||||
// Читаем конфигурационный файл
|
||||
data, err := os.ReadFile(configPath)
|
||||
if err != nil {
|
||||
return "error"
|
||||
}
|
||||
|
||||
// Парсим JSON
|
||||
var config map[string]interface{}
|
||||
if err := json.Unmarshal(data, &config); err != nil {
|
||||
return "error"
|
||||
}
|
||||
|
||||
// Получаем список сайтов
|
||||
siteWww, ok := config["Site_www"].([]interface{})
|
||||
if !ok {
|
||||
return "error"
|
||||
}
|
||||
|
||||
// Ищем сайт по host
|
||||
for _, siteInterface := range siteWww {
|
||||
site, ok := siteInterface.(map[string]interface{})
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
// Проверяем только по host (имя папки)
|
||||
if host, ok := site["host"].(string); ok && host == siteName {
|
||||
if status, ok := site["status"].(string); ok {
|
||||
return status
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return "inactive"
|
||||
}
|
||||
|
||||
func SiteList(w http.ResponseWriter, r *http.Request, path string) bool {
|
||||
|
||||
switch path {
|
||||
|
||||
case "/service/Site_List":
|
||||
sites := []map[string]interface{}{}
|
||||
|
||||
path_www()
|
||||
|
||||
for _, entry := range entries {
|
||||
if entry.IsDir() {
|
||||
site := map[string]interface{}{
|
||||
"host": entry.Name(),
|
||||
"type": site_type(entry),
|
||||
"aliases": site_alliace(entry.Name()),
|
||||
"status": site_status(entry.Name()),
|
||||
}
|
||||
sites = append(sites, site)
|
||||
}
|
||||
}
|
||||
|
||||
metrics := map[string]interface{}{
|
||||
"sites": sites,
|
||||
}
|
||||
|
||||
data, _ := json.MarshalIndent(metrics, "", " ")
|
||||
w.Write(data)
|
||||
|
||||
return true
|
||||
|
||||
}
|
||||
|
||||
return false
|
||||
|
||||
}
|
||||
|
||||
func addSiteToConfig(siteName string) error {
|
||||
// Получаем абсолютный путь к config.json
|
||||
configPath, err := tools.AbsPath("WebServer/config.json")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Читаем содержимое config.json
|
||||
configData, err := os.ReadFile(configPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Парсим как общий JSON объект
|
||||
var config map[string]interface{}
|
||||
err = json.Unmarshal(configData, &config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Получаем массив сайтов
|
||||
siteWWW, ok := config["Site_www"].([]interface{})
|
||||
if !ok {
|
||||
siteWWW = []interface{}{}
|
||||
}
|
||||
|
||||
// Создаем новый сайт в том же формате что уже есть
|
||||
newSite := map[string]interface{}{
|
||||
"name": siteName,
|
||||
"host": siteName,
|
||||
"alias": []string{""},
|
||||
"status": "active",
|
||||
}
|
||||
|
||||
// Добавляем новый сайт в массив
|
||||
config["Site_www"] = append(siteWWW, newSite)
|
||||
|
||||
// Сохраняем обновленный конфиг
|
||||
updatedData, err := json.MarshalIndent(config, "", " ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Делаем массивы алиасов в одну строку
|
||||
re := regexp.MustCompile(`"alias": \[\s+"([^"]*?)"\s+\]`)
|
||||
compactData := re.ReplaceAll(updatedData, []byte(`"alias": ["$1"]`))
|
||||
|
||||
// Исправляем отступы после Site_www
|
||||
dataStr := string(compactData)
|
||||
dataStr = strings.ReplaceAll(dataStr, ` ],
|
||||
"Soft_Settings"`, ` ],
|
||||
|
||||
"Soft_Settings"`)
|
||||
compactData = []byte(dataStr)
|
||||
|
||||
err = os.WriteFile(configPath, compactData, 0644)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func site_add(w http.ResponseWriter, path string) bool {
|
||||
|
||||
// URL параметры: /service/Site_Add/sitename
|
||||
if strings.HasPrefix(path, "/service/Site_Add/") {
|
||||
siteName := strings.TrimPrefix(path, "/service/Site_Add/")
|
||||
|
||||
if siteName == "" {
|
||||
w.WriteHeader(400)
|
||||
w.Write([]byte(`{"status":"error","message":"Не указано имя сайта в URL"}`))
|
||||
return true
|
||||
}
|
||||
|
||||
wwwPath := "WebServer/www/" + siteName
|
||||
|
||||
// Проверяем существует ли уже такой сайт
|
||||
if _, err := os.Stat(wwwPath); err == nil {
|
||||
w.WriteHeader(409) // Conflict
|
||||
w.Write([]byte(`{"status":"error","message":"Сайт ` + siteName + ` уже существует"}`))
|
||||
return true
|
||||
}
|
||||
|
||||
err := os.MkdirAll(wwwPath, 0755)
|
||||
if err != nil {
|
||||
w.WriteHeader(500)
|
||||
w.Write([]byte(`{"status":"error","message":"Ошибка создания папки сайта"}`))
|
||||
return true
|
||||
}
|
||||
|
||||
// Добавляем сайт в config.json
|
||||
err = addSiteToConfig(siteName)
|
||||
if err != nil {
|
||||
w.WriteHeader(500)
|
||||
w.Write([]byte(`{"status":"error","message":"Ошибка добавления в конфигурацию: ` + err.Error() + `"}`))
|
||||
return true
|
||||
}
|
||||
|
||||
// Создаем папку public_www
|
||||
publicWwwPath := wwwPath + "/public_www"
|
||||
err = os.MkdirAll(publicWwwPath, 0755)
|
||||
if err != nil {
|
||||
w.WriteHeader(500)
|
||||
w.Write([]byte(`{"status":"error","message":"Ошибка создания папки public_www"}`))
|
||||
return true
|
||||
}
|
||||
|
||||
indexFilePath := wwwPath + "/public_www/index.html"
|
||||
indexContent := "Привет друг! Твой сайт создан!"
|
||||
err = os.WriteFile(indexFilePath, []byte(indexContent), 0644)
|
||||
if err != nil {
|
||||
w.WriteHeader(500)
|
||||
w.Write([]byte(`{"status":"error","message":"Ошибка создания index.html: ` + err.Error() + `"}`))
|
||||
return true
|
||||
}
|
||||
|
||||
w.Write([]byte(`{"status":"ok","message":"Сайт ` + siteName + ` успешно создан и добавлен в конфигурацию"}`))
|
||||
config.LoadConfig()
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
45
Backend/admin/go/json/json.go
Normal file
45
Backend/admin/go/json/json.go
Normal file
@@ -0,0 +1,45 @@
|
||||
package json
|
||||
|
||||
import "encoding/json"
|
||||
|
||||
// Данные серверов
|
||||
var ServerStatus = []map[string]interface{}{
|
||||
{"NameService": "HTTP Server", "Port": 80, "Status": "stopped"},
|
||||
{"NameService": "HTTPS Server", "Port": 443, "Status": "stopped"},
|
||||
{"NameService": "PHP Server", "Port": 9000, "Status": "stopped"},
|
||||
{"NameService": "MySQL Server", "Port": 3306, "Status": "stopped"},
|
||||
}
|
||||
|
||||
// Данные меню
|
||||
var MenuData = []map[string]interface{}{
|
||||
{"name": "Dashboard", "icon": "🏠", "url": "#dashboard", "active": true},
|
||||
{"name": "Серверы", "icon": "🖥️", "url": "#servers", "active": false},
|
||||
{"name": "Сайты", "icon": "🌐", "url": "#sites", "active": false},
|
||||
{"name": "SSL Сертификаты", "icon": "🔒", "url": "#certificates", "active": false},
|
||||
{"name": "Файловый менеджер", "icon": "📁", "url": "#files", "active": false},
|
||||
{"name": "Базы данных", "icon": "🗄️", "url": "#databases", "active": false},
|
||||
{"name": "Логи", "icon": "📋", "url": "#logs", "active": false},
|
||||
{"name": "Настройки", "icon": "⚙️", "url": "#settings", "active": false},
|
||||
}
|
||||
|
||||
// Функция обновления статуса сервера
|
||||
func UpdateServerStatus(serviceName, status string) {
|
||||
for i := range ServerStatus {
|
||||
if ServerStatus[i]["NameService"] == serviceName {
|
||||
ServerStatus[i]["Status"] = status
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Получить JSON серверов
|
||||
func GetServerStatusJSON() []byte {
|
||||
data, _ := json.Marshal(ServerStatus)
|
||||
return data
|
||||
}
|
||||
|
||||
// Получить JSON меню
|
||||
func GetMenuJSON() []byte {
|
||||
data, _ := json.Marshal(MenuData)
|
||||
return data
|
||||
}
|
130
Backend/admin/go/json/metrics.go
Normal file
130
Backend/admin/go/json/metrics.go
Normal file
@@ -0,0 +1,130 @@
|
||||
package json
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
"vServer/Backend/tools"
|
||||
)
|
||||
|
||||
var CPU_NAME string
|
||||
var CPU_GHz string
|
||||
var CPU_Cores string
|
||||
var CPU_Using string
|
||||
var Disk_Size string
|
||||
var Disk_Free string
|
||||
var Disk_Used string
|
||||
var Disk_Name string
|
||||
var RAM_Using string
|
||||
var RAM_Total string
|
||||
|
||||
// Инициализация при запуске пакета
|
||||
func init() {
|
||||
// Загружаем статичные данные один раз при старте
|
||||
UpdateMetrics()
|
||||
// Загружаем динамические данные в фоне
|
||||
go updateMetricsBackground()
|
||||
}
|
||||
|
||||
func UpdateMetrics() {
|
||||
commands := []string{
|
||||
`$name = (Get-WmiObject Win32_DiskDrive | Where-Object { $_.Index -eq (Get-WmiObject Win32_DiskPartition | Where-Object { $_.DeviceID -eq ((Get-WmiObject Win32_LogicalDiskToPartition | Where-Object { $_.Dependent -match "C:" }).Antecedent -split '"')[1] }).DiskIndex }).Model`,
|
||||
`$size = "{0} GB" -f [math]::Round(((Get-PSDrive -Name C).Used + (Get-PSDrive -Name C).Free) / 1GB)`,
|
||||
"$cpuInfo = Get-CimInstance Win32_Processor",
|
||||
"$cpuCores = $cpuInfo.NumberOfCores",
|
||||
"$cpuName = $cpuInfo.Name",
|
||||
`$ram_total = [math]::Round((Get-CimInstance Win32_ComputerSystem).TotalPhysicalMemory / 1GB, 2)`,
|
||||
"Write-Output \"$cpuName|$cpuCores|$name|$size|$ram_total\"",
|
||||
}
|
||||
|
||||
// Выполняем команды и получаем результат
|
||||
result := tools.RunPersistentScript(commands)
|
||||
|
||||
// Парсим результат для статичных данных
|
||||
parts := strings.Split(result, "|")
|
||||
if len(parts) >= 4 {
|
||||
cpuName := strings.TrimSpace(parts[0])
|
||||
cpuCores := strings.TrimSpace(parts[1])
|
||||
diskName := strings.TrimSpace(parts[2])
|
||||
diskSize := strings.TrimSpace(parts[3])
|
||||
ramTotal := strings.TrimSpace(parts[4])
|
||||
|
||||
// Обновляем глобальные переменные
|
||||
CPU_NAME = cpuName
|
||||
CPU_Cores = cpuCores
|
||||
Disk_Name = diskName
|
||||
Disk_Size = diskSize
|
||||
RAM_Total = ramTotal
|
||||
}
|
||||
}
|
||||
|
||||
// Фоновое обновление динамических метрик (внутреннее)
|
||||
func updateMetricsBackground() {
|
||||
|
||||
updateDynamicMetrics := func() {
|
||||
commands := []string{
|
||||
"$cpuInfo = Get-CimInstance Win32_Processor",
|
||||
"$cpuGHz = $cpuInfo.MaxClockSpeed",
|
||||
"$cpuUsage = $cpuInfo.LoadPercentage",
|
||||
`$used = "{0} GB" -f [math]::Round(((Get-PSDrive -Name C).Used / 1GB))`,
|
||||
`$free = "{0} GB" -f [math]::Round(((Get-PSDrive -Name C).Free / 1GB))`,
|
||||
`$ram_using = [math]::Round((Get-CimInstance Win32_OperatingSystem | % {($_.TotalVisibleMemorySize - $_.FreePhysicalMemory) / 1MB}), 2)`,
|
||||
"Write-Output \"$cpuGHz|$cpuUsage|$used|$free|$ram_using\"",
|
||||
}
|
||||
|
||||
// Один запуск PowerShell для динамических команд!
|
||||
result := tools.RunPersistentScript(commands)
|
||||
|
||||
// Парсим результат для динамических данных
|
||||
parts := strings.Split(result, "|")
|
||||
if len(parts) >= 4 {
|
||||
cpuGHz := strings.TrimSpace(parts[0])
|
||||
cpuUsage := strings.TrimSpace(parts[1])
|
||||
diskUsed := strings.TrimSpace(parts[2])
|
||||
diskFree := strings.TrimSpace(parts[3])
|
||||
ramUsing := strings.TrimSpace(parts[4])
|
||||
// Обновляем глобальные переменные
|
||||
CPU_GHz = cpuGHz
|
||||
CPU_Using = cpuUsage
|
||||
Disk_Used = diskUsed
|
||||
Disk_Free = diskFree
|
||||
RAM_Using = ramUsing
|
||||
}
|
||||
}
|
||||
|
||||
// Выполняем сразу при запуске
|
||||
updateDynamicMetrics()
|
||||
|
||||
// Затем каждые 5 секунд
|
||||
for range time.NewTicker(5 * time.Second).C {
|
||||
updateDynamicMetrics()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Получить JSON системных метрик
|
||||
func GetAllMetrics(w http.ResponseWriter) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.Write(GetMetricsJSON())
|
||||
}
|
||||
|
||||
// Получить JSON метрик
|
||||
func GetMetricsJSON() []byte {
|
||||
metrics := map[string]interface{}{
|
||||
"cpu_name": CPU_NAME,
|
||||
"cpu_ghz": CPU_GHz,
|
||||
"cpu_cores": CPU_Cores,
|
||||
"cpu_usage": CPU_Using,
|
||||
"disk_name": Disk_Name,
|
||||
"disk_size": Disk_Size,
|
||||
"disk_used": Disk_Used,
|
||||
"disk_free": Disk_Free,
|
||||
"ram_using": RAM_Using,
|
||||
"ram_total": RAM_Total,
|
||||
"server_uptime": tools.ServerUptime("get"),
|
||||
}
|
||||
|
||||
data, _ := json.Marshal(metrics)
|
||||
return data
|
||||
}
|
Reference in New Issue
Block a user