| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196 |
- // package log_buf -- потокобезопасный буфер лога.
- package log_buf
- import (
- "fmt"
- "log"
- "sync"
- "gitp78su.ipnodns.ru/svi/kern/v4/d0"
- "gitp78su.ipnodns.ru/svi/kern/v4/d0/helpers"
- "gitp78su.ipnodns.ru/svi/kern/v4/d1/log_buf/log_msg"
- )
- // ILogBuf -- буферизованный лог для диагностики.
- //
- // Буфер для Error -- отдельный.
- type ILogBuf interface {
- // Debug -- сообщение отладки
- Debug(fMsg d0.Txt, args ...any)
- // LogBus -- возвращает объект публикации в шину
- // LogBus()ILogBus
- // Info -- информационные сообщения
- Info(fMsg d0.Txt, args ...any)
- // Warn -- предупреждающие сообщения
- Warn(fMsg d0.Txt, args ...any)
- // Err -- сообщения об ошибках
- Err(fMsg *d0.LErr, args ...any)
- // Get -- возвращает сообщение по номеру (0..99)
- Get(num d0.Num) log_msg.ILogMsg
- // GetErr -- возвращает сообщение ошибки по номеру (0..99)
- GetErr(num d0.Num) log_msg.ILogMsg
- // Size -- возвращает размер лога
- Size() d0.Num
- // IsTerm -- возвращает признак логирования в терминал
- IsTerm() *d0.MSafeBool
- }
- // LogBufParam -- параметры логирующего буфера.
- type LogBufParam struct {
- Prefix_ *d0.LTxt // Префикс для сообщений
- IsTerm_ *d0.MSafeBool // Признак вывода в терминал
- }
- // SelfCheck -- проверяет корректность параметров.
- func (sf *LogBufParam) SelfCheck() {
- d0.If(sf.IsTerm_ == nil).Hassert("LogBufParam.SelfCheck(): IsTerm_==nil")
- }
- // LogBuf -- потокобезопасный буфер лога.
- type LogBuf struct {
- sync.RWMutex
- *LogBufParam
- lst []log_msg.ILogMsg
- lstErr []log_msg.ILogMsg
- }
- // NewLogBuf -- возвращает новый потокобезопасный буфер лога.
- func NewLogBuf(param *LogBufParam) *LogBuf {
- d0.If(param == nil).Hassert("NewLogBuf(): param==nil")
- param.SelfCheck()
- sf := &LogBuf{
- LogBufParam: param,
- lst: []log_msg.ILogMsg{},
- lstErr: []log_msg.ILogMsg{},
- }
- pref := sf.Prefix_.Get() + d0.Txt(".")
- sf.Prefix_ = d0.LetTxt(pref)
- return sf
- }
- // IsTerm -- возвращает признак логирования.
- func (sf *LogBuf) IsTerm() *d0.MSafeBool {
- return sf.IsTerm_
- }
- // GetErr -- возвращает сообщение ошибки по номеру.
- func (sf *LogBuf) GetErr(num d0.Num) log_msg.ILogMsg {
- sf.RLock()
- defer sf.RUnlock()
- if len(sf.lstErr) == 0 {
- msg := sf.Prefix_.Get() + "not error msg"
- return log_msg.NewLogMsg(log_msg.DEBUG, msg)
- }
- if num >= d0.Num(len(sf.lstErr)) {
- return sf.lstErr[len(sf.lstErr)-1]
- }
- if num <= 0 {
- return sf.lstErr[0]
- }
- return sf.lstErr[num]
- }
- // Get -- возвращает сообщение по номеру.
- func (sf *LogBuf) Get(num d0.Num) log_msg.ILogMsg {
- sf.RLock()
- defer sf.RUnlock()
- msg := sf.Prefix_.Get() + "*no msg*"
- if len(sf.lst) == 0 {
- return log_msg.NewLogMsg(log_msg.DEBUG, msg)
- }
- if num >= d0.Num(len(sf.lst)) {
- return log_msg.NewLogMsg(log_msg.DEBUG, msg)
- }
- if num <= 0 {
- return log_msg.NewLogMsg(log_msg.DEBUG, msg)
- }
- return sf.lst[num]
- }
- // Debug -- сообщение отладки.
- func (sf *LogBuf) Debug(fTxt d0.Txt, args ...any) {
- sf.Lock()
- defer sf.Unlock()
- strMsg := d0.Sprintf(fTxt, args...)
- msg := sf.Prefix_.Get() + d0.Txt(strMsg)
- _msg := log_msg.NewLogMsg(log_msg.DEBUG, msg)
- sf.lst = append(sf.lst, _msg)
- sf.checkLen()
- sf.printTerm(_msg)
- }
- // Info -- информационные сообщения.
- func (sf *LogBuf) Info(fMsg d0.Txt, args ...any) {
- sf.Lock()
- defer sf.Unlock()
- strMsg := d0.Sprintf(fMsg, args...)
- msg := sf.Prefix_.Get() + d0.Txt(strMsg)
- _msg := log_msg.NewLogMsg(log_msg.INFO, msg)
- sf.lst = append(sf.lst, _msg)
- sf.checkLen()
- sf.printTerm(_msg)
- }
- // Warn -- предупреждающие сообщения.
- func (sf *LogBuf) Warn(fMsg d0.Txt, args ...any) {
- sf.Lock()
- defer sf.Unlock()
- strMsg := d0.Sprintf(fMsg, args...)
- msg := sf.Prefix_.Get() + d0.Txt(strMsg)
- _msg := log_msg.NewLogMsg(log_msg.WARN, msg)
- sf.lst = append(sf.lst, _msg)
- sf.checkLen()
- sf.printTerm(_msg)
- }
- // Err -- сообщения об ошибках.
- func (sf *LogBuf) Err(err *d0.LErr, args ...any) {
- sf.Lock()
- defer sf.Unlock()
- strMsg := fmt.Sprintf(err.String(), args...)
- msg := sf.Prefix_.Get() + d0.Txt(strMsg)
- _msg := log_msg.NewLogMsg(log_msg.ERROR, msg)
- sf.lst = append(sf.lst, _msg)
- sf.lstErr = append(sf.lstErr, _msg)
- sf.checkLen()
- sf.checkLenErr()
- sf.printTerm(_msg)
- }
- // Size -- возвращает размер буфера.
- func (sf *LogBuf) Size() d0.Num {
- sf.RLock()
- defer sf.RUnlock()
- return d0.Num(len(sf.lst))
- }
- // Проверяет длину общую лога.
- func (sf *LogBuf) checkLen() {
- for len(sf.lst) > 100 {
- sf.lst = sf.lst[1:]
- }
- }
- // Проверяет длину лога ошибок.
- func (sf *LogBuf) checkLenErr() {
- for len(sf.lstErr) > 100 {
- sf.lstErr = sf.lstErr[1:]
- }
- }
- // Печатает сообщение в терминал, если разрешено.
- func (sf *LogBuf) printTerm(msg log_msg.ILogMsg) {
- if sf.IsTerm_.IsNot() {
- return
- }
- level := msg.Level()
- if helpers.IsStageProd {
- switch level.Get() {
- case "ERRO", "WARN":
- log.Printf("%v %v\n", level, msg.String())
- default:
- return
- }
- }
- log.Printf("%v\n", msg.String())
- }
|