log_controller.go 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. package controllers
  2. import (
  3. "bufio"
  4. "fmt"
  5. "net/http"
  6. "os"
  7. "path/filepath"
  8. "strings"
  9. "time"
  10. "github.com/gin-gonic/gin"
  11. )
  12. type LogController struct {
  13. LogDir string
  14. }
  15. func NewLogController() *LogController {
  16. return &LogController{LogDir: "logs"}
  17. }
  18. // GetLogFiles 获取所有日志文件列表
  19. func (lc *LogController) GetLogFiles(c *gin.Context) {
  20. files, err := os.ReadDir(lc.LogDir)
  21. if err != nil {
  22. // 如果目录不存在,返回空列表
  23. c.JSON(http.StatusOK, []string{})
  24. return
  25. }
  26. var fileList []string
  27. for _, f := range files {
  28. if !f.IsDir() && strings.HasSuffix(f.Name(), ".log") {
  29. fileList = append(fileList, f.Name())
  30. }
  31. }
  32. // 按时间倒序排列(最新的在最前)
  33. for i, j := 0, len(fileList)-1; i < j; i, j = i+1, j-1 {
  34. fileList[i], fileList[j] = fileList[j], fileList[i]
  35. }
  36. c.JSON(http.StatusOK, fileList)
  37. }
  38. // GetLogContent 读取指定日志内容
  39. // Query参数: filename(文件名), keyword(过滤关键字), limit(行数限制)
  40. func (lc *LogController) GetLogContent(c *gin.Context) {
  41. filename := c.Query("filename")
  42. if filename == "" {
  43. filename = fmt.Sprintf("%s.log", time.Now().Format("2006-01-02"))
  44. }
  45. // 安全检查:防止目录遍历
  46. if strings.Contains(filename, "..") || strings.Contains(filename, "/") || strings.Contains(filename, "\\") {
  47. c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid filename"})
  48. return
  49. }
  50. fpath := filepath.Join(lc.LogDir, filename)
  51. file, err := os.Open(fpath)
  52. if err != nil {
  53. if os.IsNotExist(err) {
  54. c.JSON(http.StatusNotFound, gin.H{"error": "Log file not found"})
  55. return
  56. }
  57. c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
  58. return
  59. }
  60. defer file.Close()
  61. keyword := c.Query("keyword")
  62. scanner := bufio.NewScanner(file)
  63. var lines []string
  64. // 简单的读取逻辑,支持关键字过滤
  65. for scanner.Scan() {
  66. line := scanner.Text()
  67. if keyword != "" && !strings.Contains(strings.ToLower(line), strings.ToLower(keyword)) {
  68. continue
  69. }
  70. lines = append(lines, line)
  71. }
  72. // 限制返回行数,避免数据量过大(取最后 5000 行)
  73. maxLines := 5000
  74. total := len(lines)
  75. if total > maxLines {
  76. lines = lines[total-maxLines:]
  77. }
  78. c.JSON(http.StatusOK, gin.H{
  79. "filename": filename,
  80. "content": lines,
  81. "total": total,
  82. })
  83. }