log_buf.go 5.4 KB

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