slog.go 3.3 KB

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