// ------------------------------------------------------------------------ // 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" "iosys" ) type ( LoggerCore struct { loggerObject filters EntryFilters appender EntryAppender onStartFn LoggerCoreEventFnc onStopFn LoggerCoreEventFnc onFlushFn LoggerCoreEventFnc onErrorFn LoggerCoreErrorFnc onEntryFatalFn LoggerCoreEntryFnc onEntryErrorFn LoggerCoreEntryFnc } LoggerCoreFnc func(l *LoggerCore) error 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,error) { l := &LoggerCore { appender : AppendEntryFnc(nopEntryAppender), onStartFn: nopOnEvent, onStopFn : nopOnEvent, } l.loggerObject = *newLoggerObject(name,level,l.log) for _,o := range options { if er:=o(l); er != nil { return nil,er } } 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,nil } func (l *LoggerCore) Start () error { l.Lock() er := l.start() l.Unlock() return er } func (l *LoggerCore) start () error { if l.state == StateStarted { return G.ErrLoggerStarted.WrapWithFieldString(entryFieldLogger,l.name) } l.errors = l.errors.Reset() if er := l.onStartFn(l); er != nil { er = errs.WrapWithFieldString(er,entryFieldLogger,l.name) 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.WrapWithFieldString(entryFieldLogger,l.name) } l.state = StateStopped er := l.onStopFn(l) if er != nil { er = errs.WrapWithFieldString(er,entryFieldLogger,l.name) l.handleError(er,nil) return er } return nil } func (l *LoggerCore) Flush () error { l.Lock() er := l.flush() l.Unlock() return er } func (l *LoggerCore) flush () error { if l.onFlushFn == nil { return nil } er := l.onFlushFn(l) if er == nil { return nil } er = errs.WrapWithFieldString(er,entryFieldLogger,l.name) l.handleError(er,nil) return er } func (l *LoggerCore) log(level Level, msg string, err error, options []EntryFnc) { l.Lock() en := l.extenders.ExtendEntry(AcquireEntry(l,level,msg,err,options...)) _ = l.handleEntry(en,true) l.Unlock() } func (l *LoggerCore) Log(entry *Entry) error { l.Lock() er := l.handleEntry(entry,false) l.Unlock() return er } func (l *LoggerCore) handleEntry (entry *Entry, self bool) error { if l.state != StateStarted { return G.ErrLoggerNotStarted.WrapWithFieldString(entryFieldLogger,l.name) } if !l.level.Has(entry.Level) { return nil } if !self { if entry.Excludes.Has(l.name) || !l.filters.Filter(entry) { return nil } } er := l.appender.AppendEntry(entry) if er != nil { er = errs.WrapWithFieldString(er,errFieldLogger,l.name) l.handleError(er,nil) } if self { if entry.Logger == l { if entry.Level == LevelFatal { l.onEntryFatalFn(l, entry) } if entry.Level == LevelError { l.onEntryErrorFn(l, entry) } ReleaseEntry(entry) } } return er } func (l *LoggerCore) handleError (err error, entry *Entry) { if err == nil { return } l.errors = l.errors.Append(err) if l.onEntryErrorFn != nil { l.onErrorFn(l, entry, err) } } func LoggerCoreWithEvents (onStart, onStop, onFlush LoggerCoreEventFnc) LoggerCoreFnc { return func(a *LoggerCore) error { if onStart != nil { a.onStartFn = onStart } if onStop != nil { a.onStopFn = onStop } if onFlush != nil { a.onFlushFn = onFlush } return nil } } func LoggerCoreWithOnError (onError LoggerCoreErrorFnc) LoggerCoreFnc { return func(a *LoggerCore) error { if a.State() != StateCreated { return G.ErrInvalidState.WrapWithMessage("config-logger-core-with-on-error") } a.onErrorFn = onError return nil } } func LoggerCoreWithOnEntryFatal (onFatal LoggerCoreEntryFnc) LoggerCoreFnc { return func(a *LoggerCore) error { if a.State() != StateCreated { return G.ErrInvalidState.WrapWithMessage("config-logger-core-with-on-fatal") } a.onEntryFatalFn = onFatal return nil } } func LoggerCoreWithOnEntryError (onError LoggerCoreEntryFnc) LoggerCoreFnc { return func(a *LoggerCore) error { if a.State() != StateCreated { return G.ErrInvalidState.WrapWithMessage("config-logger-core-with-entry-on-error") } a.onEntryErrorFn = onError return nil } } func LoggerCoreWithExtender (extender ...EntryExtender) LoggerCoreFnc { return func(a *LoggerCore) error { if a.State() != StateCreated { return G.ErrInvalidState.WrapWithMessage("config-logger-core-with-extender") } a.extenders = append(a.extenders,extender...) return nil } } func LoggerCoreWithFilters (configFilters EntryFiltersFnc) LoggerCoreFnc { return func(a *LoggerCore) error { if a.State() != StateCreated { return G.ErrInvalidState.WrapWithMessage("config-logger-core-with-filters") } configFilters(&a.filters) return nil } } func LoggerCoreWithAppender(appender EntryAppender) LoggerCoreFnc { return func(a *LoggerCore) error { if a.State() != StateCreated { return G.ErrInvalidState.WrapWithMessage("config-logger-core-with-appender") } a.appender = appender return nil } }