mirror of
https://github.com/nabbar/golib.git
synced 2025-10-31 02:56:26 +08:00
- Change reloading component method : try to reload all component and store errors, report list of errors but don't break the reloading process Package Logger : - Fix bug with entry logger filtering Package Viper: - reword message log before reloading config file (watchFS) - add message log after reloading config file (watchFS) Package Status : - Fix DATA Race with status/info - Add component key into log error message for health - Add component key into function to use it into info (name) - Reword health message : no OK/KO (still into status info), add error message reporting Package httpserver : - status info : apply update status component, use key in name - status info : optimize code Package Request : - Fix error in url path operation - Status info : optimize code - Status info : apply update component, add endpoint hostname with name Package Static : - apply status component update Other : - Bump dependencies
269 lines
5.4 KiB
Go
269 lines
5.4 KiB
Go
/***********************************************************************************************************************
|
|
*
|
|
* MIT License
|
|
*
|
|
* Copyright (c) 2021 Nicolas JUHEL
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
* of this software and associated documentation files (the "Software"), to deal
|
|
* in the Software without restriction, including without limitation the rights
|
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
* copies of the Software, and to permit persons to whom the Software is
|
|
* furnished to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be included in all
|
|
* copies or substantial portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
* SOFTWARE.
|
|
*
|
|
*
|
|
**********************************************************************************************************************/
|
|
|
|
package logger
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"strings"
|
|
"sync"
|
|
|
|
"github.com/sirupsen/logrus"
|
|
)
|
|
|
|
type HookSyslog interface {
|
|
logrus.Hook
|
|
io.WriteCloser
|
|
RegisterHook(log *logrus.Logger)
|
|
}
|
|
|
|
type syslogWrapper interface {
|
|
io.WriteCloser
|
|
|
|
Panic(p []byte) (n int, err error)
|
|
Fatal(p []byte) (n int, err error)
|
|
Error(p []byte) (n int, err error)
|
|
Warning(p []byte) (n int, err error)
|
|
Info(p []byte) (n int, err error)
|
|
Debug(p []byte) (n int, err error)
|
|
}
|
|
|
|
type FuncFormatter func() logrus.Formatter
|
|
|
|
type _HookSyslog struct {
|
|
m sync.Mutex
|
|
w syslogWrapper
|
|
f logrus.Formatter
|
|
l []logrus.Level
|
|
o _HookSyslogOptions
|
|
}
|
|
|
|
type _HookSyslogOptions struct {
|
|
Net NetworkType
|
|
Hst string
|
|
Tag string
|
|
// Sev SyslogSeverity
|
|
Fac SyslogFacility
|
|
|
|
Pid bool
|
|
Tms bool
|
|
Trc bool
|
|
Acc bool
|
|
}
|
|
|
|
func NewHookSyslog(opt OptionsSyslog, format logrus.Formatter) (HookSyslog, error) {
|
|
var (
|
|
LVLs = make([]logrus.Level, 0)
|
|
sys syslogWrapper
|
|
err error
|
|
)
|
|
|
|
if len(opt.LogLevel) > 0 {
|
|
for _, ls := range opt.LogLevel {
|
|
LVLs = append(LVLs, GetLevelString(ls).Logrus())
|
|
}
|
|
} else {
|
|
LVLs = logrus.AllLevels
|
|
}
|
|
|
|
obj := &_HookSyslog{
|
|
m: sync.Mutex{},
|
|
w: sys,
|
|
f: format,
|
|
l: LVLs,
|
|
o: _HookSyslogOptions{
|
|
Net: MakeNetwork(opt.Network),
|
|
Hst: opt.Host,
|
|
Tag: opt.Tag,
|
|
// Sev: MakeSeverity(opt.Severity),
|
|
Fac: MakeFacility(opt.Facility),
|
|
Pid: opt.DisableStack,
|
|
Tms: opt.DisableTimestamp,
|
|
Trc: opt.EnableTrace,
|
|
Acc: opt.EnableAccessLog,
|
|
},
|
|
}
|
|
|
|
if h, e := obj.openCreate(); e != nil {
|
|
return nil, e
|
|
} else {
|
|
_ = h.Close()
|
|
}
|
|
|
|
return obj, err
|
|
}
|
|
|
|
func (o *_HookSyslog) openCreate() (syslogWrapper, error) {
|
|
return newSyslog(o.o.Net, o.o.Hst, o.o.Tag, o.o.Fac)
|
|
//return newSyslog(o.o.Net, o.o.Hst, o.o.Tag, o.o.Sev, o.o.Fac)
|
|
}
|
|
|
|
func (o *_HookSyslog) isStack() bool {
|
|
o.m.Lock()
|
|
defer o.m.Unlock()
|
|
|
|
return o.o.Pid
|
|
}
|
|
|
|
func (o *_HookSyslog) isTimeStamp() bool {
|
|
o.m.Lock()
|
|
defer o.m.Unlock()
|
|
|
|
return o.o.Tms
|
|
}
|
|
|
|
func (o *_HookSyslog) isTrace() bool {
|
|
o.m.Lock()
|
|
defer o.m.Unlock()
|
|
|
|
return o.o.Trc
|
|
}
|
|
|
|
func (o *_HookSyslog) isAccessLog() bool {
|
|
o.m.Lock()
|
|
defer o.m.Unlock()
|
|
|
|
return o.o.Acc
|
|
}
|
|
|
|
func (o *_HookSyslog) RegisterHook(log *logrus.Logger) {
|
|
log.AddHook(o)
|
|
}
|
|
|
|
func (o *_HookSyslog) Levels() []logrus.Level {
|
|
return o.l
|
|
}
|
|
|
|
func (o *_HookSyslog) Fire(entry *logrus.Entry) error {
|
|
ent := entry.Dup()
|
|
ent.Level = entry.Level
|
|
|
|
if o.isStack() {
|
|
ent.Data = o.filterKey(ent.Data, FieldStack)
|
|
}
|
|
|
|
if o.isTimeStamp() {
|
|
ent.Data = o.filterKey(ent.Data, FieldTime)
|
|
}
|
|
|
|
if !o.isTrace() {
|
|
ent.Data = o.filterKey(ent.Data, FieldCaller)
|
|
ent.Data = o.filterKey(ent.Data, FieldFile)
|
|
ent.Data = o.filterKey(ent.Data, FieldLine)
|
|
}
|
|
|
|
var (
|
|
p []byte
|
|
e error
|
|
)
|
|
|
|
if o.isAccessLog() {
|
|
if len(entry.Message) > 0 {
|
|
if !strings.HasSuffix(entry.Message, "\n") {
|
|
entry.Message += "\n"
|
|
}
|
|
p = []byte(entry.Message)
|
|
} else {
|
|
return nil
|
|
}
|
|
} else {
|
|
if len(ent.Data) < 1 {
|
|
return nil
|
|
} else if p, e = ent.Bytes(); e != nil {
|
|
return e
|
|
}
|
|
}
|
|
|
|
if _, e = o.writeLevel(ent.Level, p); e != nil {
|
|
_ = o.Close()
|
|
_, e = o.writeLevel(ent.Level, p)
|
|
}
|
|
|
|
return e
|
|
}
|
|
|
|
func (o *_HookSyslog) Write(p []byte) (n int, err error) {
|
|
return o.writeLevel(logrus.InfoLevel, p)
|
|
}
|
|
|
|
func (o *_HookSyslog) writeLevel(lvl logrus.Level, p []byte) (n int, err error) {
|
|
o.m.Lock()
|
|
defer o.m.Unlock()
|
|
|
|
if o.w == nil {
|
|
var e error
|
|
if o.w, e = o.openCreate(); e != nil {
|
|
return 0, fmt.Errorf("logrus.hooksyslog: %v", e)
|
|
}
|
|
}
|
|
|
|
switch lvl {
|
|
case logrus.PanicLevel:
|
|
return o.w.Panic(p)
|
|
case logrus.FatalLevel:
|
|
return o.w.Fatal(p)
|
|
case logrus.ErrorLevel:
|
|
return o.w.Error(p)
|
|
case logrus.WarnLevel:
|
|
return o.w.Warning(p)
|
|
case logrus.InfoLevel:
|
|
return o.w.Info(p)
|
|
case logrus.DebugLevel:
|
|
return o.w.Debug(p)
|
|
default:
|
|
return o.w.Write(p)
|
|
}
|
|
}
|
|
|
|
func (o *_HookSyslog) Close() error {
|
|
o.m.Lock()
|
|
defer o.m.Unlock()
|
|
|
|
var e error
|
|
|
|
if o.w != nil {
|
|
e = o.w.Close()
|
|
}
|
|
|
|
o.w = nil
|
|
return e
|
|
}
|
|
|
|
func (o *_HookSyslog) filterKey(f logrus.Fields, key string) logrus.Fields {
|
|
if len(f) < 1 {
|
|
return f
|
|
}
|
|
|
|
if _, ok := f[key]; !ok {
|
|
return f
|
|
} else {
|
|
delete(f, key)
|
|
return f
|
|
}
|
|
}
|