prettylog.go 2.1 KB

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