// ------------------------------------------------------------------------ // Project active2 // Active Thing (activething.com) git.activething.com/go // // File name logger_core.go // Created by DEV // Modified 25/04/2024 // // Copyright 2024 activething.com // ------------------------------------------------------------------------ // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // ------------------------------------------------------------------------ package alogs import ( "errs" "fmt" "iosys" "sync" ) type ( LoggerCore struct { sync.RWMutex filters EntryFilters extenders EntryExtenders appender EntryAppender name string level Level state State count int errors errs.ErrorList //eventos onStartFn LoggerCoreEventFnc onStopFn LoggerCoreEventFnc onFlushFn LoggerCoreEventFnc onFatalFn LoggerCoreEntryFnc onErrorFn LoggerCoreErrorFnc } LoggerCoreFnc func(l *LoggerCore) LoggerCoreEventFnc func (l *LoggerCore) error LoggerCoreEntryFnc func (l *LoggerCore, entry *Entry) LoggerCoreErrorFnc func (l *LoggerCore, entry *Entry, err error) ) func NewLoggerCore (name string, level Level, options ...LoggerCoreFnc) *LoggerCore { l := &LoggerCore { filters : *NewEntryFilters(), appender : AppendEntryFnc(nopEntryAppender), name : name, level : level, state : StateCreated, onStartFn: nopOnEvent, onStopFn : nopOnEvent, } for _,o := range options { o(l) } // if l.onFlushFn == nil { if fl,is := l.appender.(iosys.Flusher); is { l.onFlushFn = func(c *LoggerCore) error { return fl.Flush() } } else { l.onFlushFn = nopOnEvent } } return l } func (l *LoggerCore) Name () string { return l.name } func (l *LoggerCore) Level() (lv Level) { l.RLock() lv = l.level l.RUnlock() return } func (l *LoggerCore) SetLevel (level Level) { l.Lock() l.level = level l.Unlock() } func (l *LoggerCore) Start () error { l.Lock() er := l.start() l.Unlock() return er } func (l *LoggerCore) start () error { if l.state == StateStarted { return nil } l.errors = l.errors.Reset() if er := l.onStartFn(l); er != nil { l.handleError(er,nil) return er } l.state = StateStarted return nil } func (l *LoggerCore) Stop () error { l.Lock() er := l.stop() l.Unlock() return er } func (l *LoggerCore) stop () error { if l.state != StateStarted { return G.ErrLoggerNotStarted } l.state = StateStopped er := l.onStopFn(l) if er != nil { l.handleError(er,nil) return er } return nil } func (l *LoggerCore) Fatal (msg string, err error, ops ...EntryFnc){ l.log(LevelFatal,msg,err,ops ...) } func (l *LoggerCore) Error (msg string, err error, ops ...EntryFnc){ l.log(LevelError,msg,err,ops ...) } func (l *LoggerCore) Warn (msg string, ops ...EntryFnc){ l.log(LevelWarn,msg,nil,ops ...) } func (l *LoggerCore) Info (msg string, ops ...EntryFnc){ l.log(LevelInfo,msg,nil,ops...) } func (l *LoggerCore) Debug (msg string, ops ...EntryFnc){ l.log(LevelDebug,msg,nil,ops...) } func (l *LoggerCore) Data (msg string, data any, ops ...EntryFnc){ l.log(LevelData,msg,nil,EntryWithData(data,ops...)) } func (l *LoggerCore) log(level Level, msg string, err error, options ...EntryFnc) { l.Lock() if l.state != StateStarted { l.Unlock() return } if !l.level.Has(level) { l.Unlock() return } en := l.extenders.ExtendEntry(AcquireEntry(l,level,msg,err,options...)) if er := l.appender.AppendEntry(en); er != nil { l.handleError(er,en) } l.Unlock() if level == LevelFatal && l.onFatalFn != nil { l.onFatalFn(l,en) } ReleaseEntry(en) } func (l *LoggerCore) Log(entry *Entry) error { l.Lock() if l.state != StateStarted { l.Unlock() return G.ErrLoggerNotStarted } if !l.level.Has(entry.Level) || entry.Excludes.Has(l.name) || !l.filters.Filter(entry) { l.Unlock() return nil } fmt.Printf("--> Llalmando al logger %s con la entrada logger %v\n",l.name,entry.Excludes) er := l.appender.AppendEntry(entry) l.Unlock() return er } func (l *LoggerCore) Flush () error { l.Lock() er := l.flush() l.Unlock() return er } func (l *LoggerCore) flush () error { if l.onFlushFn != nil { if er := l.onFlushFn(l); er != nil { l.handleError(er,nil) return er } } return nil } func (l *LoggerCore) handleError (err error, entry *Entry) { if err == nil { return } l.errors = l.errors.Append(err) if l.onErrorFn != nil { l.onErrorFn(l, entry, err) } } func LoggerCoreWithEvents (onStart, onStop, onFlush LoggerCoreEventFnc) LoggerCoreFnc { return func(a *LoggerCore) { if onStart != nil { a.onStartFn = onStart } if onStop != nil { a.onStopFn = onStop } if onFlush != nil { a.onFlushFn = onFlush } } } func LoggerCoreWithOnFatal (onFatal LoggerCoreEntryFnc) LoggerCoreFnc { return func(a *LoggerCore) { a.onFatalFn = onFatal } } func LoggerCoreWithOnError (onError LoggerCoreErrorFnc) LoggerCoreFnc { return func(a *LoggerCore) { a.onErrorFn = onError } } func LoggerCoreWithExtender (extender ...EntryExtender) LoggerCoreFnc { return func(a *LoggerCore) { a.extenders = append(a.extenders,extender...) } } func LoggerCoreWithFilters (configFilters EntryFiltersFnc) LoggerCoreFnc { return func(a *LoggerCore) { configFilters(&a.filters) } } func LoggerCoreWithAppender(appender EntryAppender) LoggerCoreFnc { return func(a *LoggerCore) { a.appender = appender } } func nopOnEvent(_ *LoggerCore) error { return nil }