log_buf.go 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. // package log_buf -- потокобезопасный буфер лога.
  2. package log_buf
  3. import (
  4. "log"
  5. "gitp78su.ipnodns.ru/svi/kern/v4/d0"
  6. "gitp78su.ipnodns.ru/svi/kern/v4/d0/defs/def_txt"
  7. "gitp78su.ipnodns.ru/svi/kern/v4/d0/defs/table/owner"
  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. Owner_ *d0.LOwner // Владелец буфера
  37. Prefix_ *d0.LTxt // Префикс для сообщений
  38. IsTerm_ *d0.MSafeBool // Признак вывода в терминал
  39. }
  40. // SelfCheck -- проверяет корректность параметров.
  41. func (sf *LogBufParam) SelfCheck() {
  42. d0.If(sf.IsTerm_ == nil).Hassert("LogBufParam.SelfCheck(): IsTerm_==nil")
  43. d0.If(sf.Owner_ == nil).Hassert("LogBufParam.SelfCheck(): Owner_==nil")
  44. }
  45. // LogBuf -- потокобезопасный буфер лога.
  46. type LogBuf struct {
  47. *d0.MSafeMutex
  48. *LogBufParam
  49. owner *owner.LOwner
  50. lst []log_msg.ILogMsg
  51. lstErr []log_msg.ILogMsg
  52. level *d0.LTxt
  53. levDebug *d0.LTxt
  54. levInfo *d0.LTxt
  55. levWarn *d0.LTxt
  56. levError *d0.LTxt
  57. levEmpty *d0.LTxt
  58. }
  59. const (
  60. DEBUG = d0.Num(-4)
  61. INFO = d0.Num(-3)
  62. WARN = d0.Num(-2)
  63. ERROR = d0.Num(-1)
  64. EMPTY = d0.Num(0)
  65. )
  66. // NewLogBuf -- возвращает новый потокобезопасный буфер лога.
  67. func NewLogBuf(param *LogBufParam) *LogBuf {
  68. d0.If(param == nil).Hassert("NewLogBuf(): param==nil")
  69. param.SelfCheck()
  70. sf := &LogBuf{
  71. owner: param.Owner_,
  72. MSafeMutex: d0.MutSafeMutex(),
  73. LogBufParam: param,
  74. lst: []log_msg.ILogMsg{},
  75. lstErr: []log_msg.ILogMsg{},
  76. level: d0.LetTxt(param.Owner_, "DEBU"),
  77. levDebug: d0.LetTxt(param.Owner_, "DEBU"),
  78. levInfo: d0.LetTxt(param.Owner_, "INFO"),
  79. levWarn: d0.LetTxt(param.Owner_, "WARN"),
  80. levError: d0.LetTxt(param.Owner_, "ERRO"),
  81. levEmpty: d0.LetTxt(param.Owner_, "EMPT"),
  82. }
  83. pref := sf.Prefix_.Get() + d0.Txt(".")
  84. sf.Prefix_ = d0.LetTxt(sf.owner, pref)
  85. return sf
  86. }
  87. // IsTerm -- возвращает признак логирования.
  88. func (sf *LogBuf) IsTerm() *d0.MSafeBool {
  89. return sf.IsTerm_
  90. }
  91. // GetErr -- возвращает сообщение ошибки по номеру.
  92. func (sf *LogBuf) GetErr(num d0.Num) log_msg.ILogMsg {
  93. sf.RLock()
  94. defer sf.RUnlock()
  95. if len(sf.lstErr) == 0 {
  96. msg := def_txt.LetTxt(sf.owner, sf.Prefix_.Get()+"not error msg")
  97. return log_msg.NewLogMsg(sf.levDebug, msg)
  98. }
  99. if num >= d0.Num(len(sf.lstErr)) {
  100. return sf.lstErr[len(sf.lstErr)-1]
  101. }
  102. if num <= 0 {
  103. return sf.lstErr[0]
  104. }
  105. return sf.lstErr[num]
  106. }
  107. // Get -- возвращает сообщение по номеру.
  108. func (sf *LogBuf) Get(num d0.Num) log_msg.ILogMsg {
  109. sf.RLock()
  110. defer sf.RUnlock()
  111. msg := def_txt.LetTxt(sf.owner, sf.Prefix_.Get()+"*no msg*")
  112. if len(sf.lst) == 0 {
  113. return log_msg.NewLogMsg(sf.levDebug, msg)
  114. }
  115. if num >= d0.Num(len(sf.lst)) {
  116. return log_msg.NewLogMsg(sf.levDebug, msg)
  117. }
  118. if num <= 0 {
  119. return log_msg.NewLogMsg(sf.levDebug, msg)
  120. }
  121. return sf.lst[num]
  122. }
  123. // Debug -- сообщение отладки.
  124. func (sf *LogBuf) Debug(fTxt d0.Txt, args ...any) {
  125. sf.Lock()
  126. defer sf.Unlock()
  127. strMsg := d0.Sprintf(fTxt, args...)
  128. msg := def_txt.LetTxt(sf.owner, sf.Prefix_.Get()+d0.Txt(strMsg))
  129. _msg := log_msg.NewLogMsg(sf.levDebug, msg)
  130. sf.lst = append(sf.lst, _msg)
  131. sf.checkLen()
  132. sf.printTerm(_msg)
  133. }
  134. // Info -- информационные сообщения.
  135. func (sf *LogBuf) Info(fMsg d0.Txt, args ...any) {
  136. sf.Lock()
  137. defer sf.Unlock()
  138. strMsg := d0.Sprintf(fMsg, args...)
  139. msg := def_txt.LetTxt(sf.owner, sf.Prefix_.Get()+strMsg)
  140. _msg := log_msg.NewLogMsg(sf.levInfo, msg)
  141. sf.lst = append(sf.lst, _msg)
  142. sf.checkLen()
  143. sf.printTerm(_msg)
  144. }
  145. // Warn -- предупреждающие сообщения.
  146. func (sf *LogBuf) Warn(fMsg d0.Txt, args ...any) {
  147. sf.Lock()
  148. defer sf.Unlock()
  149. strMsg := d0.Sprintf(fMsg, args...)
  150. msg := def_txt.LetTxt(sf.owner, sf.Prefix_.Get()+strMsg)
  151. _msg := log_msg.NewLogMsg(sf.levWarn, msg)
  152. sf.lst = append(sf.lst, _msg)
  153. sf.checkLen()
  154. sf.printTerm(_msg)
  155. }
  156. // Err -- сообщения об ошибках.
  157. func (sf *LogBuf) Err(err *d0.LErr, args ...any) {
  158. sf.Lock()
  159. defer sf.Unlock()
  160. strMsg := d0.Sprintf(err.String(), args...)
  161. msg := def_txt.LetTxt(sf.owner, sf.Prefix_.Get()+strMsg)
  162. _msg := log_msg.NewLogMsg(sf.levError, msg)
  163. sf.lst = append(sf.lst, _msg)
  164. sf.lstErr = append(sf.lstErr, _msg)
  165. sf.checkLen()
  166. sf.checkLenErr()
  167. sf.printTerm(_msg)
  168. }
  169. // Size -- возвращает размер буфера.
  170. func (sf *LogBuf) Size() d0.Num {
  171. sf.RLock()
  172. defer sf.RUnlock()
  173. return d0.Num(len(sf.lst))
  174. }
  175. // Проверяет длину общую лога.
  176. func (sf *LogBuf) checkLen() {
  177. for len(sf.lst) > 100 {
  178. sf.lst = sf.lst[1:]
  179. }
  180. }
  181. // Проверяет длину лога ошибок.
  182. func (sf *LogBuf) checkLenErr() {
  183. for len(sf.lstErr) > 100 {
  184. sf.lstErr = sf.lstErr[1:]
  185. }
  186. }
  187. // Печатает сообщение в терминал, если разрешено.
  188. func (sf *LogBuf) printTerm(msg log_msg.ILogMsg) {
  189. if sf.IsTerm_.IsNot() {
  190. return
  191. }
  192. level := msg.Level()
  193. if helpers.IsStageProd {
  194. switch level.Get() {
  195. case "ERRO", "WARN":
  196. log.Printf("%v %v\n", level, msg.String())
  197. default:
  198. return
  199. }
  200. }
  201. log.Printf("%v\n", msg.String())
  202. }
  203. // SetLevel -- проверяет правильность своего состава.
  204. func (sf *LogBuf) SetLevel(level d0.Num) {
  205. switch level {
  206. case EMPTY:
  207. sf.level = sf.levEmpty
  208. case INFO:
  209. sf.level = sf.levInfo
  210. case DEBUG:
  211. sf.level = sf.levDebug
  212. case WARN:
  213. sf.level = sf.levWarn
  214. case ERROR:
  215. sf.level = sf.levError
  216. default:
  217. d0.If(true).Hassert("logMsg.LogBuf(): NOT SET level(%v)", level)
  218. }
  219. }