Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions server/cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,8 @@ func main() {
settings.HttpAuth = params.HttpAuth
log.Init(params.LogPath, params.WebLogPath)

fmt.Println("=========== START ===========")
fmt.Println("TorrServer", version.Version+",", runtime.Version()+",", "CPU Num:", runtime.NumCPU())
log.TLogln("=========== START ===========")
log.TLogln("TorrServer", version.Version+",", runtime.Version()+",", "CPU Num:", runtime.NumCPU())
if params.HttpAuth {
log.TLogln("Use HTTP Auth file", settings.Path+"/accs.db")
}
Expand Down
83 changes: 57 additions & 26 deletions server/log/log.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"io"
"log"
"os"
"path/filepath"
"strings"

"github.com/gin-gonic/gin"
Expand All @@ -24,53 +25,82 @@ var (
)

func Init(path, webpath string) {
webLogPath = webpath
logPath = path
webLogPath = webpath

shared := path != "" && webpath != "" && filepath.Clean(path) == filepath.Clean(webpath)
if path != "" {
path = filepath.Clean(path)
}
if webpath != "" {
webpath = filepath.Clean(webpath)
}

if shared {
ff, err := openLogFile(path)
if err != nil {
fmt.Fprintf(os.Stderr, "Error create log file: %v\n", err)
return
}
logFile = ff
webLogFile = ff
webLog = log.New(ff, " ", log.LstdFlags)
applyServerLog(ff)
return
}

if webpath != "" {
ff, err := os.OpenFile(webLogPath, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0o666)
ff, err := os.OpenFile(webpath, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0o666)
if err != nil {
TLogln("Error create web log file:", err)
fmt.Fprintf(os.Stderr, "Error create web log file: %v\n", err)
} else {
webLogFile = ff
webLog = log.New(ff, " ", log.LstdFlags)
}
}

if path != "" {
if fi, err := os.Lstat(path); err == nil {
if fi.Size() >= 100*1024*1024 { // 100MB
os.Remove(path)
}
}
ff, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0o666)
ff, err := openLogFile(path)
if err != nil {
TLogln("Error create log file:", err)
fmt.Fprintf(os.Stderr, "Error create log file: %v\n", err)
return
}
logFile = ff
os.Stdout = ff
os.Stderr = ff
// var timeFmt string
// var ok bool
// timeFmt, ok = os.LookupEnv("GO_LOG_TIME_FMT")
// if !ok {
// timeFmt = "2006-01-02T15:04:05-0700"
// }
// log.SetFlags(log.Lmsgprefix)
// log.SetPrefix(time.Now().Format(timeFmt) + " TSM ")
log.SetFlags(log.LstdFlags | log.LUTC | log.Lmsgprefix)
log.SetPrefix("UTC0 ")
log.SetOutput(ff)
applyServerLog(ff)
}
}

func openLogFile(path string) (*os.File, error) {
if fi, err := os.Lstat(path); err == nil {
if fi.Size() >= 100*1024*1024 { // 100MB
os.Remove(path)
}
}
return os.OpenFile(path, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0o666)
}

func applyServerLog(ff *os.File) {
if err := redirectStdFDs(ff); err != nil {
fmt.Fprintf(os.Stderr, "Error redirect stdout/stderr: %v\n", err)
}
log.SetFlags(log.LstdFlags | log.LUTC | log.Lmsgprefix)
log.SetPrefix("UTC0 ")
log.SetOutput(ff)
}

func Close() {
if logFile != nil {
logFile.Close()
if webLogFile == logFile {
webLogFile = nil
webLog = nil
}
logFile = nil
}
if webLogFile != nil {
webLogFile.Close()
webLogFile = nil
webLog = nil
}
}

Expand All @@ -93,8 +123,9 @@ func WebLogger() gin.HandlerFunc {
body := ""
// save body if not form or file
if !strings.HasPrefix(c.Request.Header.Get("Content-Type"), "multipart/form-data") {
body, _ := io.ReadAll(c.Request.Body)
c.Request.Body = io.NopCloser(bytes.NewBuffer(body))
bodyBytes, _ := io.ReadAll(c.Request.Body)
c.Request.Body = io.NopCloser(bytes.NewBuffer(bodyBytes))
body = string(bodyBytes)
} else {
body = "body hidden, too large"
}
Expand All @@ -114,7 +145,7 @@ func WebLogger() gin.HandlerFunc {
clientIP,
method,
path,
string(body),
body,
)
WebLogln(logStr)
}
Expand Down
52 changes: 52 additions & 0 deletions server/log/log_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package log

import (
"path/filepath"
"testing"
)

func TestInitSharedLogPath(t *testing.T) {
dir := t.TempDir()
path := filepath.Join(dir, "combined.log")

Init(path, path)
defer Close()

if logFile == nil {
t.Fatal("expected logFile to be set")
}
if webLogFile != logFile {
t.Fatal("expected webLogFile to share logFile when paths are equal")
}
if webLog == nil {
t.Fatal("expected webLog to be set")
}
}

func TestInitSeparateLogPaths(t *testing.T) {
dir := t.TempDir()
serverPath := filepath.Join(dir, "server.log")
webPath := filepath.Join(dir, "web.log")

Init(serverPath, webPath)
defer Close()

if logFile == nil || webLogFile == nil {
t.Fatal("expected both log files to be set")
}
if logFile == webLogFile {
t.Fatal("expected separate file handles for different paths")
}
}

func TestCloseSharedLogPathOnce(t *testing.T) {
dir := t.TempDir()
path := filepath.Join(dir, "combined.log")

Init(path, path)
Close()

if logFile != nil || webLogFile != nil || webLog != nil {
t.Fatal("expected log handles to be cleared after Close")
}
}
22 changes: 22 additions & 0 deletions server/log/redirect_unix.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
//go:build !windows

package log

import (
"os"

"golang.org/x/sys/unix"
)

func redirectStdFDs(f *os.File) error {
fd := int(f.Fd())
if err := unix.Dup2(fd, 1); err != nil {
return err
}
if err := unix.Dup2(fd, 2); err != nil {
return err
}
os.Stdout = f
os.Stderr = f
return nil
}
11 changes: 11 additions & 0 deletions server/log/redirect_windows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
//go:build windows

package log

import "os"

func redirectStdFDs(f *os.File) error {
os.Stdout = f
os.Stderr = f
return nil
}