| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197 |
- // package log_buf -- потокобезопасный буфер лога.
- package log_buf
- import (
- "fmt"
- "log"
- "sync"
- "gitp78su.ipnodns.ru/svi/kern/v4/lev0/helpers"
- mKt "gitp78su.ipnodns.ru/svi/kern/v4/lev0/kspec"
- "gitp78su.ipnodns.ru/svi/kern/v4/lev1/log_msg"
- "gitp78su.ipnodns.ru/svi/kern/v4/lev1/safe_bool"
- )
- // LogBuf -- потокобезопасный буфер лога.
- type LogBuf struct {
- sync.RWMutex
- isTerm mKt.ISafeBool // Признак вывода в стандартный поток
- prefix string // Префикс для сообщений
- lst []mKt.ILogMsg
- lstErr []mKt.ILogMsg
- }
- // OptionLogBuf -- опция для конфигурирования ILogBuf.
- type OptionLogBuf func(logBuf *LogBuf)
- // OptIsTerm -- устанавливает признак вывода в терминал.
- func OptIsTerm(isTerm bool) OptionLogBuf {
- return func(sf *LogBuf) {
- if isTerm {
- sf.IsTerm().Set()
- }
- }
- }
- // OptPrefix -- устанавливает префикс в сообщениях.
- func OptPrefix(prefix string) OptionLogBuf {
- return func(sf *LogBuf) {
- sf.prefix = prefix + "."
- }
- }
- // NewLogBuf -- возвращает новый потокобезопасный буфер лога.
- func NewLogBuf(opts ...OptionLogBuf) mKt.ILogBuf {
- sf := &LogBuf{
- isTerm: safe_bool.NewSafeBool(),
- lst: []mKt.ILogMsg{},
- lstErr: []mKt.ILogMsg{},
- }
- for _, opt := range opts {
- opt(sf)
- }
- return sf
- }
- // IsTerm -- возвращает признак логирования.
- func (sf *LogBuf) IsTerm() mKt.ISafeBool {
- return sf.isTerm
- }
- // GetErr -- возвращает сообщение ошибки по номеру.
- func (sf *LogBuf) GetErr(num int) mKt.ILogMsg {
- sf.RLock()
- defer sf.RUnlock()
- if len(sf.lstErr) == 0 {
- return log_msg.NewLogMsg(log_msg.DEBUG, sf.prefix+"not error msg")
- }
- if 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 int) mKt.ILogMsg {
- sf.RLock()
- defer sf.RUnlock()
- if len(sf.lst) == 0 {
- return log_msg.NewLogMsg(log_msg.DEBUG, sf.prefix+"*no msg*")
- }
- if num >= len(sf.lst) {
- return log_msg.NewLogMsg(log_msg.DEBUG, sf.prefix+"*no msg*")
- }
- if num <= 0 {
- return log_msg.NewLogMsg(log_msg.DEBUG, sf.prefix+"*no msg*")
- }
- return sf.lst[num]
- }
- type tMsg struct {
- text string
- args []any
- }
- // Debug -- сообщение отладки.
- func (sf *LogBuf) Debug(fMsg string, args ...any) {
- sf.Lock()
- defer sf.Unlock()
- msg := tMsg{
- text: fMsg,
- args: args,
- }
- strMsg := fmt.Sprintf(msg.text, msg.args...)
- _msg := log_msg.NewLogMsg(log_msg.DEBUG, sf.prefix+strMsg)
- sf.lst = append(sf.lst, _msg)
- sf.checkLen()
- sf.printTerm(_msg)
- }
- // Info -- информационные сообщения.
- func (sf *LogBuf) Info(fMsg string, args ...any) {
- sf.Lock()
- defer sf.Unlock()
- msg := tMsg{
- text: fMsg,
- args: args,
- }
- strMsg := fmt.Sprintf(msg.text, msg.args...)
- _msg := log_msg.NewLogMsg(log_msg.INFO, sf.prefix+strMsg)
- sf.lst = append(sf.lst, _msg)
- sf.checkLen()
- sf.printTerm(_msg)
- }
- // Warn -- предупреждающие сообщения.
- func (sf *LogBuf) Warn(fMsg string, args ...any) {
- sf.Lock()
- defer sf.Unlock()
- msg := tMsg{
- text: fMsg,
- args: args,
- }
- strMsg := fmt.Sprintf(msg.text, msg.args...)
- _msg := log_msg.NewLogMsg(log_msg.WARN, sf.prefix+strMsg)
- sf.lst = append(sf.lst, _msg)
- sf.checkLen()
- sf.printTerm(_msg)
- }
- // Err -- сообщения об ошибках.
- func (sf *LogBuf) Err(fMsg string, args ...any) {
- sf.Lock()
- defer sf.Unlock()
- msg := tMsg{
- text: fMsg,
- args: args,
- }
- strMsg := fmt.Sprintf(msg.text, msg.args...)
- _msg := log_msg.NewLogMsg(log_msg.ERROR, sf.prefix+strMsg)
- sf.lst = append(sf.lst, _msg)
- sf.lstErr = append(sf.lstErr, _msg)
- sf.checkLen()
- sf.checkLenErr()
- sf.printTerm(_msg)
- }
- // Size -- возвращает размер буфера.
- func (sf *LogBuf) Size() int {
- sf.RLock()
- defer sf.RUnlock()
- return 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 mKt.ILogMsg) {
- if !sf.isTerm.Get() {
- 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())
- }
|