logging.go 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. package lifecycle
  2. import (
  3. "fmt"
  4. "log/slog"
  5. "os"
  6. "path/filepath"
  7. "strconv"
  8. "strings"
  9. "github.com/ollama/ollama/envconfig"
  10. )
  11. func InitLogging() {
  12. level := slog.LevelInfo
  13. if envconfig.Debug() {
  14. level = slog.LevelDebug
  15. }
  16. var logFile *os.File
  17. var err error
  18. // Detect if we're a GUI app on windows, and if not, send logs to console
  19. if os.Stderr.Fd() != 0 {
  20. // Console app detected
  21. logFile = os.Stderr
  22. // TODO - write one-line to the app.log file saying we're running in console mode to help avoid confusion
  23. } else {
  24. rotateLogs(AppLogFile)
  25. logFile, err = os.OpenFile(AppLogFile, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0o755)
  26. if err != nil {
  27. slog.Error(fmt.Sprintf("failed to create server log %v", err))
  28. return
  29. }
  30. }
  31. handler := slog.NewTextHandler(logFile, &slog.HandlerOptions{
  32. Level: level,
  33. AddSource: true,
  34. ReplaceAttr: func(_ []string, attr slog.Attr) slog.Attr {
  35. if attr.Key == slog.SourceKey {
  36. source := attr.Value.Any().(*slog.Source)
  37. source.File = filepath.Base(source.File)
  38. }
  39. return attr
  40. },
  41. })
  42. slog.SetDefault(slog.New(handler))
  43. slog.Info("ollama app started")
  44. }
  45. func rotateLogs(logFile string) {
  46. if _, err := os.Stat(logFile); os.IsNotExist(err) {
  47. return
  48. }
  49. index := strings.LastIndex(logFile, ".")
  50. pre := logFile[:index]
  51. post := "." + logFile[index+1:]
  52. for i := LogRotationCount; i > 0; i-- {
  53. older := pre + "-" + strconv.Itoa(i) + post
  54. newer := pre + "-" + strconv.Itoa(i-1) + post
  55. if i == 1 {
  56. newer = pre + post
  57. }
  58. if _, err := os.Stat(newer); err == nil {
  59. if _, err := os.Stat(older); err == nil {
  60. err := os.Remove(older)
  61. if err != nil {
  62. slog.Warn("Failed to remove older log", "older", older, "error", err)
  63. continue
  64. }
  65. }
  66. err := os.Rename(newer, older)
  67. if err != nil {
  68. slog.Warn("Failed to rotate log", "older", older, "newer", newer, "error", err)
  69. }
  70. }
  71. }
  72. }