82 lines
1.4 KiB
Go
82 lines
1.4 KiB
Go
package frp
|
|
|
|
import (
|
|
"io"
|
|
"os"
|
|
"strings"
|
|
)
|
|
|
|
// ReadTailLog 读取文件末尾 n 行
|
|
func ReadTailLog(filePath string, n int) ([]string, error) {
|
|
file, err := os.Open(filePath)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer file.Close()
|
|
|
|
info, err := file.Stat()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
fileSize := info.Size()
|
|
if fileSize == 0 {
|
|
return []string{}, nil
|
|
}
|
|
|
|
const chunkSize = 4096
|
|
var lines []string
|
|
var leftover []byte
|
|
offset := fileSize
|
|
|
|
for len(lines) < n && offset > 0 {
|
|
readSize := chunkSize
|
|
if offset < int64(chunkSize) {
|
|
readSize = int(offset)
|
|
}
|
|
offset -= int64(readSize)
|
|
|
|
buf := make([]byte, readSize)
|
|
_, err := file.ReadAt(buf, offset)
|
|
if err != nil && err != io.EOF {
|
|
return nil, err
|
|
}
|
|
|
|
data := append(buf, leftover...)
|
|
leftover = nil
|
|
|
|
start := 0
|
|
for i := len(data) - 1; i >= 0; i-- {
|
|
if data[i] == '\n' {
|
|
if i+1 < len(data) {
|
|
line := string(data[i+1:])
|
|
if line != "" {
|
|
lines = append([]string{line}, lines...)
|
|
if len(lines) >= n {
|
|
break
|
|
}
|
|
}
|
|
}
|
|
start = i
|
|
}
|
|
}
|
|
|
|
if len(lines) < n && start > 0 {
|
|
leftover = data[:start]
|
|
}
|
|
}
|
|
|
|
if len(lines) < n && len(leftover) > 0 {
|
|
parts := strings.Split(string(leftover), "\n")
|
|
for i := len(parts) - 1; i >= 0; i-- {
|
|
if parts[i] != "" {
|
|
lines = append([]string{parts[i]}, lines...)
|
|
if len(lines) >= n {
|
|
break
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return lines, nil
|
|
}
|