优化结构
This commit is contained in:
@@ -7,14 +7,13 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"io/fs"
|
||||
"kra/internal/biz/system"
|
||||
"os"
|
||||
pathpkg "path"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"kra/internal/biz"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -26,21 +25,21 @@ const (
|
||||
func (r *logFileRepo) configuredLogRoot() (root string, exists bool, err error) {
|
||||
admin := r.data.Runtime().Admin()
|
||||
if admin == nil || admin.Zap == nil || strings.TrimSpace(admin.Zap.Director) == "" {
|
||||
return "", false, biz.ErrLogRootUnavailable
|
||||
return "", false, system.ErrLogRootUnavailable
|
||||
}
|
||||
root, err = filepath.Abs(admin.Zap.Director)
|
||||
if err != nil {
|
||||
return "", false, fmt.Errorf("%w: %v", biz.ErrLogRootUnavailable, err)
|
||||
return "", false, fmt.Errorf("%w: %v", system.ErrLogRootUnavailable, err)
|
||||
}
|
||||
info, err := os.Stat(root)
|
||||
if errors.Is(err, fs.ErrNotExist) {
|
||||
return root, false, nil
|
||||
}
|
||||
if err != nil {
|
||||
return "", false, fmt.Errorf("%w: %v", biz.ErrLogRootUnavailable, err)
|
||||
return "", false, fmt.Errorf("%w: %v", system.ErrLogRootUnavailable, err)
|
||||
}
|
||||
if !info.IsDir() {
|
||||
return "", false, biz.ErrLogRootUnavailable
|
||||
return "", false, system.ErrLogRootUnavailable
|
||||
}
|
||||
return root, true, nil
|
||||
}
|
||||
@@ -52,12 +51,12 @@ func (r *logFileRepo) openConfiguredLogRoot() (root *os.Root, exists bool, err e
|
||||
}
|
||||
root, err = os.OpenRoot(rootPath)
|
||||
if err != nil {
|
||||
return nil, false, fmt.Errorf("%w: %v", biz.ErrLogRootUnavailable, err)
|
||||
return nil, false, fmt.Errorf("%w: %v", system.ErrLogRootUnavailable, err)
|
||||
}
|
||||
return root, true, nil
|
||||
}
|
||||
|
||||
func (r *logFileRepo) LogDates(ctx context.Context, month string) ([]biz.LogDate, error) {
|
||||
func (r *logFileRepo) LogDates(ctx context.Context, month string) ([]system.LogDate, error) {
|
||||
if err := validateLogMonth(month); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -66,15 +65,15 @@ func (r *logFileRepo) LogDates(ctx context.Context, month string) ([]biz.LogDate
|
||||
return nil, err
|
||||
}
|
||||
if !exists {
|
||||
return []biz.LogDate{}, nil
|
||||
return []system.LogDate{}, nil
|
||||
}
|
||||
defer logRoot.Close()
|
||||
|
||||
entries, err := fs.ReadDir(logRoot.FS(), ".")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%w: %v", biz.ErrLogRootUnavailable, err)
|
||||
return nil, fmt.Errorf("%w: %v", system.ErrLogRootUnavailable, err)
|
||||
}
|
||||
result := make([]biz.LogDate, 0)
|
||||
result := make([]system.LogDate, 0)
|
||||
for _, entry := range entries {
|
||||
if err = ctx.Err(); err != nil {
|
||||
return nil, err
|
||||
@@ -90,14 +89,14 @@ func (r *logFileRepo) LogDates(ctx context.Context, month string) ([]biz.LogDate
|
||||
return nil, countErr
|
||||
}
|
||||
if count > 0 {
|
||||
result = append(result, biz.LogDate{Date: entry.Name(), FileCount: count})
|
||||
result = append(result, system.LogDate{Date: entry.Name(), FileCount: count})
|
||||
}
|
||||
}
|
||||
sort.Slice(result, func(i, j int) bool { return result[i].Date < result[j].Date })
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (r *logFileRepo) LogFiles(ctx context.Context, date string) ([]biz.LogFile, error) {
|
||||
func (r *logFileRepo) LogFiles(ctx context.Context, date string) ([]system.LogFile, error) {
|
||||
if err := validateLogDate(date); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -106,27 +105,27 @@ func (r *logFileRepo) LogFiles(ctx context.Context, date string) ([]biz.LogFile,
|
||||
return nil, err
|
||||
}
|
||||
if !exists {
|
||||
return []biz.LogFile{}, nil
|
||||
return []system.LogFile{}, nil
|
||||
}
|
||||
defer logRoot.Close()
|
||||
|
||||
info, err := logRoot.Lstat(date)
|
||||
if errors.Is(err, fs.ErrNotExist) {
|
||||
return []biz.LogFile{}, nil
|
||||
return []system.LogFile{}, nil
|
||||
}
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%w: %v", biz.ErrLogRootUnavailable, err)
|
||||
return nil, fmt.Errorf("%w: %v", system.ErrLogRootUnavailable, err)
|
||||
}
|
||||
if info.Mode()&os.ModeSymlink != 0 || !info.IsDir() {
|
||||
return []biz.LogFile{}, nil
|
||||
return []system.LogFile{}, nil
|
||||
}
|
||||
dateRoot, err := logRoot.OpenRoot(date)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%w: %v", biz.ErrLogRootUnavailable, err)
|
||||
return nil, fmt.Errorf("%w: %v", system.ErrLogRootUnavailable, err)
|
||||
}
|
||||
defer dateRoot.Close()
|
||||
|
||||
result := make([]biz.LogFile, 0)
|
||||
result := make([]system.LogFile, 0)
|
||||
err = fs.WalkDir(dateRoot.FS(), ".", func(path string, entry fs.DirEntry, walkErr error) error {
|
||||
if walkErr != nil {
|
||||
return walkErr
|
||||
@@ -151,24 +150,24 @@ func (r *logFileRepo) LogFiles(ctx context.Context, date string) ([]biz.LogFile,
|
||||
return infoErr
|
||||
}
|
||||
if fileInfo.Mode().IsRegular() {
|
||||
result = append(result, biz.LogFile{Path: path, Name: entry.Name(), Size: fileInfo.Size(), ModifiedAt: fileInfo.ModTime()})
|
||||
result = append(result, system.LogFile{Path: path, Name: entry.Name(), Size: fileInfo.Size(), ModifiedAt: fileInfo.ModTime()})
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%w: %v", biz.ErrLogRootUnavailable, err)
|
||||
return nil, fmt.Errorf("%w: %v", system.ErrLogRootUnavailable, err)
|
||||
}
|
||||
sort.Slice(result, func(i, j int) bool { return result[i].Path < result[j].Path })
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (r *logFileRepo) LogContent(ctx context.Context, date, apiPath string, cursor *int64) (*biz.LogContent, error) {
|
||||
result := &biz.LogContent{Date: date, Path: apiPath}
|
||||
func (r *logFileRepo) LogContent(ctx context.Context, date, apiPath string, cursor *int64) (*system.LogContent, error) {
|
||||
result := &system.LogContent{Date: date, Path: apiPath}
|
||||
if err := ctx.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if cursor != nil && *cursor < 0 {
|
||||
return nil, biz.ErrInvalidLogPath
|
||||
return nil, system.ErrInvalidLogPath
|
||||
}
|
||||
file, info, err := r.openValidatedLogFile(date, apiPath)
|
||||
if err != nil {
|
||||
@@ -182,19 +181,19 @@ func (r *logFileRepo) LogContent(ctx context.Context, date, apiPath string, curs
|
||||
}
|
||||
start, limitedByBytes, err := findLogChunkStart(file, end)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%w: %v", biz.ErrLogFileUnreadable, err)
|
||||
return nil, fmt.Errorf("%w: %v", system.ErrLogFileUnreadable, err)
|
||||
}
|
||||
data, err := readLogRange(file, start, end)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%w: %v", biz.ErrLogFileUnreadable, err)
|
||||
return nil, fmt.Errorf("%w: %v", system.ErrLogFileUnreadable, err)
|
||||
}
|
||||
if int64(len(data)) < end-start {
|
||||
currentInfo, statErr := file.Stat()
|
||||
if statErr != nil || currentInfo.Size() < start {
|
||||
if statErr != nil {
|
||||
return nil, fmt.Errorf("%w: %v", biz.ErrLogFileUnreadable, statErr)
|
||||
return nil, fmt.Errorf("%w: %v", system.ErrLogFileUnreadable, statErr)
|
||||
}
|
||||
return nil, biz.ErrLogFileUnreadable
|
||||
return nil, system.ErrLogFileUnreadable
|
||||
}
|
||||
info = currentInfo
|
||||
}
|
||||
@@ -221,23 +220,23 @@ func (r *logFileRepo) openValidatedLogFile(date, apiPath string) (file *os.File,
|
||||
return nil, nil, err
|
||||
}
|
||||
if !exists {
|
||||
return nil, nil, biz.ErrLogFileNotFound
|
||||
return nil, nil, system.ErrLogFileNotFound
|
||||
}
|
||||
defer logRoot.Close()
|
||||
|
||||
dateInfo, err := logRoot.Lstat(date)
|
||||
if errors.Is(err, fs.ErrNotExist) {
|
||||
return nil, nil, biz.ErrLogFileNotFound
|
||||
return nil, nil, system.ErrLogFileNotFound
|
||||
}
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("%w: %v", biz.ErrLogFileUnreadable, err)
|
||||
return nil, nil, fmt.Errorf("%w: %v", system.ErrLogFileUnreadable, err)
|
||||
}
|
||||
if dateInfo.Mode()&os.ModeSymlink != 0 || !dateInfo.IsDir() {
|
||||
return nil, nil, biz.ErrInvalidLogPath
|
||||
return nil, nil, system.ErrInvalidLogPath
|
||||
}
|
||||
dateRoot, err := logRoot.OpenRoot(date)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("%w: %v", biz.ErrLogFileUnreadable, err)
|
||||
return nil, nil, fmt.Errorf("%w: %v", system.ErrLogFileUnreadable, err)
|
||||
}
|
||||
defer dateRoot.Close()
|
||||
|
||||
@@ -247,35 +246,35 @@ func (r *logFileRepo) openValidatedLogFile(date, apiPath string) (file *os.File,
|
||||
relativePath = filepath.Join(relativePath, segment)
|
||||
validatedInfo, err = dateRoot.Lstat(relativePath)
|
||||
if errors.Is(err, fs.ErrNotExist) {
|
||||
return nil, nil, biz.ErrLogFileNotFound
|
||||
return nil, nil, system.ErrLogFileNotFound
|
||||
}
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("%w: %v", biz.ErrLogFileUnreadable, err)
|
||||
return nil, nil, fmt.Errorf("%w: %v", system.ErrLogFileUnreadable, err)
|
||||
}
|
||||
if validatedInfo.Mode()&os.ModeSymlink != 0 {
|
||||
return nil, nil, biz.ErrInvalidLogPath
|
||||
return nil, nil, system.ErrInvalidLogPath
|
||||
}
|
||||
if index < len(segments)-1 && !validatedInfo.IsDir() {
|
||||
return nil, nil, biz.ErrInvalidLogPath
|
||||
return nil, nil, system.ErrInvalidLogPath
|
||||
}
|
||||
}
|
||||
if validatedInfo == nil || !validatedInfo.Mode().IsRegular() {
|
||||
return nil, nil, biz.ErrInvalidLogPath
|
||||
return nil, nil, system.ErrInvalidLogPath
|
||||
}
|
||||
file, err = dateRoot.Open(relativePath)
|
||||
if err != nil {
|
||||
if errors.Is(err, fs.ErrNotExist) {
|
||||
return nil, nil, biz.ErrLogFileNotFound
|
||||
return nil, nil, system.ErrLogFileNotFound
|
||||
}
|
||||
return nil, nil, fmt.Errorf("%w: %v", biz.ErrLogFileUnreadable, err)
|
||||
return nil, nil, fmt.Errorf("%w: %v", system.ErrLogFileUnreadable, err)
|
||||
}
|
||||
openedInfo, statErr := file.Stat()
|
||||
if statErr != nil || !openedInfo.Mode().IsRegular() || !os.SameFile(validatedInfo, openedInfo) {
|
||||
file.Close()
|
||||
if statErr != nil {
|
||||
return nil, nil, fmt.Errorf("%w: %v", biz.ErrLogFileUnreadable, statErr)
|
||||
return nil, nil, fmt.Errorf("%w: %v", system.ErrLogFileUnreadable, statErr)
|
||||
}
|
||||
return nil, nil, biz.ErrInvalidLogPath
|
||||
return nil, nil, system.ErrInvalidLogPath
|
||||
}
|
||||
return file, openedInfo, nil
|
||||
}
|
||||
@@ -283,7 +282,7 @@ func (r *logFileRepo) openValidatedLogFile(date, apiPath string) (file *os.File,
|
||||
func validateLogMonth(month string) error {
|
||||
parsed, err := time.Parse("2006-01", month)
|
||||
if err != nil || parsed.Format("2006-01") != month {
|
||||
return biz.ErrInvalidLogMonth
|
||||
return system.ErrInvalidLogMonth
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -291,23 +290,23 @@ func validateLogMonth(month string) error {
|
||||
func validateLogDate(date string) error {
|
||||
parsed, err := time.Parse("2006-01-02", date)
|
||||
if err != nil || parsed.Format("2006-01-02") != date {
|
||||
return biz.ErrInvalidLogDate
|
||||
return system.ErrInvalidLogDate
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateLogAPIPath(apiPath string) ([]string, error) {
|
||||
if apiPath == "" || strings.Contains(apiPath, "\\") || strings.Contains(apiPath, ":") || pathpkg.IsAbs(apiPath) {
|
||||
return nil, biz.ErrInvalidLogPath
|
||||
return nil, system.ErrInvalidLogPath
|
||||
}
|
||||
segments := strings.Split(apiPath, "/")
|
||||
for _, segment := range segments {
|
||||
if segment == "" || segment == "." || segment == ".." {
|
||||
return nil, biz.ErrInvalidLogPath
|
||||
return nil, system.ErrInvalidLogPath
|
||||
}
|
||||
}
|
||||
if !strings.EqualFold(pathpkg.Ext(apiPath), ".log") {
|
||||
return nil, biz.ErrInvalidLogPath
|
||||
return nil, system.ErrInvalidLogPath
|
||||
}
|
||||
return segments, nil
|
||||
}
|
||||
@@ -351,7 +350,7 @@ func countLogFiles(ctx context.Context, logRoot *os.Root, date string) (count in
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("%w: %v", biz.ErrLogRootUnavailable, err)
|
||||
return 0, fmt.Errorf("%w: %v", system.ErrLogRootUnavailable, err)
|
||||
}
|
||||
return count, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user