prettylog.go 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. /* Low performance but pretty and coherent log writer */
  2. package prettylog
  3. import (
  4. "fmt"
  5. "log"
  6. "os"
  7. "runtime"
  8. "strings"
  9. "time"
  10. "golang.org/x/crypto/ssh/terminal"
  11. )
  12. var (
  13. style = NewStyle()
  14. )
  15. type PrettyLogWritter struct {
  16. prefix string
  17. lastTime time.Time
  18. counter int64
  19. // Flags??
  20. }
  21. func NewWriter(prefix string) *PrettyLogWritter {
  22. return &PrettyLogWritter{prefix, time.Now(), 0}
  23. }
  24. func (p *PrettyLogWritter) Write(b []byte) (int, error) {
  25. if len(b) == 0 {
  26. return 0, nil
  27. }
  28. originalLen := len(b)
  29. parts := strings.Split(string(b), "\n")
  30. if len(parts) > 2 {
  31. for _, v := range parts {
  32. p.Write([]byte(v))
  33. }
  34. return originalLen, nil
  35. }
  36. msg := parts[0]
  37. //msg := string(b)
  38. /*{
  39. for i := 0; i < 6; i++ {
  40. ptr, _, _, _ := runtime.Caller(i)
  41. fname := runtime.FuncForPC(ptr).Name()
  42. fmt.Println("Stack:", fname)
  43. }
  44. }*/
  45. ptr, _, line, _ := runtime.Caller(3)
  46. tname := runtime.FuncForPC(ptr).Name()
  47. li := strings.LastIndex(tname, "/")
  48. fname := tname[li+1:]
  49. timeDiff := time.Since(p.lastTime)
  50. fdurationSuf := "ms"
  51. fduration := float64(timeDiff.Nanoseconds()) / 1000000.0
  52. if fduration > 100 {
  53. fduration /= 1000
  54. fdurationSuf = "s"
  55. }
  56. prefixStr := fmt.Sprintf("%12s", p.prefix)
  57. if !terminal.IsTerminal(int(os.Stderr.Fd())) {
  58. style.Disabled = true
  59. }
  60. //msg := fmt.Sprintf("[%d:\033[34m%s\033[0m (\033[33m%s:%d\033[0m) %s\033[90m+%.2f/ms\033[0m]: %s",
  61. str := fmt.Sprintf("[%s %s]: %s %s %s\n",
  62. style.Get("Time", time.Now().Format("2006-01-02 15:04:05")),
  63. style.Get("Prefix", prefixStr),
  64. style.Get("Message", msg),
  65. style.Get("Duration", fmt.Sprintf("+%.2f/%s", fduration, fdurationSuf)),
  66. style.GetX("File", fmt.Sprintf("%s:%d", fname, line)),
  67. )
  68. p.lastTime = time.Now()
  69. p.counter++
  70. n, err := os.Stderr.Write([]byte(str))
  71. if err != nil {
  72. return n, err
  73. }
  74. return originalLen, nil
  75. }
  76. func New(prefix string) *log.Logger {
  77. return log.New(NewWriter(prefix), "", 0)
  78. }
  79. func Global() {
  80. log.SetFlags(0)
  81. log.SetOutput(NewWriter(""))
  82. }