slog.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. package slog
  2. import (
  3. "fmt"
  4. "os"
  5. "strings"
  6. "sync"
  7. "time"
  8. "wartank/pkg/components/kernel/slog/slog_file"
  9. "wartank/pkg/components/kernel/slog/slog_term"
  10. "wartank/pkg/components/safebool"
  11. "wartank/pkg/cons"
  12. "wartank/pkg/types"
  13. )
  14. /*
  15. Попытка сделать логирование в файл и консоль
  16. */
  17. const (
  18. strSlog = "ISlog"
  19. LevelDebug = iota
  20. LevelInfo
  21. LevelWarn
  22. LevelError
  23. )
  24. // Slog -- лог событий для записи
  25. type Slog struct {
  26. kern types.IKernel
  27. buf strings.Builder
  28. block sync.RWMutex
  29. lf *slog_file.SlogFile
  30. lt *slog_term.SlogTerm
  31. isWork *safebool.SafeBool
  32. level int // Уровень логирования
  33. }
  34. // NewSlog -- возвращает объект логирования
  35. func NewSlog(kern types.IKernel) (*Slog, error) {
  36. if kern == nil {
  37. return nil, fmt.Errorf("NewSlog(): IKernel is nil")
  38. }
  39. os.Setenv("BUILD", "test_BUILD")
  40. build := os.Getenv("BUILD")
  41. if build == "" {
  42. return nil, fmt.Errorf("NewSlog(): strBuild is empty")
  43. }
  44. sf := &Slog{
  45. kern: kern,
  46. buf: strings.Builder{},
  47. lt: slog_term.NewSlogTerm(),
  48. isWork: safebool.NewSafeBool(),
  49. }
  50. lf, err := slog_file.NewSlogFile(kern, build)
  51. if err != nil {
  52. return nil, fmt.Errorf("NewSlog(): in create SlogFile, err=\n\t%w", err)
  53. }
  54. sf.lf = lf
  55. go sf.close()
  56. sf.isWork.Set()
  57. sf.kern.Wg().Add(strSlog)
  58. sf.Infof("NewSlog()\n")
  59. return sf, nil
  60. }
  61. // Debugf -- выводит в лог отладочную инфу
  62. func (sf *Slog) Debugf(str string, lstVal ...interface{}) {
  63. sf.block.Lock()
  64. defer sf.block.Unlock()
  65. if !sf.isWork.Get() {
  66. return
  67. }
  68. sf.printf("DEBUG", str, lstVal...)
  69. }
  70. // Infof -- выводит в лог дежурную инфу
  71. func (sf *Slog) Infof(str string, lstVal ...interface{}) {
  72. sf.block.Lock()
  73. defer sf.block.Unlock()
  74. if !sf.isWork.Get() {
  75. return
  76. }
  77. sf.printf("INFO", str, lstVal...)
  78. }
  79. // Warnf -- выводит в лог предупредительную инфу
  80. func (sf *Slog) Warnf(str string, lstVal ...interface{}) {
  81. sf.block.Lock()
  82. defer sf.block.Unlock()
  83. if !sf.isWork.Get() {
  84. return
  85. }
  86. sf.printf("WARN", str, lstVal...)
  87. }
  88. // Errorf -- выводит в лог инфу об ошибках
  89. func (sf *Slog) Errorf(str string, lstVal ...interface{}) {
  90. sf.block.Lock()
  91. defer sf.block.Unlock()
  92. if !sf.isWork.Get() {
  93. return
  94. }
  95. sf.printf("ERROR", str, lstVal...)
  96. }
  97. // Внутренний вызов без блокировки
  98. func (sf *Slog) printf(pref, str string, lstVal ...interface{}) {
  99. style := ""
  100. switch pref {
  101. case "DEBUG": // Режим отладки
  102. style = "\033[2;37;40m"
  103. // case "PRINT": // Режим печати
  104. // style = "\033[0;34;40m"
  105. case "INFO": // Режим информирования
  106. style = "\033[0;37;40m"
  107. case "WARN": // Режим предупреждения
  108. style = "\033[1;31;40m"
  109. case "ERROR": // Режим ошибки
  110. style = "\033[1;37;41m"
  111. }
  112. strTime := time.Now().Local().Format("2006-01-02 15:04:05.000\t")
  113. sf.buf.WriteString(strTime + "\t")
  114. sf.buf.WriteString(pref + "\t")
  115. sf.buf.WriteString(cons.SelfName + "\n\t")
  116. sf.buf.WriteString(fmt.Sprintf(str, lstVal...))
  117. sf.lf.Write(sf.buf.String())
  118. sf.lt.Write(style + sf.buf.String() + "\033[00m")
  119. sf.buf.Reset()
  120. }
  121. // Ожидает закрытия приложения
  122. func (sf *Slog) close() {
  123. <-sf.kern.Done()
  124. sf.block.Lock()
  125. if !sf.isWork.Get() {
  126. return
  127. }
  128. sf.isWork.Reset()
  129. sf.kern.Wg().Done(strSlog)
  130. sf.block.Unlock()
  131. }