parent
2b12abf8ed
commit
88226e0679
@ -0,0 +1,49 @@
|
||||
// ------------------------------------------------------------------------
|
||||
// Project atila
|
||||
// Active Thing (activething.com) git.activething.com/go
|
||||
//
|
||||
// File name appender.go
|
||||
// Created by DEV
|
||||
// Modified 22/02/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 logs
|
||||
|
||||
|
||||
|
||||
type (
|
||||
|
||||
Appender interface {
|
||||
|
||||
Append (entry *Entry) error
|
||||
}
|
||||
|
||||
|
||||
NopAppender struct {}
|
||||
|
||||
AppendFnc func (entry *Entry) error
|
||||
)
|
||||
|
||||
|
||||
|
||||
func (f AppendFnc) Append (entry *Entry) error {
|
||||
return f(entry) }
|
||||
|
||||
|
||||
|
||||
func (_ NopAppender) Append (_ *Entry) error {
|
||||
return nil }
|
||||
@ -0,0 +1,105 @@
|
||||
// ------------------------------------------------------------------------
|
||||
// Project atila
|
||||
// Active Thing (activething.com) git.activething.com/go
|
||||
//
|
||||
// File name entry.go
|
||||
// Created by DEV
|
||||
// Modified 22/02/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 logs
|
||||
|
||||
import (
|
||||
"activething.com/go/gogo/core/errs"
|
||||
"activething.com/go/gogo/core/slices"
|
||||
"time"
|
||||
)
|
||||
|
||||
type (
|
||||
|
||||
|
||||
Entry struct {
|
||||
|
||||
logger Logger
|
||||
|
||||
Id uint64
|
||||
Scope string
|
||||
Scopes [][]byte
|
||||
Level Level
|
||||
|
||||
Message string
|
||||
Date time.Time
|
||||
|
||||
Err error
|
||||
Stack errs.StackTrace
|
||||
|
||||
Data any
|
||||
|
||||
excludes slices.String
|
||||
}
|
||||
|
||||
|
||||
EntryFnc func(*Entry)
|
||||
)
|
||||
|
||||
|
||||
|
||||
func NewEntry (logger Logger, level Level, message string, err error, options ...EntryFnc) *Entry {
|
||||
en := G.entryPool.Get().init(logger, level, message, err)
|
||||
for _, o := range options {
|
||||
o(en)
|
||||
}
|
||||
return en
|
||||
}
|
||||
|
||||
|
||||
func (e *Entry) init (logger Logger, level Level, message string, err error) *Entry {
|
||||
e.logger = logger
|
||||
e.Level = level
|
||||
e.Message = message
|
||||
e.Err = err
|
||||
return e
|
||||
}
|
||||
|
||||
|
||||
func (e *Entry) reset ()*Entry {
|
||||
e.logger = nil
|
||||
e.Stack = nil
|
||||
e.Data = nil
|
||||
e.Message = ""
|
||||
e.Scopes = e.Scopes [:0]
|
||||
e.excludes= e.excludes[:0]
|
||||
return e
|
||||
}
|
||||
|
||||
|
||||
func (e *Entry) HasExclude (exclude string) bool {
|
||||
return e.excludes.Has(exclude) }
|
||||
|
||||
|
||||
func (e *Entry) Clone () *Entry {
|
||||
c := G.entryPool.Get()
|
||||
c.Message = e.Message
|
||||
c.Level = e.Level
|
||||
c.Err = e.Err
|
||||
c.logger = e.logger
|
||||
c.Scope = e.Scope
|
||||
c.Scopes = append(c.Scopes[:0],e.Scopes...)
|
||||
c.excludes = append(c.excludes[:0],e.excludes ...)
|
||||
c.Stack = append(c.Stack[:0],e.Stack ...)
|
||||
return c
|
||||
}
|
||||
@ -0,0 +1,41 @@
|
||||
// ------------------------------------------------------------------------
|
||||
// Project atila
|
||||
// Active Thing (activething.com) git.activething.com/go
|
||||
//
|
||||
// File name entry_agregators.go
|
||||
// Created by DEV
|
||||
// Modified 23/02/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 logs
|
||||
|
||||
|
||||
|
||||
type EntryAggregators []EntryFnc
|
||||
|
||||
|
||||
|
||||
func (a EntryAggregators) Apply (entry *Entry) *Entry {
|
||||
for _,f := range a {
|
||||
f(entry)
|
||||
}
|
||||
return entry
|
||||
}
|
||||
|
||||
|
||||
func (a EntryAggregators) Aggregate(aggregator EntryFnc) EntryAggregators {
|
||||
return append(a,aggregator) }
|
||||
@ -0,0 +1,72 @@
|
||||
// ------------------------------------------------------------------------
|
||||
// Project atila
|
||||
// Active Thing (activething.com) git.activething.com/go
|
||||
//
|
||||
// File name entry_ops.go
|
||||
// Created by DEV
|
||||
// Modified 22/02/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 logs
|
||||
|
||||
import (
|
||||
"activething.com/go/gogo/core/errs"
|
||||
)
|
||||
|
||||
/*
|
||||
func EntryWithField (fld vals.Field, ovw bool)EntryFnc{
|
||||
return func(e *Entry){ e.Fields.AddField(fld,ovw,true) } }
|
||||
*/
|
||||
|
||||
/*
|
||||
func EntryWithNewField (fld string, val interface{}, ovw bool)EntryFnc{
|
||||
return func(e *Entry){ e.Fields.AddField(vals.NewField(fld,val),ovw,true) } }
|
||||
*/
|
||||
|
||||
|
||||
func EntryWithData (val interface{}) EntryFnc {
|
||||
return func(e *Entry){
|
||||
e.Data = val }
|
||||
}
|
||||
|
||||
|
||||
|
||||
func EntryWithError (err error) EntryFnc {
|
||||
return func(e *Entry){
|
||||
e.Err = err }
|
||||
}
|
||||
|
||||
|
||||
|
||||
func EntryWithCaller(level Level,skip int)EntryFnc{
|
||||
return func(e *Entry){
|
||||
if level.Has(e.Level) {
|
||||
e.Stack = errs.MakeStackTrace(skip)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
func EntryWithAggregator(agr EntryAggregator)EntryFnc{
|
||||
return func(e *Entry){ agr.Apply(e) } }
|
||||
*/
|
||||
|
||||
func EntryWithExcluder(exc string)EntryFnc{
|
||||
return func(e *Entry){
|
||||
e.excludes = append(e.excludes,exc) }
|
||||
}
|
||||
@ -0,0 +1,87 @@
|
||||
// ------------------------------------------------------------------------
|
||||
// Project atila
|
||||
// Active Thing (activething.com) git.activething.com/go
|
||||
//
|
||||
// File name filter.go
|
||||
// Created by DEV
|
||||
// Modified 23/02/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 logs
|
||||
|
||||
import "activething.com/go/gogo/sapis/tokens"
|
||||
|
||||
type (
|
||||
|
||||
Filter struct {
|
||||
name string
|
||||
active bool
|
||||
applyFn FilterFnc
|
||||
}
|
||||
|
||||
FilterFnc func (*Entry) bool
|
||||
)
|
||||
|
||||
|
||||
func NewFilter (name string, filterFn FilterFnc) *Filter {
|
||||
if filterFn == nil {
|
||||
filterFn = filterAlwaysTrue
|
||||
}
|
||||
return &Filter{
|
||||
name : name,
|
||||
active : true,
|
||||
applyFn : filterFn,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func NewFilterLevel (level Level) *Filter {
|
||||
l := level
|
||||
return NewFilter(level.String(),func(e *Entry) bool {
|
||||
return e.Level.Has(l) })
|
||||
}
|
||||
|
||||
|
||||
func NewFilterScope (scope string) *Filter {
|
||||
tk := tokens.NewTopic(G.tokenizer,[]byte(scope),tokens.TokenKindAll)
|
||||
if tk.Kind().HasInvalid() {
|
||||
return nil
|
||||
}
|
||||
return NewFilter(scope,func(e *Entry) bool {
|
||||
return tk.Match(e.Scopes) })
|
||||
}
|
||||
|
||||
|
||||
func (f Filter) Name () string {
|
||||
return f.name }
|
||||
|
||||
|
||||
func (f Filter) Active () bool {
|
||||
return f.active }
|
||||
|
||||
func (f Filter) SetActive (active bool) {
|
||||
f.active = active }
|
||||
|
||||
|
||||
func (f Filter) Apply (e *Entry) bool {
|
||||
return f.applyFn(e) }
|
||||
|
||||
|
||||
|
||||
|
||||
func filterAlwaysTrue(_ *Entry) bool {
|
||||
return true }
|
||||
@ -0,0 +1,62 @@
|
||||
// ------------------------------------------------------------------------
|
||||
// Project atila
|
||||
// Active Thing (activething.com) git.activething.com/go
|
||||
//
|
||||
// File name filters.go
|
||||
// Created by DEV
|
||||
// Modified 23/02/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 logs
|
||||
|
||||
import (
|
||||
"activething.com/go/gogo/core/opts"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type (
|
||||
|
||||
Filters struct {
|
||||
mux sync.RWMutex
|
||||
allows []Filter
|
||||
denies []Filter
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
|
||||
func NewFilters (options ...opts.OptionFnc[Filters]) *Filters {
|
||||
return opts.Apply[Filters](&Filters{}, options ...) }
|
||||
|
||||
|
||||
func (f *Filters) RegAllowed (filter Filter) {
|
||||
f.allows = append(f.allows,filter) }
|
||||
|
||||
func (f *Filters) RegDenied (filter Filter) {
|
||||
f.denies = append(f.denies,filter) }
|
||||
|
||||
|
||||
func (f *Filters) RegNewAllowed (name string, applyFn FilterFnc) {
|
||||
f.allows = append(f.allows,*NewFilter(name, applyFn)) }
|
||||
|
||||
|
||||
func (f *Filters) RegNewDenied (name string, applyFn FilterFnc) {
|
||||
f.denies = append(f.denies,*NewFilter(name, applyFn)) }
|
||||
|
||||
|
||||
|
||||
|
||||
@ -0,0 +1,4 @@
|
||||
module activething.com/go/gogo/logs
|
||||
|
||||
|
||||
go 1.20
|
||||
@ -0,0 +1,73 @@
|
||||
// ------------------------------------------------------------------------
|
||||
// Project atila
|
||||
// Active Thing (activething.com) git.activething.com/go
|
||||
//
|
||||
// File name gogo.go
|
||||
// Created by DEV
|
||||
// Modified 22/02/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 logs
|
||||
|
||||
import (
|
||||
"activething.com/go/gogo/core/errs"
|
||||
"activething.com/go/gogo/core/syncs"
|
||||
"activething.com/go/gogo/sapis/tokens"
|
||||
"sync/atomic"
|
||||
)
|
||||
|
||||
const(
|
||||
|
||||
scopeSep byte = '.'
|
||||
)
|
||||
|
||||
|
||||
var (
|
||||
|
||||
|
||||
G = struct {
|
||||
|
||||
entryIdGenerator uint64
|
||||
|
||||
ErrDuplicatedScope errs.ErrCode
|
||||
ErrDuplicatedLogger errs.ErrCode
|
||||
ErrInvalidScope errs.ErrCode
|
||||
ErrNotExistsLogger errs.ErrCode
|
||||
|
||||
entryPool *syncs.Pool[Entry]
|
||||
tokenizer *tokens.Tokenizer
|
||||
|
||||
}{
|
||||
ErrDuplicatedScope : errs.ErrCode ("logs:duplicated-scope"),
|
||||
ErrDuplicatedLogger: errs.ErrCode ("logs:duplicated-logger"),
|
||||
ErrInvalidScope : errs.ErrCode ("logs:invalid-scope"),
|
||||
ErrNotExistsLogger : errs.ErrCode ("logs:not-exists-logger"),
|
||||
|
||||
|
||||
entryPool: syncs.NewPool[Entry](
|
||||
syncs.PoolWithNew[Entry](func() *Entry {
|
||||
return &Entry{}
|
||||
})),
|
||||
tokenizer: tokens.NewTokenizer(),
|
||||
}
|
||||
|
||||
)
|
||||
|
||||
|
||||
|
||||
func newEntryId () uint64 {
|
||||
return atomic.AddUint64(&G.entryIdGenerator,1) }
|
||||
@ -0,0 +1,157 @@
|
||||
// ------------------------------------------------------------------------
|
||||
// Project atila
|
||||
// Active Thing (activething.com) git.activething.com/go
|
||||
//
|
||||
// File name level.go
|
||||
// Created by DEV
|
||||
// Modified 22/02/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 logs
|
||||
|
||||
import (
|
||||
"math/bits"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const(
|
||||
|
||||
levelsCount int = 6
|
||||
LevelNone Level = 0
|
||||
)
|
||||
|
||||
const(
|
||||
|
||||
LevelData Level = 1 << iota
|
||||
LevelDebug
|
||||
LevelInfo
|
||||
LevelWarn
|
||||
LevelError
|
||||
LevelFatal
|
||||
|
||||
LevelAll Level = LevelData|LevelDebug|LevelInfo|LevelWarn|LevelError|LevelFatal
|
||||
|
||||
)
|
||||
|
||||
|
||||
type (
|
||||
|
||||
Level uint8
|
||||
|
||||
|
||||
)
|
||||
|
||||
|
||||
func (lv Level) Add(lvl Level) Level {
|
||||
return lv | lvl }
|
||||
|
||||
|
||||
func (lv Level) Sub(lvl Level) Level {
|
||||
return lv &^ lvl }
|
||||
|
||||
|
||||
|
||||
func (lv Level) Has (lvl Level) bool {
|
||||
return lv&lvl != 0 }
|
||||
|
||||
|
||||
func (lv Level) HasData() bool {
|
||||
return lv&LevelData!=0 }
|
||||
|
||||
|
||||
func (lv Level) HasDebug() bool {
|
||||
return lv&LevelDebug!=0 }
|
||||
|
||||
|
||||
func (lv Level) HasInfo() bool {
|
||||
return lv&LevelInfo!=0 }
|
||||
|
||||
|
||||
func (lv Level) HasWarn() bool {
|
||||
return lv&LevelWarn!=0 }
|
||||
|
||||
|
||||
func (lv Level) HasError() bool {
|
||||
return lv&LevelError!=0 }
|
||||
|
||||
|
||||
func (lv Level) HasFatal() bool {
|
||||
return lv&LevelFatal!=0 }
|
||||
|
||||
|
||||
func (lv Level) Count() int{
|
||||
return bits.OnesCount8(uint8(lv)) }
|
||||
|
||||
|
||||
func (lv Level) String() string {
|
||||
return LevelNames(lv) }
|
||||
|
||||
|
||||
|
||||
func LevelList(level Level) []Level {
|
||||
var result [int(levelsCount)]Level
|
||||
x := 0
|
||||
for i := uint8(0); i <= uint8(levelsCount); i++ {
|
||||
c := Level(1 << i)
|
||||
level := c
|
||||
if level.Has(level) {
|
||||
result[x] = c
|
||||
x++
|
||||
}
|
||||
}
|
||||
return result[:x]
|
||||
}
|
||||
|
||||
|
||||
func LevelNames (level Level) string {
|
||||
if level == LevelNone {
|
||||
return ""
|
||||
}
|
||||
ix := 0
|
||||
ls := make([]string, levelsCount)
|
||||
if level&LevelData != 0 { ls[ix]="DATA"; ix++ }
|
||||
if level&LevelDebug!= 0 { ls[ix]="DEBUG";ix++ }
|
||||
if level&LevelInfo != 0 { ls[ix]="INFO" ;ix++ }
|
||||
if level&LevelWarn != 0 { ls[ix]="WARN" ;ix++ }
|
||||
if level&LevelError!= 0 { ls[ix]="ERROR";ix++ }
|
||||
if level&LevelFatal!= 0 { ls[ix]="FATAL";ix++ }
|
||||
if ix==0 {
|
||||
return ""
|
||||
}
|
||||
return strings.Join(ls[:ix],"|")
|
||||
}
|
||||
|
||||
|
||||
func LevelWithNames(name string) Level {
|
||||
if name == "" {
|
||||
return LevelNone
|
||||
}
|
||||
lv := LevelNone
|
||||
for _,sl := range strings.Split(strings.ToUpper(name),"|") {
|
||||
switch sl {
|
||||
case "DATA" : lv|=LevelData
|
||||
case "DEBUG": lv|=LevelDebug
|
||||
case "INFO" : lv|=LevelInfo
|
||||
case "WARN" : lv|=LevelWarn
|
||||
case "ERROR": lv|=LevelError
|
||||
case "FATAL": lv|=LevelFatal
|
||||
}
|
||||
}
|
||||
return lv
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,43 @@
|
||||
// ------------------------------------------------------------------------
|
||||
// Project atila
|
||||
// Active Thing (activething.com) git.activething.com/go
|
||||
//
|
||||
// File name loggable.go
|
||||
// Created by DEV
|
||||
// Modified 22/02/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 logs
|
||||
|
||||
|
||||
|
||||
type (
|
||||
|
||||
Loggable interface {
|
||||
|
||||
Log (entry *Entry) error
|
||||
}
|
||||
|
||||
|
||||
LogFnc func (entry *Entry) error
|
||||
|
||||
)
|
||||
|
||||
|
||||
func (f LogFnc) Log (entry *Entry) error {
|
||||
return f(entry) }
|
||||
|
||||
@ -0,0 +1,47 @@
|
||||
// ------------------------------------------------------------------------
|
||||
// Project atila
|
||||
// Active Thing (activething.com) git.activething.com/go
|
||||
//
|
||||
// File name logger.go
|
||||
// Created by DEV
|
||||
// Modified 22/02/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 logs
|
||||
|
||||
|
||||
|
||||
type (
|
||||
|
||||
|
||||
Logger interface {
|
||||
|
||||
Name () string
|
||||
|
||||
Level () Level
|
||||
|
||||
Fatal (message string, err error, options ...EntryFnc)
|
||||
Error (message string, err error, options ...EntryFnc)
|
||||
Warn (message string, options ...EntryFnc)
|
||||
Info (message string, options ...EntryFnc)
|
||||
Debug (message string, options ...EntryFnc)
|
||||
Data (message string, data any, options ...EntryFnc)
|
||||
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@ -0,0 +1,45 @@
|
||||
// ------------------------------------------------------------------------
|
||||
// Project atila
|
||||
// Active Thing (activething.com) git.activething.com/go
|
||||
//
|
||||
// File name logger_level.go
|
||||
// Created by DEV
|
||||
// Modified 22/02/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 logs
|
||||
|
||||
import "sync"
|
||||
|
||||
type (
|
||||
|
||||
loggerLevel struct {
|
||||
mux sync.RWMutex
|
||||
name string
|
||||
level Level
|
||||
logFnc func (level Level, message string, err error, options ...*EntryFnc)
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
|
||||
func newLoggerLevel (name string, level Level) *loggerLevel {
|
||||
return &loggerLevel{
|
||||
name : name,
|
||||
level: level,
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,183 @@
|
||||
// ------------------------------------------------------------------------
|
||||
// Project atila
|
||||
// Active Thing (activething.com) git.activething.com/go
|
||||
//
|
||||
// File name scope.go
|
||||
// Created by DEV
|
||||
// Modified 22/02/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 logs
|
||||
|
||||
import (
|
||||
"activething.com/go/gogo/core/opts"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type (
|
||||
|
||||
Scope struct {
|
||||
loggerLevel
|
||||
|
||||
level Level
|
||||
mode ScopeMode
|
||||
|
||||
path string
|
||||
nodes [][]byte
|
||||
|
||||
parent Loggable
|
||||
children []*Scope
|
||||
|
||||
aggregators EntryAggregators
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
func newScope (name string, level Level, parent Loggable, path string, nodes [][]byte, options ...opts.OptionFnc[Scope]) *Scope {
|
||||
if path != "" {
|
||||
path = fmt.Sprintf("%s%c%s",path,scopeSep,name)
|
||||
} else {
|
||||
path = name
|
||||
}
|
||||
|
||||
return opts.Apply[Scope](&Scope {
|
||||
loggerLevel: *newLoggerLevel(name,level),
|
||||
parent : parent,
|
||||
nodes : append(nodes,[]byte(name)),
|
||||
path : path,
|
||||
}, options ...)
|
||||
}
|
||||
|
||||
|
||||
func (s *Scope) Mode () (m ScopeMode) {
|
||||
s.mux.RLock()
|
||||
m = s.mode
|
||||
s.mux.RUnlock()
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
func (s *Scope) SetMode(mode ScopeMode) {
|
||||
s.mux.Lock()
|
||||
s.mode = mode
|
||||
s.mux.Unlock()
|
||||
}
|
||||
|
||||
|
||||
func (s *Scope) Level() Level {
|
||||
return s.level }
|
||||
|
||||
|
||||
func (s *Scope) Path () string {
|
||||
return s.path }
|
||||
|
||||
|
||||
func (s *Scope) Nodes () [][]byte {
|
||||
return s.nodes }
|
||||
|
||||
|
||||
|
||||
func (s *Scope) NewChildScope (path string, options ...opts.OptionFnc[Scope]) (*Scope,error) {
|
||||
s.mux.Lock()
|
||||
sc,er := s.newChildScope(strings.Split(strings.ToLower(path),string(scopeSep)),options ...)
|
||||
s.mux.Unlock()
|
||||
return sc,er
|
||||
}
|
||||
|
||||
func (s *Scope) newChildScope (path []string, options ...opts.OptionFnc[Scope])(*Scope,error){
|
||||
sc := s.getChildScope(path[0])
|
||||
if sc == nil {
|
||||
sc = newScope(path[0],s.level, s, s.path, s.nodes, options ...)
|
||||
s.children = append (s.children, sc)
|
||||
if len(path) == 1 {
|
||||
return sc, nil
|
||||
}
|
||||
} else if len(path) == 1 {
|
||||
return nil,G.ErrDuplicatedScope
|
||||
}
|
||||
return sc.newChildScope(path[1:],options...)
|
||||
}
|
||||
|
||||
|
||||
|
||||
func (s *Scope) GetScope (name string) *Scope {
|
||||
return s.getScope(strings.Split(strings.ToLower(name),string(scopeSep))) }
|
||||
|
||||
func (s *Scope) getScope (nodes []string) *Scope {
|
||||
s.mux.RLock()
|
||||
sc := s.getChildScope(nodes[0])
|
||||
if sc != nil {
|
||||
if len(nodes) > 1 {
|
||||
sc = sc.getScope(nodes[1:])
|
||||
}
|
||||
}
|
||||
s.mux.RUnlock()
|
||||
return sc
|
||||
}
|
||||
|
||||
|
||||
func (s *Scope) getChildScope (name string) *Scope {
|
||||
if i := s.findChildScope(name); i != -1 {
|
||||
return s.children[i]
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
func (s *Scope) findChildScope (name string) int {
|
||||
for i,s := range s.children {
|
||||
if name == s.name {
|
||||
return i
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
|
||||
func (s *Scope) Log (entry *Entry) error {
|
||||
s.mux.Lock()
|
||||
if s.mode.IsFilter() && s.level.Has(entry.Level) {
|
||||
s.mux.Unlock()
|
||||
return nil
|
||||
}
|
||||
if s.mode.IsCascade() {
|
||||
s.aggregators.Apply(entry)
|
||||
}
|
||||
s.mux.Unlock()
|
||||
return s.parent.Log(entry)
|
||||
}
|
||||
|
||||
|
||||
func (s *Scope) log(lvl Level, msg string, err error,options ...EntryFnc){
|
||||
s.mux.Lock()
|
||||
if !s.level.Has(lvl) {
|
||||
s.mux.Unlock()
|
||||
return
|
||||
}
|
||||
en := s.aggregators.Apply(NewEntry(nil,lvl,msg,err,options...))
|
||||
en.Scope = s.path
|
||||
en.Scopes= s.nodes
|
||||
s.mux.Unlock()
|
||||
|
||||
s.parent.Log(en)
|
||||
G.entryPool.Put(en)
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,53 @@
|
||||
// ------------------------------------------------------------------------
|
||||
// Project atila
|
||||
// Active Thing (activething.com) git.activething.com/go
|
||||
//
|
||||
// File name scope_mode.go
|
||||
// Created by DEV
|
||||
// Modified 22/02/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 logs
|
||||
|
||||
|
||||
|
||||
const (
|
||||
|
||||
|
||||
ScopeDirect ScopeMode = 0
|
||||
ScopeCascade ScopeMode = 1
|
||||
ScopeFilter ScopeMode = 2
|
||||
|
||||
)
|
||||
|
||||
|
||||
|
||||
type (
|
||||
|
||||
ScopeMode uint8
|
||||
|
||||
)
|
||||
|
||||
|
||||
func (m ScopeMode) IsDirect () bool {
|
||||
return m == ScopeDirect }
|
||||
|
||||
func (m ScopeMode) IsCascade() bool {
|
||||
return m&ScopeCascade!=0 }
|
||||
|
||||
func (m ScopeMode) IsFilter () bool {
|
||||
return m&ScopeFilter!=0 }
|
||||
@ -0,0 +1,67 @@
|
||||
// ------------------------------------------------------------------------
|
||||
// Project atila
|
||||
// Active Thing (activething.com) git.activething.com/go
|
||||
//
|
||||
// File name scope_ops.go
|
||||
// Created by DEV
|
||||
// Modified 23/02/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 logs
|
||||
|
||||
import "activething.com/go/gogo/core/opts"
|
||||
|
||||
func ScopeWithModeDirect () opts.OptionFnc[Scope] {
|
||||
return func(s *Scope){
|
||||
s.mode = ScopeDirect }
|
||||
}
|
||||
|
||||
|
||||
|
||||
func ScopeWithModeFilter ()opts.OptionFnc[Scope] {
|
||||
return func(s *Scope){
|
||||
s.mode |= ScopeFilter }
|
||||
}
|
||||
|
||||
|
||||
|
||||
func ScopeWithModeCascade ()opts.OptionFnc[Scope] {
|
||||
return func(s *Scope){
|
||||
s.mode |= ScopeCascade }
|
||||
}
|
||||
|
||||
|
||||
|
||||
func ScopeWithLevel (lvl Level)opts.OptionFnc[Scope] {
|
||||
return func(s *Scope){
|
||||
s.level = lvl }
|
||||
}
|
||||
|
||||
|
||||
func ScopeWithAggregates(efn ...EntryFnc)opts.OptionFnc[Scope]{
|
||||
return func(a *Scope){
|
||||
for _,f := range efn {
|
||||
a.aggregators.Aggregate(f)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -0,0 +1,41 @@
|
||||
// ------------------------------------------------------------------------
|
||||
// Project atila
|
||||
// Active Thing (activething.com) git.activething.com/go
|
||||
//
|
||||
// File name state.go
|
||||
// Created by DEV
|
||||
// Modified 22/02/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 logs
|
||||
|
||||
|
||||
|
||||
const (
|
||||
|
||||
StateCreated State = iota
|
||||
StateStarted
|
||||
StateStopped
|
||||
)
|
||||
|
||||
|
||||
|
||||
type (
|
||||
|
||||
State uint8
|
||||
|
||||
)
|
||||
Loading…
Reference in new issue