logging.go 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. package tea
  2. import (
  3. "io"
  4. "log"
  5. "os"
  6. "unicode"
  7. )
  8. // LogToFile sets up default logging to log to a file. This is helpful as we
  9. // can't print to the terminal since our TUI is occupying it. If the file
  10. // doesn't exist it will be created.
  11. //
  12. // Don't forget to close the file when you're done with it.
  13. //
  14. // f, err := LogToFile("debug.log", "debug")
  15. // if err != nil {
  16. // fmt.Println("fatal:", err)
  17. // os.Exit(1)
  18. // }
  19. // defer f.Close()
  20. func LogToFile(path string, prefix string) (*os.File, error) {
  21. return LogToFileWith(path, prefix, log.Default())
  22. }
  23. // LogOptionsSetter is an interface implemented by stdlib's log and charm's log
  24. // libraries.
  25. type LogOptionsSetter interface {
  26. SetOutput(io.Writer)
  27. SetPrefix(string)
  28. }
  29. // LogToFileWith does allows to call LogToFile with a custom LogOptionsSetter.
  30. func LogToFileWith(path string, prefix string, log LogOptionsSetter) (*os.File, error) {
  31. f, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0o644)
  32. if err != nil {
  33. return nil, err
  34. }
  35. log.SetOutput(f)
  36. // Add a space after the prefix if a prefix is being specified and it
  37. // doesn't already have a trailing space.
  38. if len(prefix) > 0 {
  39. finalChar := prefix[len(prefix)-1]
  40. if !unicode.IsSpace(rune(finalChar)) {
  41. prefix += " "
  42. }
  43. }
  44. log.SetPrefix(prefix)
  45. return f, nil
  46. }