| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899 |
- package controllers
- import (
- "bufio"
- "fmt"
- "net/http"
- "os"
- "path/filepath"
- "strings"
- "time"
- "github.com/gin-gonic/gin"
- )
- type LogController struct {
- LogDir string
- }
- func NewLogController() *LogController {
- return &LogController{LogDir: "logs"}
- }
- // GetLogFiles 获取所有日志文件列表
- func (lc *LogController) GetLogFiles(c *gin.Context) {
- files, err := os.ReadDir(lc.LogDir)
- if err != nil {
- // 如果目录不存在,返回空列表
- c.JSON(http.StatusOK, []string{})
- return
- }
- var fileList []string
- for _, f := range files {
- if !f.IsDir() && strings.HasSuffix(f.Name(), ".log") {
- fileList = append(fileList, f.Name())
- }
- }
-
- // 按时间倒序排列(最新的在最前)
- for i, j := 0, len(fileList)-1; i < j; i, j = i+1, j-1 {
- fileList[i], fileList[j] = fileList[j], fileList[i]
- }
- c.JSON(http.StatusOK, fileList)
- }
- // GetLogContent 读取指定日志内容
- // Query参数: filename(文件名), keyword(过滤关键字), limit(行数限制)
- func (lc *LogController) GetLogContent(c *gin.Context) {
- filename := c.Query("filename")
- if filename == "" {
- filename = fmt.Sprintf("%s.log", time.Now().Format("2006-01-02"))
- }
-
- // 安全检查:防止目录遍历
- if strings.Contains(filename, "..") || strings.Contains(filename, "/") || strings.Contains(filename, "\\") {
- c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid filename"})
- return
- }
- fpath := filepath.Join(lc.LogDir, filename)
- file, err := os.Open(fpath)
- if err != nil {
- if os.IsNotExist(err) {
- c.JSON(http.StatusNotFound, gin.H{"error": "Log file not found"})
- return
- }
- c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
- return
- }
- defer file.Close()
- keyword := c.Query("keyword")
-
- scanner := bufio.NewScanner(file)
- var lines []string
-
- // 简单的读取逻辑,支持关键字过滤
- for scanner.Scan() {
- line := scanner.Text()
- if keyword != "" && !strings.Contains(strings.ToLower(line), strings.ToLower(keyword)) {
- continue
- }
- lines = append(lines, line)
- }
- // 限制返回行数,避免数据量过大(取最后 5000 行)
- maxLines := 5000
- total := len(lines)
- if total > maxLines {
- lines = lines[total-maxLines:]
- }
- c.JSON(http.StatusOK, gin.H{
- "filename": filename,
- "content": lines,
- "total": total,
- })
- }
|