122 lines
3.4 KiB
Go
122 lines
3.4 KiB
Go
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"os"
|
|
"os/exec"
|
|
"strings"
|
|
|
|
"github.com/moby/moby/client"
|
|
)
|
|
|
|
func getDockerPsA() ([]dockerPs, error) {
|
|
var dps []dockerPs
|
|
var err error
|
|
//
|
|
apiClient, err := client.New(client.FromEnv)
|
|
if err != nil {
|
|
err = fmt.Errorf("Ошибка при создании docker клиента %s", err)
|
|
return dps, err
|
|
}
|
|
defer apiClient.Close()
|
|
|
|
containers, err := apiClient.ContainerList(context.Background(), client.ContainerListOptions{All: true})
|
|
|
|
if err != nil {
|
|
err = fmt.Errorf("Ошибка получения списка контейнеров : %s", err)
|
|
return dps, err
|
|
}
|
|
for _, ctr := range containers.Items {
|
|
var dp dockerPs
|
|
dp.Id = ctr.ID
|
|
dp.Image = ctr.Image
|
|
dp.Names = ctr.Names
|
|
dp.Created = ctr.Created
|
|
dp.State = string(ctr.State)
|
|
dp.Status = ctr.Status
|
|
// dp.Health = string(ctr.Health.Status)
|
|
dps = append(dps, dp)
|
|
}
|
|
|
|
return dps, err
|
|
}
|
|
|
|
func getDockerStats() ([]dockerStats, error) {
|
|
var ds []dockerStats
|
|
var err error
|
|
cmd := exec.Command("docker", "stats", "-a", "--no-stream", "--format", "{{ json . }}")
|
|
output, err := cmd.Output()
|
|
if err != nil {
|
|
err = fmt.Errorf("Ошибка выполнения docker stats -a --format \"{{ json . }}\"")
|
|
return ds, err
|
|
}
|
|
for _, stat := range strings.Split(strings.TrimSpace(string(output)), "\n") {
|
|
var docS dockerStats
|
|
if stat == "" {
|
|
continue
|
|
}
|
|
buf := bytes.NewBuffer([]byte(stat))
|
|
err := json.NewDecoder(buf).Decode(&docS)
|
|
if err != nil {
|
|
err = fmt.Errorf("Ошибка десериализации переменной %v в строке %s", err, stat)
|
|
return ds, err
|
|
}
|
|
ds = append(ds, docS)
|
|
}
|
|
|
|
return ds, err
|
|
}
|
|
|
|
func getDockerSupervisordLog(outputServerStruct outputServerStruct, outDir string) ([]dockerSupervisor, []error) {
|
|
var dS []dockerSupervisor
|
|
var errs []error
|
|
|
|
for _, d := range outputServerStruct.DockerStats {
|
|
dSup := dockerSupervisor{
|
|
Id: d.ID,
|
|
Name: d.Name,
|
|
}
|
|
|
|
// 1. Ищем supervisord.log
|
|
cmd := exec.Command("docker", "exec", d.Name, "bash", "-c", "find / -name supervisord.log 2>/dev/null | head -1")
|
|
output, err := cmd.Output()
|
|
if err != nil || len(output) == 0 {
|
|
errs = append(errs, fmt.Errorf("supervisord.log не найден в контейнере %s", d.Name))
|
|
dS = append(dS, dSup)
|
|
continue
|
|
}
|
|
|
|
// Очищаем путь от пробелов и переносов
|
|
logPath := strings.TrimSpace(string(output))
|
|
|
|
// 2. Читаем содержимое файла
|
|
cmd = exec.Command("docker", "exec", d.Name, "bash", "-c", fmt.Sprintf("cat %s", logPath))
|
|
logContent, err := cmd.Output()
|
|
if err != nil {
|
|
errs = append(errs, fmt.Errorf("ошибка чтения supervisord.log в %s: %s", d.Name, err.Error()))
|
|
} else {
|
|
// Сохраняем лог в файл
|
|
supervisordLogFile := fmt.Sprintf("%s/%s_supervisord.log", outDir, d.Name)
|
|
if err := os.WriteFile(supervisordLogFile, logContent, 0644); err != nil {
|
|
errs = append(errs, fmt.Errorf("ошибка записи лога %s: %s", d.Name, err.Error()))
|
|
}
|
|
}
|
|
|
|
// 3. Получаем supervisorctl status
|
|
cmd = exec.Command("docker", "exec", d.Name, "bash", "-c", "supervisorctl status")
|
|
status, err := cmd.Output()
|
|
if err != nil {
|
|
errs = append(errs, fmt.Errorf("ошибка supervisorctl status в %s: %s", d.Name, err.Error()))
|
|
} else {
|
|
dSup.SupStatus = string(status)
|
|
}
|
|
|
|
dS = append(dS, dSup)
|
|
}
|
|
|
|
return dS, errs
|
|
}
|