diff --git a/.gitignore b/.gitignore index 4ad6861..2338955 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ ctop .idea -/vendor/ \ No newline at end of file +/vendor/ +*.log \ No newline at end of file diff --git a/_docs/debug.md b/_docs/debug.md index 60c8410..4a30af3 100644 --- a/_docs/debug.md +++ b/_docs/debug.md @@ -54,3 +54,18 @@ CTOP_DEBUG=1 CTOP_DEBUG_TCP=1 ./ctop ``` A TCP listener for streaming log messages will be started on the default listen address(`0.0.0.0:9000`) + +## Log to file + +You can also log to a file by specifying `CTOP_DEBUG_FILE=/path/to/ctop.log` environment variable: +```sh +CTOP_DEBUG=1 CTOP_DEBUG_FILE=ctop.log ./ctop +``` + +This is useful for GoLand to see logs right in debug panel: +* Edit Run configuration +* Go to Logs tab +* Specify this log file in "Log file to be shown in console". +Then during debugging you'll see the log tab in debug panel: + +![Debug in GoLand](img/goland_debug.png) diff --git a/_docs/img/goland_debug.png b/_docs/img/goland_debug.png new file mode 100644 index 0000000..93c2e2d Binary files /dev/null and b/_docs/img/goland_debug.png differ diff --git a/logging/main.go b/logging/main.go index f7baa3a..c4b5bf5 100644 --- a/logging/main.go +++ b/logging/main.go @@ -29,6 +29,7 @@ type statusMsg struct { type CTopLogger struct { *logging.Logger backend *logging.MemoryBackend + logFile *os.File sLog []statusMsg } @@ -58,6 +59,7 @@ func Init() *CTopLogger { Log = &CTopLogger{ logging.MustGetLogger("ctop"), logging.NewMemoryBackend(size), + nil, []statusMsg{}, } @@ -68,7 +70,22 @@ func Init() *CTopLogger { backendLvl := logging.AddModuleLevel(Log.backend) backendLvl.SetLevel(level, "") - logging.SetBackend(backendLvl) + logFilePath := debugModeFile() + if logFilePath == "" { + logging.SetBackend(backendLvl) + } else { + logFile, err := os.OpenFile(logFilePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0666) + if err != nil { + logging.SetBackend(backendLvl) + Log.Error("Unable to create log file: %s", err.Error()) + } else { + backendFile := logging.NewLogBackend(logFile, "", 0) + backendFileLvl := logging.AddModuleLevel(backendFile) + backendFileLvl.SetLevel(level, "") + logging.SetBackend(backendLvl, backendFileLvl) + Log.logFile = logFile + } + } if debugMode { StartServer() @@ -105,8 +122,12 @@ func (log *CTopLogger) tail() chan string { func (log *CTopLogger) Exit() { exited = true + if log.logFile != nil { + _ = log.logFile.Close() + } StopServer() } -func debugMode() bool { return os.Getenv("CTOP_DEBUG") == "1" } -func debugModeTCP() bool { return os.Getenv("CTOP_DEBUG_TCP") == "1" } +func debugMode() bool { return os.Getenv("CTOP_DEBUG") == "1" } +func debugModeTCP() bool { return os.Getenv("CTOP_DEBUG_TCP") == "1" } +func debugModeFile() string { return os.Getenv("CTOP_DEBUG_FILE") }