log_buf.go 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  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.ITxtFix // Префикс для сообщений
  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. pref := sf.Prefix_.Get() + defs.ATxt(".")
  64. sf.Prefix_ = defs.Txt(pref)
  65. return sf
  66. }
  67. // IsTerm -- возвращает признак логирования.
  68. func (sf *LogBuf) IsTerm() core_spec.ISafeBool {
  69. return sf.IsTerm_
  70. }
  71. // GetErr -- возвращает сообщение ошибки по номеру.
  72. func (sf *LogBuf) GetErr(num defs.Int) log_msg.ILogMsg {
  73. sf.RLock()
  74. defer sf.RUnlock()
  75. if len(sf.lstErr) == 0 {
  76. msg := sf.Prefix_.Get() + "not error msg"
  77. return log_msg.NewLogMsg(log_msg.DEBUG, defs.Txt(msg))
  78. }
  79. if num.Int() >= len(sf.lstErr) {
  80. return sf.lstErr[len(sf.lstErr)-1]
  81. }
  82. if num <= 0 {
  83. return sf.lstErr[0]
  84. }
  85. return sf.lstErr[num]
  86. }
  87. // Get -- возвращает сообщение по номеру.
  88. func (sf *LogBuf) Get(num defs.Int) log_msg.ILogMsg {
  89. sf.RLock()
  90. defer sf.RUnlock()
  91. msg := sf.Prefix_.Get() + "*no msg*"
  92. if len(sf.lst) == 0 {
  93. return log_msg.NewLogMsg(log_msg.DEBUG, defs.Txt(msg))
  94. }
  95. if num.Int() >= len(sf.lst) {
  96. return log_msg.NewLogMsg(log_msg.DEBUG, defs.Txt(msg))
  97. }
  98. if num <= 0 {
  99. return log_msg.NewLogMsg(log_msg.DEBUG, defs.Txt(msg))
  100. }
  101. return sf.lst[num]
  102. }
  103. // Debug -- сообщение отладки.
  104. func (sf *LogBuf) Debug(fTxt defs.ITxtFix, args ...any) {
  105. sf.Lock()
  106. defer sf.Unlock()
  107. strMsg := fmt.Sprintf(fTxt.String(), args...)
  108. msg := sf.Prefix_.Get() + defs.ATxt(strMsg)
  109. _msg := log_msg.NewLogMsg(log_msg.DEBUG, defs.Txt(msg))
  110. sf.lst = append(sf.lst, _msg)
  111. sf.checkLen()
  112. sf.printTerm(_msg)
  113. }
  114. // Info -- информационные сообщения.
  115. func (sf *LogBuf) Info(fMsg defs.ITxtFix, args ...any) {
  116. sf.Lock()
  117. defer sf.Unlock()
  118. strMsg := fmt.Sprintf(fMsg.String(), args...)
  119. msg := sf.Prefix_.Get() + defs.ATxt(strMsg)
  120. _msg := log_msg.NewLogMsg(log_msg.INFO, defs.Txt(msg))
  121. sf.lst = append(sf.lst, _msg)
  122. sf.checkLen()
  123. sf.printTerm(_msg)
  124. }
  125. // Warn -- предупреждающие сообщения.
  126. func (sf *LogBuf) Warn(fMsg defs.ITxtFix, args ...any) {
  127. sf.Lock()
  128. defer sf.Unlock()
  129. strMsg := fmt.Sprintf(fMsg.String(), args...)
  130. msg := sf.Prefix_.Get() + defs.ATxt(strMsg)
  131. _msg := log_msg.NewLogMsg(log_msg.WARN, defs.Txt(msg))
  132. sf.lst = append(sf.lst, _msg)
  133. sf.checkLen()
  134. sf.printTerm(_msg)
  135. }
  136. // Err -- сообщения об ошибках.
  137. func (sf *LogBuf) Err(err defs.IErr, args ...any) {
  138. sf.Lock()
  139. defer sf.Unlock()
  140. strMsg := fmt.Sprintf(err.String(), args...)
  141. msg := sf.Prefix_.Get() + defs.ATxt(strMsg)
  142. _msg := log_msg.NewLogMsg(log_msg.ERROR, defs.Txt(msg))
  143. sf.lst = append(sf.lst, _msg)
  144. sf.lstErr = append(sf.lstErr, _msg)
  145. sf.checkLen()
  146. sf.checkLenErr()
  147. sf.printTerm(_msg)
  148. }
  149. // Size -- возвращает размер буфера.
  150. func (sf *LogBuf) Size() defs.Int {
  151. sf.RLock()
  152. defer sf.RUnlock()
  153. return defs.Int(len(sf.lst))
  154. }
  155. // Проверяет длину общую лога.
  156. func (sf *LogBuf) checkLen() {
  157. for len(sf.lst) > 100 {
  158. sf.lst = sf.lst[1:]
  159. }
  160. }
  161. // Проверяет длину лога ошибок.
  162. func (sf *LogBuf) checkLenErr() {
  163. for len(sf.lstErr) > 100 {
  164. sf.lstErr = sf.lstErr[1:]
  165. }
  166. }
  167. // Печатает сообщение в терминал, если разрешено.
  168. func (sf *LogBuf) printTerm(msg log_msg.ILogMsg) {
  169. if !sf.IsTerm_.Get() {
  170. return
  171. }
  172. level := msg.Level()
  173. if helpers.IsStageProd {
  174. switch level.Get() {
  175. case "ERRO", "WARN":
  176. log.Printf("%v %v\n", level, msg.String())
  177. default:
  178. return
  179. }
  180. }
  181. log.Printf("%v\n", msg.String())
  182. }