Files
DragonCoreSSH-NewWEB/system_logs_api.go
2026-05-03 11:05:13 -03:00

114 lines
2.3 KiB
Go

package main
import (
"bufio"
"encoding/json"
"net/http"
"os"
"strconv"
"strings"
)
const defaultPanelLogFile = "/opt/sshpanel/logs/panel.log"
type systemLogsResponse struct {
Source string `json:"source"`
Path string `json:"path,omitempty"`
Lines []string `json:"lines"`
}
func handleSystemLogs(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodGet {
w.WriteHeader(http.StatusMethodNotAllowed)
return
}
limit := 300
if raw := strings.TrimSpace(r.URL.Query().Get("lines")); raw != "" {
if n, err := strconv.Atoi(raw); err == nil && n > 0 {
limit = n
}
}
if limit > 2000 {
limit = 2000
}
source := strings.ToLower(strings.TrimSpace(r.URL.Query().Get("source")))
if source == "" {
source = "panel"
}
resp := systemLogsResponse{Source: source, Lines: []string{}}
switch source {
case "dnstt":
resp.Lines = limitLines(getDNSTTLogLines(), limit)
case "xray":
resp.Lines = limitLines(xrayLogBuf.snapshot(), limit)
default:
resp.Source = "panel"
path := panelLogFilePath()
resp.Path = path
lines, err := tailTextFile(path, limit)
if err != nil {
lines = []string{"unable to read " + path + ": " + err.Error()}
}
resp.Lines = lines
}
w.Header().Set("Content-Type", "application/json")
_ = json.NewEncoder(w).Encode(resp)
}
func tailTextFile(path string, limit int) ([]string, error) {
f, err := os.Open(path)
if err != nil {
return nil, err
}
defer f.Close()
if limit <= 0 {
limit = 300
}
ring := make([]string, limit)
count := 0
scanner := bufio.NewScanner(f)
buf := make([]byte, 0, 64*1024)
scanner.Buffer(buf, 1024*1024)
for scanner.Scan() {
ring[count%limit] = scanner.Text()
count++
}
if err := scanner.Err(); err != nil {
return nil, err
}
if count == 0 {
return []string{}, nil
}
outLen := count
if outLen > limit {
outLen = limit
}
out := make([]string, 0, outLen)
start := 0
if count > limit {
start = count % limit
}
for i := 0; i < outLen; i++ {
out = append(out, ring[(start+i)%limit])
}
return out, nil
}
func limitLines(lines []string, limit int) []string {
if len(lines) == 0 {
return []string{}
}
if limit <= 0 || len(lines) <= limit {
out := make([]string, len(lines))
copy(out, lines)
return out
}
out := make([]string, limit)
copy(out, lines[len(lines)-limit:])
return out
}