This commit is contained in:
2026-08-15 01:12:04 +08:00
parent f63acae353
commit 6698e59c3a
45 changed files with 725 additions and 415 deletions
+29 -18
View File
@@ -14,28 +14,32 @@ import (
"kra/internal/biz"
)
func logRoot() (string, error) {
root, err := filepath.Abs("logs")
func (r *auditRepo) logRoot() (string, error) {
admin := r.data.runtime.Admin()
if admin == nil || admin.Zap == nil || strings.TrimSpace(admin.Zap.Director) == "" {
return "", biz.ErrLogRootUnavailable
}
root, err := filepath.Abs(admin.Zap.Director)
if err != nil {
return "", err
return "", errors.Join(biz.ErrLogRootUnavailable, err)
}
info, err := os.Stat(root)
if errors.Is(err, fs.ErrNotExist) {
return root, nil
}
if err != nil {
return "", err
return "", errors.Join(biz.ErrLogRootUnavailable, err)
}
if !info.IsDir() {
return "", errors.New("日志路径不是目录")
return "", biz.ErrLogRootUnavailable
}
return root, nil
}
func (r *auditRepo) LogDates(ctx context.Context, month string) ([]biz.LogDate, error) {
if parsed, err := time.Parse("2006-01", month); err != nil || parsed.Format("2006-01") != month {
return nil, errors.New("日志月份格式不正确")
return nil, biz.ErrInvalidLogMonth
}
root, err := logRoot()
root, err := r.logRoot()
if err != nil {
return nil, err
}
@@ -73,9 +77,9 @@ func (r *auditRepo) LogDates(ctx context.Context, month string) ([]biz.LogDate,
}
func (r *auditRepo) LogFiles(ctx context.Context, date string) ([]biz.LogFile, error) {
if parsed, err := time.Parse("2006-01-02", date); err != nil || parsed.Format("2006-01-02") != date {
return nil, errors.New("日志日期格式不正确")
return nil, biz.ErrInvalidLogDate
}
root, err := logRoot()
root, err := r.logRoot()
if err != nil {
return nil, err
}
@@ -112,24 +116,27 @@ func (r *auditRepo) LogFiles(ctx context.Context, date string) ([]biz.LogFile, e
return out, err
}
func (r *auditRepo) LogContent(ctx context.Context, date, path string, cursor *int64) (*biz.LogContent, error) {
if _, err := time.Parse("2006-01-02", date); err != nil {
return nil, errors.New("日志日期格式不正确")
if parsed, err := time.Parse("2006-01-02", date); err != nil || parsed.Format("2006-01-02") != date {
return nil, biz.ErrInvalidLogDate
}
root, err := logRoot()
root, err := r.logRoot()
if err != nil {
return nil, err
}
dateRoot := filepath.Join(root, date)
target := filepath.Clean(filepath.Join(dateRoot, filepath.FromSlash(path)))
if target == dateRoot || !strings.HasPrefix(target, dateRoot+string(os.PathSeparator)) || !strings.EqualFold(filepath.Ext(target), ".log") {
return nil, errors.New("日志文件路径不合法")
return nil, biz.ErrInvalidLogPath
}
info, err := os.Lstat(target)
if errors.Is(err, fs.ErrNotExist) {
return nil, biz.ErrLogFileNotFound
}
if err != nil {
return nil, err
return nil, errors.Join(biz.ErrLogFileUnreadable, err)
}
if info.Mode()&os.ModeSymlink != 0 || !info.Mode().IsRegular() {
return nil, errors.New("日志文件路径不合法")
return nil, biz.ErrInvalidLogPath
}
end := info.Size()
if cursor != nil && *cursor >= 0 && *cursor < end {
@@ -142,13 +149,13 @@ func (r *auditRepo) LogContent(ctx context.Context, date, path string, cursor *i
}
file, err := os.Open(target)
if err != nil {
return nil, err
return nil, errors.Join(biz.ErrLogFileUnreadable, err)
}
defer file.Close()
data := make([]byte, end-start)
n, err := file.ReadAt(data, start)
if err != nil && n == 0 {
return nil, err
return nil, errors.Join(biz.ErrLogFileUnreadable, err)
}
data = data[:n]
lines := bytes.Split(data, []byte("\n"))
@@ -162,5 +169,9 @@ func (r *auditRepo) LogContent(ctx context.Context, date, path string, cursor *i
data = data[offset:]
limited = true
}
return &biz.LogContent{Date: date, Path: path, Content: string(data), LineCount: bytes.Count(data, []byte("\n")), NextCursor: start, HasMore: start > 0, LimitedByBytes: limited, Size: info.Size(), ModifiedAt: info.ModTime()}, nil
lineCount := bytes.Count(data, []byte("\n"))
if len(data) > 0 && data[len(data)-1] != '\n' {
lineCount++
}
return &biz.LogContent{Date: date, Path: path, Content: string(data), LineCount: lineCount, NextCursor: start, HasMore: start > 0, LimitedByBytes: limited, Size: info.Size(), ModifiedAt: info.ModTime()}, nil
}