log_buf.go 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  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.AStr, args ...any)
  18. // LogBus -- возвращает объект публикации в шину
  19. // LogBus()ILogBus
  20. // Info -- информационные сообщения
  21. Info(fMsg defs.AStr, args ...any)
  22. // Warn -- предупреждающие сообщения
  23. Warn(fMsg defs.AStr, 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.AStr // Префикс для сообщений
  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. type tMsg struct {
  101. text defs.AStr
  102. args []any
  103. }
  104. // Debug -- сообщение отладки.
  105. func (sf *LogBuf) Debug(fMsg defs.AStr, args ...any) {
  106. sf.Lock()
  107. defer sf.Unlock()
  108. msg := tMsg{
  109. text: fMsg,
  110. args: args,
  111. }
  112. strMsg := fmt.Sprintf(msg.text.String(), msg.args...)
  113. _msg := log_msg.NewLogMsg(log_msg.DEBUG, sf.Prefix_+defs.AStr(strMsg))
  114. sf.lst = append(sf.lst, _msg)
  115. sf.checkLen()
  116. sf.printTerm(_msg)
  117. }
  118. // Info -- информационные сообщения.
  119. func (sf *LogBuf) Info(fMsg defs.AStr, args ...any) {
  120. sf.Lock()
  121. defer sf.Unlock()
  122. msg := tMsg{
  123. text: fMsg,
  124. args: args,
  125. }
  126. strMsg := fmt.Sprintf(msg.text.String(), msg.args...)
  127. _msg := log_msg.NewLogMsg(log_msg.INFO, sf.Prefix_+defs.AStr(strMsg))
  128. sf.lst = append(sf.lst, _msg)
  129. sf.checkLen()
  130. sf.printTerm(_msg)
  131. }
  132. // Warn -- предупреждающие сообщения.
  133. func (sf *LogBuf) Warn(fMsg defs.AStr, args ...any) {
  134. sf.Lock()
  135. defer sf.Unlock()
  136. msg := tMsg{
  137. text: fMsg,
  138. args: args,
  139. }
  140. strMsg := fmt.Sprintf(msg.text.String(), msg.args...)
  141. _msg := log_msg.NewLogMsg(log_msg.WARN, sf.Prefix_+defs.AStr(strMsg))
  142. sf.lst = append(sf.lst, _msg)
  143. sf.checkLen()
  144. sf.printTerm(_msg)
  145. }
  146. // Err -- сообщения об ошибках.
  147. func (sf *LogBuf) Err(fMsg defs.IErr, args ...any) {
  148. sf.Lock()
  149. defer sf.Unlock()
  150. msg := tMsg{
  151. text: fMsg.Str(),
  152. args: args,
  153. }
  154. strMsg := fmt.Sprintf(msg.text.String(), msg.args...)
  155. _msg := log_msg.NewLogMsg(log_msg.ERROR, sf.Prefix_+defs.AStr(strMsg))
  156. sf.lst = append(sf.lst, _msg)
  157. sf.lstErr = append(sf.lstErr, _msg)
  158. sf.checkLen()
  159. sf.checkLenErr()
  160. sf.printTerm(_msg)
  161. }
  162. // Size -- возвращает размер буфера.
  163. func (sf *LogBuf) Size() defs.Int {
  164. sf.RLock()
  165. defer sf.RUnlock()
  166. return defs.Int(len(sf.lst))
  167. }
  168. // Проверяет длину общую лога.
  169. func (sf *LogBuf) checkLen() {
  170. for len(sf.lst) > 100 {
  171. sf.lst = sf.lst[1:]
  172. }
  173. }
  174. // Проверяет длину лога ошибок.
  175. func (sf *LogBuf) checkLenErr() {
  176. for len(sf.lstErr) > 100 {
  177. sf.lstErr = sf.lstErr[1:]
  178. }
  179. }
  180. // Печатает сообщение в терминал, если разрешено.
  181. func (sf *LogBuf) printTerm(msg log_msg.ILogMsg) {
  182. if !sf.IsTerm_.Get() {
  183. return
  184. }
  185. level := msg.Level()
  186. if helpers.IsStageProd {
  187. switch level.Get() {
  188. case "ERRO", "WARN":
  189. log.Printf("%v %v\n", level, msg.String())
  190. default:
  191. return
  192. }
  193. }
  194. log.Printf("%v\n", msg.String())
  195. }