log_buf.go 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. // package log_buf -- потокобезопасный буфер лога
  2. package log_buf
  3. import (
  4. "fmt"
  5. "gitp78su.ipnodns.ru/svi/kern/kc/log_buf/log_msg"
  6. . "gitp78su.ipnodns.ru/svi/kern/krn/ktypes"
  7. )
  8. // logBuf -- потокобезопасный буфер лога
  9. type logBuf struct {
  10. chGetIn chan int
  11. chGetOut chan ILogMsg
  12. chDebugIn chan tMsg
  13. chDebugOut chan int
  14. chInfoIn chan tMsg
  15. chInfoOut chan int
  16. chWarnIn chan tMsg
  17. chWarnOut chan int
  18. chErrorIn chan tMsg
  19. lst []ILogMsg
  20. chGetErrIn chan int
  21. chGetErrOut chan ILogMsg
  22. lstErr []ILogMsg
  23. chSizeIn chan int
  24. chSizeOut chan int
  25. }
  26. // NewLogBuf -- возвращает новый потокобезопасный буфер лога
  27. func NewLogBuf() ILogBuf {
  28. sf := &logBuf{
  29. chGetIn: make(chan int, 2),
  30. chGetOut: make(chan ILogMsg, 2),
  31. chDebugIn: make(chan tMsg, 2),
  32. chDebugOut: make(chan int, 2),
  33. chInfoIn: make(chan tMsg, 2),
  34. chInfoOut: make(chan int, 2),
  35. chWarnIn: make(chan tMsg, 2),
  36. chWarnOut: make(chan int, 2),
  37. chErrorIn: make(chan tMsg, 2),
  38. lst: []ILogMsg{},
  39. chGetErrIn: make(chan int, 2),
  40. chGetErrOut: make(chan ILogMsg, 2),
  41. lstErr: []ILogMsg{},
  42. chSizeIn: make(chan int, 2),
  43. chSizeOut: make(chan int, 2),
  44. }
  45. go sf.run()
  46. return sf
  47. }
  48. // GetErr -- возвращает сообщение ошибки по номеру
  49. func (sf *logBuf) GetErr(num int) ILogMsg {
  50. sf.chGetErrIn <- num
  51. return <-sf.chGetErrOut
  52. }
  53. // Get -- возвращает сообщение по номеру
  54. func (sf *logBuf) Get(num int) ILogMsg {
  55. sf.chGetIn <- num
  56. return <-sf.chGetOut
  57. }
  58. type tMsg struct {
  59. text string
  60. args []any
  61. }
  62. // Debug -- сообщение отладки
  63. func (sf *logBuf) Debug(fMsg string, args ...any) {
  64. msg := tMsg{
  65. text: fMsg,
  66. args: args,
  67. }
  68. sf.chDebugIn <- msg
  69. <-sf.chDebugOut
  70. }
  71. // Info -- информационные сообщения
  72. func (sf *logBuf) Info(fMsg string, args ...any) {
  73. msg := tMsg{
  74. text: fMsg,
  75. args: args,
  76. }
  77. sf.chInfoIn <- msg
  78. <-sf.chInfoOut
  79. }
  80. // Warn -- предупреждающие сообщения
  81. func (sf *logBuf) Warn(fMsg string, args ...any) {
  82. msg := tMsg{
  83. text: fMsg,
  84. args: args,
  85. }
  86. sf.chWarnIn <- msg
  87. <-sf.chWarnOut
  88. }
  89. // Err -- сообщения об ошибках
  90. func (sf *logBuf) Err(fMsg string, args ...any) {
  91. msg := tMsg{
  92. text: fMsg,
  93. args: args,
  94. }
  95. sf.chErrorIn <- msg
  96. }
  97. // Size -- возвращает размер буфера
  98. func (sf *logBuf) Size() int {
  99. sf.chSizeIn <- 1
  100. return <-sf.chSizeOut
  101. }
  102. func (sf *logBuf) run() {
  103. for {
  104. select {
  105. case num := <-sf.chGetErrIn:
  106. sf.chGetErrOut <- sf.getErr(num)
  107. case num := <-sf.chGetIn:
  108. sf.chGetOut <- sf.get(num)
  109. case msg := <-sf.chDebugIn:
  110. sf.debug(msg)
  111. sf.chDebugOut <- 1
  112. case msg := <-sf.chInfoIn:
  113. sf.info(msg)
  114. sf.chInfoOut <- 1
  115. case msg := <-sf.chWarnIn:
  116. sf.warn(msg)
  117. sf.chWarnOut <- 1
  118. case msg := <-sf.chErrorIn:
  119. sf.err(msg)
  120. case <-sf.chSizeIn:
  121. sf.chSizeOut <- len(sf.lst)
  122. }
  123. }
  124. }
  125. // Возвращает сообщение ошибки по номеру
  126. func (sf *logBuf) getErr(num int) ILogMsg {
  127. if len(sf.lstErr) == 0 {
  128. return log_msg.NewLogMsg(log_msg.DEBUG, "not error msg")
  129. }
  130. if num >= len(sf.lstErr) {
  131. return sf.lstErr[len(sf.lstErr)-1]
  132. }
  133. if num <= 0 {
  134. return sf.lstErr[0]
  135. }
  136. return sf.lstErr[num]
  137. }
  138. // возвращает сообщение по номеру
  139. func (sf *logBuf) get(num int) ILogMsg {
  140. if len(sf.lst) == 0 {
  141. return log_msg.NewLogMsg(log_msg.DEBUG, "*no msg*")
  142. }
  143. if num >= len(sf.lst) {
  144. return log_msg.NewLogMsg(log_msg.DEBUG, "*no msg*")
  145. }
  146. if num <= 0 {
  147. return log_msg.NewLogMsg(log_msg.DEBUG, "*no msg*")
  148. }
  149. return sf.lst[num]
  150. }
  151. // сообщение отладки
  152. func (sf *logBuf) debug(msg tMsg) {
  153. strMsg := fmt.Sprintf(msg.text, msg.args...)
  154. _msg := log_msg.NewLogMsg(log_msg.DEBUG, strMsg)
  155. sf.lst = append(sf.lst, _msg)
  156. sf.checkLen()
  157. }
  158. // информационные сообщения
  159. func (sf *logBuf) info(msg tMsg) {
  160. strMsg := fmt.Sprintf(msg.text, msg.args...)
  161. _msg := log_msg.NewLogMsg(log_msg.INFO, strMsg)
  162. sf.lst = append(sf.lst, _msg)
  163. sf.checkLen()
  164. }
  165. // предупреждающие сообщения
  166. func (sf *logBuf) warn(msg tMsg) {
  167. strMsg := fmt.Sprintf(msg.text, msg.args...)
  168. _msg := log_msg.NewLogMsg(log_msg.WARN, strMsg)
  169. sf.lst = append(sf.lst, _msg)
  170. sf.checkLen()
  171. }
  172. // сообщения об ошибках
  173. func (sf *logBuf) err(msg tMsg) {
  174. strMsg := fmt.Sprintf(msg.text, msg.args...)
  175. _msg := log_msg.NewLogMsg(log_msg.ERROR, strMsg)
  176. sf.lst = append(sf.lst, _msg)
  177. sf.lstErr = append(sf.lstErr, _msg)
  178. sf.checkLen()
  179. sf.checkLenErr()
  180. }
  181. // Проверяет длину общую лога
  182. func (sf *logBuf) checkLen() {
  183. for len(sf.lst) > 100 {
  184. sf.lst = sf.lst[1:]
  185. }
  186. }
  187. // Проверяет длину лога ошибок
  188. func (sf *logBuf) checkLenErr() {
  189. for len(sf.lstErr) > 100 {
  190. sf.lstErr = sf.lstErr[1:]
  191. }
  192. }