log_buf.go 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. // package log_buf -- потокобезопасный буфер лога.
  2. package log_buf
  3. import (
  4. "fmt"
  5. "log"
  6. "sync"
  7. "gitp78su.ipnodns.ru/svi/kern/v4/lev0/core_spec"
  8. "gitp78su.ipnodns.ru/svi/kern/v4/lev0/defs"
  9. "gitp78su.ipnodns.ru/svi/kern/v4/lev0/helpers"
  10. "gitp78su.ipnodns.ru/svi/kern/v4/lev1/log_buf/log_msg"
  11. )
  12. // ILogBuf -- буферизованный лог для диагностики.
  13. //
  14. // Буфер для Error -- отдельный.
  15. type ILogBuf interface {
  16. // Debug -- сообщение отладки
  17. Debug(fMsg defs.ITxtFix, args ...any)
  18. // LogBus -- возвращает объект публикации в шину
  19. // LogBus()ILogBus
  20. // Info -- информационные сообщения
  21. Info(fMsg defs.ITxtFix, args ...any)
  22. // Warn -- предупреждающие сообщения
  23. Warn(fMsg defs.ITxtFix, args ...any)
  24. // Err -- сообщения об ошибках
  25. Err(fMsg defs.IErr, args ...any)
  26. // Get -- возвращает сообщение по номеру (0..99)
  27. Get(num defs.Int) log_msg.ILogMsg
  28. // GetErr -- возвращает сообщение ошибки по номеру (0..99)
  29. GetErr(num defs.Int) log_msg.ILogMsg
  30. // Size -- возвращает размер лога
  31. Size() defs.Int
  32. // IsTerm -- возвращает признак логирования в терминал
  33. IsTerm() core_spec.ISafeBool
  34. }
  35. var (
  36. hassert = helpers.Hassert
  37. )
  38. // LogBufParam -- параметры логирующего буфера.
  39. type LogBufParam struct {
  40. Prefix_ defs.ATxt // Префикс для сообщений
  41. IsTerm_ core_spec.ISafeBool // Признак вывода в терминал
  42. }
  43. // SelfCheck -- проверяет корректность параметров.
  44. func (sf *LogBufParam) SelfCheck() {
  45. hassert(sf.IsTerm_ != nil, "LogBufParam.SelfCheck(): IsTerm_==nil")
  46. }
  47. // LogBuf -- потокобезопасный буфер лога.
  48. type LogBuf struct {
  49. sync.RWMutex
  50. *LogBufParam
  51. lst []log_msg.ILogMsg
  52. lstErr []log_msg.ILogMsg
  53. }
  54. // NewLogBuf -- возвращает новый потокобезопасный буфер лога.
  55. func NewLogBuf(param *LogBufParam) ILogBuf {
  56. hassert(param != nil, "NewLogBuf(): param=nil")
  57. param.SelfCheck()
  58. sf := &LogBuf{
  59. LogBufParam: param,
  60. lst: []log_msg.ILogMsg{},
  61. lstErr: []log_msg.ILogMsg{},
  62. }
  63. sf.Prefix_ += "."
  64. return sf
  65. }
  66. // IsTerm -- возвращает признак логирования.
  67. func (sf *LogBuf) IsTerm() core_spec.ISafeBool {
  68. return sf.IsTerm_
  69. }
  70. // GetErr -- возвращает сообщение ошибки по номеру.
  71. func (sf *LogBuf) GetErr(num defs.Int) log_msg.ILogMsg {
  72. sf.RLock()
  73. defer sf.RUnlock()
  74. if len(sf.lstErr) == 0 {
  75. return log_msg.NewLogMsg(log_msg.DEBUG, sf.Prefix_+"not error msg")
  76. }
  77. if num.Int() >= len(sf.lstErr) {
  78. return sf.lstErr[len(sf.lstErr)-1]
  79. }
  80. if num <= 0 {
  81. return sf.lstErr[0]
  82. }
  83. return sf.lstErr[num]
  84. }
  85. // Get -- возвращает сообщение по номеру.
  86. func (sf *LogBuf) Get(num defs.Int) log_msg.ILogMsg {
  87. sf.RLock()
  88. defer sf.RUnlock()
  89. if len(sf.lst) == 0 {
  90. return log_msg.NewLogMsg(log_msg.DEBUG, sf.Prefix_+"*no msg*")
  91. }
  92. if num.Int() >= len(sf.lst) {
  93. return log_msg.NewLogMsg(log_msg.DEBUG, sf.Prefix_+"*no msg*")
  94. }
  95. if num <= 0 {
  96. return log_msg.NewLogMsg(log_msg.DEBUG, sf.Prefix_+"*no msg*")
  97. }
  98. return sf.lst[num]
  99. }
  100. // Debug -- сообщение отладки.
  101. func (sf *LogBuf) Debug(fTxt defs.ITxtFix, args ...any) {
  102. sf.Lock()
  103. defer sf.Unlock()
  104. strMsg := fmt.Sprintf(fTxt.String(), args...)
  105. _msg := log_msg.NewLogMsg(log_msg.DEBUG, sf.Prefix_+defs.ATxt(strMsg))
  106. sf.lst = append(sf.lst, _msg)
  107. sf.checkLen()
  108. sf.printTerm(_msg)
  109. }
  110. // Info -- информационные сообщения.
  111. func (sf *LogBuf) Info(fMsg defs.ATxt, args ...any) {
  112. sf.Lock()
  113. defer sf.Unlock()
  114. strMsg := fmt.Sprintf(string(fMsg), args...)
  115. _msg := log_msg.NewLogMsg(log_msg.INFO, sf.Prefix_+defs.ATxt(strMsg))
  116. sf.lst = append(sf.lst, _msg)
  117. sf.checkLen()
  118. sf.printTerm(_msg)
  119. }
  120. // Warn -- предупреждающие сообщения.
  121. func (sf *LogBuf) Warn(fMsg defs.ATxt, args ...any) {
  122. sf.Lock()
  123. defer sf.Unlock()
  124. strMsg := fmt.Sprintf(string(fMsg), args...)
  125. _msg := log_msg.NewLogMsg(log_msg.WARN, sf.Prefix_+defs.ATxt(strMsg))
  126. sf.lst = append(sf.lst, _msg)
  127. sf.checkLen()
  128. sf.printTerm(_msg)
  129. }
  130. // Err -- сообщения об ошибках.
  131. func (sf *LogBuf) Err(err defs.IErr, args ...any) {
  132. sf.Lock()
  133. defer sf.Unlock()
  134. strMsg := fmt.Sprintf(err.String(), args...)
  135. _msg := log_msg.NewLogMsg(log_msg.ERROR, sf.Prefix_+defs.ATxt(strMsg))
  136. sf.lst = append(sf.lst, _msg)
  137. sf.lstErr = append(sf.lstErr, _msg)
  138. sf.checkLen()
  139. sf.checkLenErr()
  140. sf.printTerm(_msg)
  141. }
  142. // Size -- возвращает размер буфера.
  143. func (sf *LogBuf) Size() defs.Int {
  144. sf.RLock()
  145. defer sf.RUnlock()
  146. return defs.Int(len(sf.lst))
  147. }
  148. // Проверяет длину общую лога.
  149. func (sf *LogBuf) checkLen() {
  150. for len(sf.lst) > 100 {
  151. sf.lst = sf.lst[1:]
  152. }
  153. }
  154. // Проверяет длину лога ошибок.
  155. func (sf *LogBuf) checkLenErr() {
  156. for len(sf.lstErr) > 100 {
  157. sf.lstErr = sf.lstErr[1:]
  158. }
  159. }
  160. // Печатает сообщение в терминал, если разрешено.
  161. func (sf *LogBuf) printTerm(msg log_msg.ILogMsg) {
  162. if !sf.IsTerm_.Get() {
  163. return
  164. }
  165. level := msg.Level()
  166. if helpers.IsStageProd {
  167. switch level.Get() {
  168. case "ERRO", "WARN":
  169. log.Printf("%v %v\n", level, msg.String())
  170. default:
  171. return
  172. }
  173. }
  174. log.Printf("%v\n", msg.String())
  175. }