mirror of
https://github.com/nabbar/golib.git
synced 2025-10-31 02:56:26 +08:00
Package Logger:
- Rework logger - Remove deprecated functions - Split Logger to sub package (fields, level, config, ...) - Optimize dependencies - Rework Hookfile: fix error like FD still opened - Rework Hooksyslog: use same model like Hookfile, use network/protocol instead of self lib - Rework HookStd: use independent hook for std out & std err - Fix std config make generic options for files & syslog - Apply formatter to hook instead of main logger entry - optimize code Package ioutils: - rework PathCheckCreate funct: optimize code & fix some error Package Network: - create sub package protocol for all network protocl use - add encode function Package httpcli: - remove file network - use package network/protocol instead of network file Package archive: - apply change following rework of logger Package aws: - apply change following rework of logger Package cluster: - apply change following rework of logger Package cobra: - apply change following rework of logger Package Config Component: - apply change following rework of logger to component log - fix logger for monitoring - fix component following fix of package request / monitoring Package context: - apply change following rework of logger Package database: - apply change following rework of logger Package httpserver: - apply change following rework of logger Package ldap: - apply change following rework of logger Package monitor: - apply change following rework of logger - fix logger for monitoring - fix minor bugs Package nats: - apply change following rework of logger Package nutsdb: - apply change following rework of logger Package request: - apply change following rework of logger - fix minor bug - fix missing logger for monitoring - add one line for healthcheck (info or error) Package router: - apply change following rework of logger Package static: - apply change following rework of logger Package status: - apply change following rework of logger - fix bug with mandatory component Package viper: - apply change following rework of logger Other: - bump dependencies - github action workflow fix
This commit is contained in:
13
.github/workflows/go.yml
vendored
13
.github/workflows/go.yml
vendored
@@ -1,9 +1,5 @@
|
|||||||
name: Go
|
name: Go
|
||||||
|
|
||||||
env:
|
|
||||||
GOPATH: "/go"
|
|
||||||
GO111MODULE: "on"
|
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches: [ master ]
|
branches: [ master ]
|
||||||
@@ -13,7 +9,6 @@ on:
|
|||||||
jobs:
|
jobs:
|
||||||
|
|
||||||
build:
|
build:
|
||||||
name: Build
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
|
|
||||||
@@ -21,10 +16,12 @@ jobs:
|
|||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
- name: Set up Go 1.x
|
- name: Set up Go 1.x
|
||||||
uses: actions/setup-go@v2
|
uses: actions/setup-go@v4
|
||||||
with:
|
with:
|
||||||
go-version: '>=1.18.0'
|
go-version: '>=1.20'
|
||||||
check-latest: true
|
|
||||||
|
- name: Check Go Version
|
||||||
|
run: go version
|
||||||
|
|
||||||
- name: Link workspace with GOPATH
|
- name: Link workspace with GOPATH
|
||||||
continue-on-error: false
|
continue-on-error: false
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ import (
|
|||||||
libzip "github.com/nabbar/golib/archive/zip"
|
libzip "github.com/nabbar/golib/archive/zip"
|
||||||
liberr "github.com/nabbar/golib/errors"
|
liberr "github.com/nabbar/golib/errors"
|
||||||
libiot "github.com/nabbar/golib/ioutils"
|
libiot "github.com/nabbar/golib/ioutils"
|
||||||
liblog "github.com/nabbar/golib/logger"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type ArchiveType uint8
|
type ArchiveType uint8
|
||||||
@@ -125,33 +124,22 @@ func ExtractAll(src libiot.FileProgress, originalName, outputPath string, defaul
|
|||||||
return ErrorFileOpen.Error(err)
|
return ErrorFileOpen.Error(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
liblog.DebugLevel.Log("try BZ2...")
|
|
||||||
if err = libbz2.GetFile(src, tmp); err == nil {
|
if err = libbz2.GetFile(src, tmp); err == nil {
|
||||||
liblog.DebugLevel.Log("try another archive...")
|
|
||||||
return ExtractAll(tmp, originalName, outputPath, defaultDirPerm)
|
return ExtractAll(tmp, originalName, outputPath, defaultDirPerm)
|
||||||
} else if !err.IsCodeError(libbz2.ErrorIOCopy) {
|
} else if !err.IsCodeError(libbz2.ErrorIOCopy) {
|
||||||
liblog.DebugLevel.Logf("error found on BZ2 : %v", err)
|
|
||||||
return err
|
return err
|
||||||
} else {
|
|
||||||
liblog.DebugLevel.Logf("not a BZ2 : %v", err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
liblog.DebugLevel.Log("try GZIP...")
|
|
||||||
if err = libgzp.GetFile(src, tmp); err == nil {
|
if err = libgzp.GetFile(src, tmp); err == nil {
|
||||||
liblog.DebugLevel.Log("try another archive...")
|
|
||||||
return ExtractAll(tmp, originalName, outputPath, defaultDirPerm)
|
return ExtractAll(tmp, originalName, outputPath, defaultDirPerm)
|
||||||
} else if !err.IsCodeError(libgzp.ErrorGZReader) {
|
} else if !err.IsCodeError(libgzp.ErrorGZReader) {
|
||||||
liblog.DebugLevel.Logf("error found on GZIP : %v", err)
|
|
||||||
return err
|
return err
|
||||||
} else {
|
|
||||||
liblog.DebugLevel.Logf("not a GZIP : %v", err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if tmp != nil {
|
if tmp != nil {
|
||||||
_ = tmp.Close()
|
_ = tmp.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
liblog.DebugLevel.Log("prepare output...")
|
|
||||||
if i, e := os.Stat(outputPath); e != nil && os.IsNotExist(e) {
|
if i, e := os.Stat(outputPath); e != nil && os.IsNotExist(e) {
|
||||||
//nolint #nosec
|
//nolint #nosec
|
||||||
/* #nosec */
|
/* #nosec */
|
||||||
@@ -164,29 +152,18 @@ func ExtractAll(src libiot.FileProgress, originalName, outputPath string, defaul
|
|||||||
return ErrorDirNotDir.Error(nil)
|
return ErrorDirNotDir.Error(nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
liblog.DebugLevel.Log("try tar...")
|
|
||||||
if err = libtar.GetAll(src, outputPath, defaultDirPerm); err == nil {
|
if err = libtar.GetAll(src, outputPath, defaultDirPerm); err == nil {
|
||||||
liblog.DebugLevel.Log("extracting TAR finished...")
|
|
||||||
return nil
|
return nil
|
||||||
} else if !err.IsCodeError(libtar.ErrorTarNext) {
|
} else if !err.IsCodeError(libtar.ErrorTarNext) {
|
||||||
liblog.DebugLevel.Logf("error found on TAR : %v", err)
|
|
||||||
return err
|
return err
|
||||||
} else {
|
|
||||||
liblog.DebugLevel.Logf("not a TAR : %v", err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
liblog.DebugLevel.Log("try zip...")
|
|
||||||
if err = libzip.GetAll(src, outputPath, defaultDirPerm); err == nil {
|
if err = libzip.GetAll(src, outputPath, defaultDirPerm); err == nil {
|
||||||
liblog.DebugLevel.Log("extracting ZIP finished...")
|
|
||||||
return nil
|
return nil
|
||||||
} else if !err.IsCodeError(libzip.ErrorZipOpen) {
|
} else if !err.IsCodeError(libzip.ErrorZipOpen) {
|
||||||
liblog.DebugLevel.Logf("error found on ZIP : %v", err)
|
|
||||||
return err
|
return err
|
||||||
} else {
|
|
||||||
liblog.DebugLevel.Logf("not a ZIP : %v", err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
liblog.DebugLevel.Log("writing original file...")
|
|
||||||
if dst, err = src.NewFilePathWrite(filepath.Join(outputPath, originalName), true, true, 0664); err != nil {
|
if dst, err = src.NewFilePathWrite(filepath.Join(outputPath, originalName), true, true, 0664); err != nil {
|
||||||
return ErrorFileOpen.Error(err)
|
return ErrorFileOpen.Error(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,7 +31,6 @@ import (
|
|||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
libsiz "github.com/nabbar/golib/size"
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
@@ -49,6 +48,7 @@ import (
|
|||||||
"github.com/nabbar/golib/aws/configCustom"
|
"github.com/nabbar/golib/aws/configCustom"
|
||||||
"github.com/nabbar/golib/httpcli"
|
"github.com/nabbar/golib/httpcli"
|
||||||
"github.com/nabbar/golib/password"
|
"github.com/nabbar/golib/password"
|
||||||
|
libsiz "github.com/nabbar/golib/size"
|
||||||
. "github.com/onsi/ginkgo/v2"
|
. "github.com/onsi/ginkgo/v2"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -32,13 +32,11 @@ import (
|
|||||||
"net/url"
|
"net/url"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
libreq "github.com/nabbar/golib/request"
|
|
||||||
|
|
||||||
sdkaws "github.com/aws/aws-sdk-go-v2/aws"
|
sdkaws "github.com/aws/aws-sdk-go-v2/aws"
|
||||||
libval "github.com/go-playground/validator/v10"
|
libval "github.com/go-playground/validator/v10"
|
||||||
liberr "github.com/nabbar/golib/errors"
|
liberr "github.com/nabbar/golib/errors"
|
||||||
libhtc "github.com/nabbar/golib/httpcli"
|
libhtc "github.com/nabbar/golib/httpcli"
|
||||||
liblog "github.com/nabbar/golib/logger"
|
libreq "github.com/nabbar/golib/request"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Model struct {
|
type Model struct {
|
||||||
@@ -247,7 +245,6 @@ func (c *awsModel) ResolveEndpointWithOptions(service, region string, options ..
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
liblog.DebugLevel.Logf("Called ResolveEndpoint for service '%s' / region '%s' with nil endpoint", service, region)
|
|
||||||
return sdkaws.Endpoint{}, ErrorEndpointInvalid.Error(nil)
|
return sdkaws.Endpoint{}, ErrorEndpointInvalid.Error(nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,15 +31,20 @@
|
|||||||
package cluster
|
package cluster
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
dgblog "github.com/lni/dragonboat/v3/logger"
|
dgblog "github.com/lni/dragonboat/v3/logger"
|
||||||
liblog "github.com/nabbar/golib/logger"
|
liblog "github.com/nabbar/golib/logger"
|
||||||
|
loglvl "github.com/nabbar/golib/logger/level"
|
||||||
)
|
)
|
||||||
|
|
||||||
const LogLib = "DragonBoat"
|
const LogLib = "DragonBoat"
|
||||||
|
|
||||||
func SetLoggerFactory(log liblog.FuncLog) {
|
func SetLoggerFactory(log liblog.FuncLog) {
|
||||||
if log == nil {
|
if log == nil {
|
||||||
log = liblog.GetDefault
|
log = func() liblog.Logger {
|
||||||
|
return liblog.New(context.Background)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dgblog.SetLoggerFactory(func(pkgName string) dgblog.ILogger {
|
dgblog.SetLoggerFactory(func(pkgName string) dgblog.ILogger {
|
||||||
@@ -62,42 +67,44 @@ func (l *logDragonBoat) SetLevel(level dgblog.LogLevel) {
|
|||||||
|
|
||||||
switch level {
|
switch level {
|
||||||
case dgblog.CRITICAL:
|
case dgblog.CRITICAL:
|
||||||
l.log().SetLevel(liblog.FatalLevel)
|
l.log().SetLevel(loglvl.FatalLevel)
|
||||||
case dgblog.ERROR:
|
case dgblog.ERROR:
|
||||||
l.log().SetLevel(liblog.ErrorLevel)
|
l.log().SetLevel(loglvl.ErrorLevel)
|
||||||
case dgblog.WARNING:
|
case dgblog.WARNING:
|
||||||
l.log().SetLevel(liblog.WarnLevel)
|
l.log().SetLevel(loglvl.WarnLevel)
|
||||||
case dgblog.INFO:
|
case dgblog.INFO:
|
||||||
l.log().SetLevel(liblog.InfoLevel)
|
l.log().SetLevel(loglvl.InfoLevel)
|
||||||
case dgblog.DEBUG:
|
case dgblog.DEBUG:
|
||||||
l.log().SetLevel(liblog.DebugLevel)
|
l.log().SetLevel(loglvl.DebugLevel)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *logDragonBoat) logMsg(lvl liblog.Level, message string, args ...interface{}) {
|
func (l *logDragonBoat) logMsg(lvl loglvl.Level, message string, args ...interface{}) {
|
||||||
if l.log == nil {
|
if l.log == nil {
|
||||||
l.log = liblog.GetDefault
|
l.log = func() liblog.Logger {
|
||||||
|
return liblog.New(context.Background)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
l.log().Entry(lvl, message, args...).FieldAdd("lib", LogLib).FieldAdd("pkg", l.pkg).Log()
|
l.log().Entry(lvl, message, args...).FieldAdd("lib", LogLib).FieldAdd("pkg", l.pkg).Log()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *logDragonBoat) Debugf(format string, args ...interface{}) {
|
func (l *logDragonBoat) Debugf(format string, args ...interface{}) {
|
||||||
l.logMsg(liblog.DebugLevel, format, args...)
|
l.logMsg(loglvl.DebugLevel, format, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *logDragonBoat) Infof(format string, args ...interface{}) {
|
func (l *logDragonBoat) Infof(format string, args ...interface{}) {
|
||||||
l.logMsg(liblog.InfoLevel, format, args...)
|
l.logMsg(loglvl.InfoLevel, format, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *logDragonBoat) Warningf(format string, args ...interface{}) {
|
func (l *logDragonBoat) Warningf(format string, args ...interface{}) {
|
||||||
l.logMsg(liblog.WarnLevel, format, args...)
|
l.logMsg(loglvl.WarnLevel, format, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *logDragonBoat) Errorf(format string, args ...interface{}) {
|
func (l *logDragonBoat) Errorf(format string, args ...interface{}) {
|
||||||
l.logMsg(liblog.ErrorLevel, format, args...)
|
l.logMsg(loglvl.ErrorLevel, format, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *logDragonBoat) Panicf(format string, args ...interface{}) {
|
func (l *logDragonBoat) Panicf(format string, args ...interface{}) {
|
||||||
l.logMsg(liblog.FatalLevel, format, args...)
|
l.logMsg(loglvl.FatalLevel, format, args...)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
liblog "github.com/nabbar/golib/logger"
|
loglvl "github.com/nabbar/golib/logger/level"
|
||||||
spfcbr "github.com/spf13/cobra"
|
spfcbr "github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -57,37 +57,37 @@ func (c *cobra) AddCommandCompletion() {
|
|||||||
var file string
|
var file string
|
||||||
|
|
||||||
if len(args) < 1 {
|
if len(args) < 1 {
|
||||||
c.getLog().CheckError(liblog.ErrorLevel, liblog.NilLevel, "missing args", cmd.Usage())
|
c.getLog().CheckError(loglvl.ErrorLevel, loglvl.NilLevel, "missing args", cmd.Usage())
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
} else if len(args) >= 2 {
|
} else if len(args) >= 2 {
|
||||||
file = filepath.Clean(args[1])
|
file = filepath.Clean(args[1])
|
||||||
c.getLog().CheckError(liblog.ErrorLevel, liblog.NilLevel, "create file path", os.MkdirAll(filepath.Dir(file), 0755))
|
c.getLog().CheckError(loglvl.ErrorLevel, loglvl.NilLevel, "create file path", os.MkdirAll(filepath.Dir(file), 0755))
|
||||||
}
|
}
|
||||||
|
|
||||||
switch strings.ToLower(args[0]) {
|
switch strings.ToLower(args[0]) {
|
||||||
case "bash":
|
case "bash":
|
||||||
if file == "" {
|
if file == "" {
|
||||||
c.getLog().CheckError(liblog.ErrorLevel, liblog.NilLevel, "generating bash completion", c.c.GenBashCompletionV2(os.Stdout, true))
|
c.getLog().CheckError(loglvl.ErrorLevel, loglvl.NilLevel, "generating bash completion", c.c.GenBashCompletionV2(os.Stdout, true))
|
||||||
} else {
|
} else {
|
||||||
c.getLog().CheckError(liblog.ErrorLevel, liblog.NilLevel, "generating bash completion", c.c.GenBashCompletionFileV2(file, true))
|
c.getLog().CheckError(loglvl.ErrorLevel, loglvl.NilLevel, "generating bash completion", c.c.GenBashCompletionFileV2(file, true))
|
||||||
}
|
}
|
||||||
case "fish":
|
case "fish":
|
||||||
if file == "" {
|
if file == "" {
|
||||||
c.getLog().CheckError(liblog.ErrorLevel, liblog.NilLevel, "generating bash completion", c.c.GenFishCompletion(os.Stdout, true))
|
c.getLog().CheckError(loglvl.ErrorLevel, loglvl.NilLevel, "generating bash completion", c.c.GenFishCompletion(os.Stdout, true))
|
||||||
} else {
|
} else {
|
||||||
c.getLog().CheckError(liblog.ErrorLevel, liblog.NilLevel, "generating bash completion", c.c.GenFishCompletionFile(file, true))
|
c.getLog().CheckError(loglvl.ErrorLevel, loglvl.NilLevel, "generating bash completion", c.c.GenFishCompletionFile(file, true))
|
||||||
}
|
}
|
||||||
case "powershell":
|
case "powershell":
|
||||||
if file == "" {
|
if file == "" {
|
||||||
c.getLog().CheckError(liblog.ErrorLevel, liblog.NilLevel, "generating bash completion", c.c.GenPowerShellCompletionWithDesc(os.Stdout))
|
c.getLog().CheckError(loglvl.ErrorLevel, loglvl.NilLevel, "generating bash completion", c.c.GenPowerShellCompletionWithDesc(os.Stdout))
|
||||||
} else {
|
} else {
|
||||||
c.getLog().CheckError(liblog.ErrorLevel, liblog.NilLevel, "generating bash completion", c.c.GenPowerShellCompletionFileWithDesc(file))
|
c.getLog().CheckError(loglvl.ErrorLevel, loglvl.NilLevel, "generating bash completion", c.c.GenPowerShellCompletionFileWithDesc(file))
|
||||||
}
|
}
|
||||||
case "zsh":
|
case "zsh":
|
||||||
if file == "" {
|
if file == "" {
|
||||||
c.getLog().CheckError(liblog.ErrorLevel, liblog.NilLevel, "generating bash completion", c.c.GenZshCompletion(os.Stdout))
|
c.getLog().CheckError(loglvl.ErrorLevel, loglvl.NilLevel, "generating bash completion", c.c.GenZshCompletion(os.Stdout))
|
||||||
} else {
|
} else {
|
||||||
c.getLog().CheckError(liblog.ErrorLevel, liblog.NilLevel, "generating bash completion", c.c.GenZshCompletionFile(file))
|
c.getLog().CheckError(loglvl.ErrorLevel, loglvl.NilLevel, "generating bash completion", c.c.GenZshCompletionFile(file))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/mitchellh/go-homedir"
|
"github.com/mitchellh/go-homedir"
|
||||||
liblog "github.com/nabbar/golib/logger"
|
loglvl "github.com/nabbar/golib/logger/level"
|
||||||
"github.com/pelletier/go-toml"
|
"github.com/pelletier/go-toml"
|
||||||
spfcbr "github.com/spf13/cobra"
|
spfcbr "github.com/spf13/cobra"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
@@ -49,7 +49,7 @@ func (c *cobra) getDefaultPath(baseName string) (string, error) {
|
|||||||
|
|
||||||
// Find home directory.
|
// Find home directory.
|
||||||
home, err := homedir.Dir()
|
home, err := homedir.Dir()
|
||||||
c.getLog().CheckError(liblog.WarnLevel, liblog.InfoLevel, "Loading home dir", err)
|
c.getLog().CheckError(loglvl.WarnLevel, loglvl.InfoLevel, "Loading home dir", err)
|
||||||
|
|
||||||
// set configname based on package name
|
// set configname based on package name
|
||||||
if baseName == "" {
|
if baseName == "" {
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
package cobra
|
package cobra
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
@@ -138,7 +139,7 @@ func (c *cobra) getLog() liblog.Logger {
|
|||||||
return l
|
return l
|
||||||
}
|
}
|
||||||
|
|
||||||
return liblog.GetDefault()
|
return liblog.New(context.Background)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *cobra) getPackageName() string {
|
func (c *cobra) getPackageName() string {
|
||||||
|
|||||||
@@ -226,11 +226,10 @@ func (o *componentAws) _runCli() liberr.Error {
|
|||||||
o.m.Unlock()
|
o.m.Unlock()
|
||||||
|
|
||||||
if req != nil {
|
if req != nil {
|
||||||
req.RegisterDefaultLogger(o.getLogger)
|
|
||||||
if req, e = opt.Update(o.x.GetContext, req); e != nil {
|
if req, e = opt.Update(o.x.GetContext, req); e != nil {
|
||||||
return prt.ErrorParent(e)
|
return prt.ErrorParent(e)
|
||||||
}
|
}
|
||||||
} else if req, e = libreq.New(o.x.GetContext, opt); e != nil {
|
} else if req, e = opt.New(o.x.GetContext); e != nil {
|
||||||
return prt.ErrorParent(e)
|
return prt.ErrorParent(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -113,6 +113,10 @@ func (o *componentAws) _registerMonitor(opt *libreq.OptionsHealth, aws libaws.Co
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if opt.Monitor.Name != key {
|
||||||
|
opt.Monitor.Name = key
|
||||||
|
}
|
||||||
|
|
||||||
if e = mon.SetConfig(o.x.GetContext, opt.Monitor); e != nil {
|
if e = mon.SetConfig(o.x.GetContext, opt.Monitor); e != nil {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -79,6 +79,10 @@ func (o *componentDatabase) _registerMonitor(cfg *libdbs.Config) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if cfg.Monitor.Name != key {
|
||||||
|
cfg.Monitor.Name = key
|
||||||
|
}
|
||||||
|
|
||||||
if e = mon.SetConfig(o.x.GetContext, cfg.Monitor); e != nil {
|
if e = mon.SetConfig(o.x.GetContext, cfg.Monitor); e != nil {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ import (
|
|||||||
cfgtps "github.com/nabbar/golib/config/types"
|
cfgtps "github.com/nabbar/golib/config/types"
|
||||||
liberr "github.com/nabbar/golib/errors"
|
liberr "github.com/nabbar/golib/errors"
|
||||||
liblog "github.com/nabbar/golib/logger"
|
liblog "github.com/nabbar/golib/logger"
|
||||||
|
logcfg "github.com/nabbar/golib/logger/config"
|
||||||
libver "github.com/nabbar/golib/version"
|
libver "github.com/nabbar/golib/version"
|
||||||
libvpr "github.com/nabbar/golib/viper"
|
libvpr "github.com/nabbar/golib/viper"
|
||||||
spfvbr "github.com/spf13/viper"
|
spfvbr "github.com/spf13/viper"
|
||||||
@@ -151,7 +152,7 @@ func (o *componentLog) _runCli() liberr.Error {
|
|||||||
e error
|
e error
|
||||||
err liberr.Error
|
err liberr.Error
|
||||||
prt = ErrorReloadLog
|
prt = ErrorReloadLog
|
||||||
cfg *liblog.Options
|
cfg *logcfg.Options
|
||||||
)
|
)
|
||||||
|
|
||||||
if !o.IsStarted() {
|
if !o.IsStarted() {
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ package log
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
liberr "github.com/nabbar/golib/errors"
|
liberr "github.com/nabbar/golib/errors"
|
||||||
liblog "github.com/nabbar/golib/logger"
|
logcfg "github.com/nabbar/golib/logger/config"
|
||||||
spfcbr "github.com/spf13/cobra"
|
spfcbr "github.com/spf13/cobra"
|
||||||
spfvpr "github.com/spf13/viper"
|
spfvpr "github.com/spf13/viper"
|
||||||
)
|
)
|
||||||
@@ -70,10 +70,10 @@ func (o *componentLog) RegisterFlag(Command *spfcbr.Command) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *componentLog) _getConfig() (*liblog.Options, liberr.Error) {
|
func (o *componentLog) _getConfig() (*logcfg.Options, liberr.Error) {
|
||||||
var (
|
var (
|
||||||
key string
|
key string
|
||||||
cfg liblog.Options
|
cfg logcfg.Options
|
||||||
vpr *spfvpr.Viper
|
vpr *spfvpr.Viper
|
||||||
err liberr.Error
|
err liberr.Error
|
||||||
)
|
)
|
||||||
@@ -88,20 +88,24 @@ func (o *componentLog) _getConfig() (*liblog.Options, liberr.Error) {
|
|||||||
return nil, ErrorParamInvalid.ErrorParent(e)
|
return nil, ErrorParamInvalid.ErrorParent(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if cfg.Stdout == nil {
|
||||||
|
cfg.Stdout = &logcfg.OptionsStd{}
|
||||||
|
}
|
||||||
|
|
||||||
if val := vpr.GetBool(key + "disableStandard"); val {
|
if val := vpr.GetBool(key + "disableStandard"); val {
|
||||||
cfg.DisableStandard = true
|
cfg.Stdout.DisableStandard = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if val := vpr.GetBool(key + "disableStack"); val {
|
if val := vpr.GetBool(key + "disableStack"); val {
|
||||||
cfg.DisableStack = true
|
cfg.Stdout.DisableStack = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if val := vpr.GetBool(key + "disableTimestamp"); val {
|
if val := vpr.GetBool(key + "disableTimestamp"); val {
|
||||||
cfg.DisableTimestamp = true
|
cfg.Stdout.DisableTimestamp = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if val := vpr.GetBool(key + "enableTrace"); val {
|
if val := vpr.GetBool(key + "enableTrace"); val {
|
||||||
cfg.EnableTrace = true
|
cfg.Stdout.EnableTrace = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if val := vpr.GetString(key + "traceFilter"); val != "" {
|
if val := vpr.GetString(key + "traceFilter"); val != "" {
|
||||||
@@ -109,7 +113,7 @@ func (o *componentLog) _getConfig() (*liblog.Options, liberr.Error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if val := vpr.GetBool(key + "disableColor"); val {
|
if val := vpr.GetBool(key + "disableColor"); val {
|
||||||
cfg.DisableColor = true
|
cfg.Stdout.DisableColor = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = cfg.Validate(); err != nil {
|
if err = cfg.Validate(); err != nil {
|
||||||
|
|||||||
@@ -27,9 +27,9 @@
|
|||||||
package log
|
package log
|
||||||
|
|
||||||
import (
|
import (
|
||||||
logdef "github.com/nabbar/golib/logger/config"
|
logcfg "github.com/nabbar/golib/logger/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (o *componentLog) DefaultConfig(indent string) []byte {
|
func (o *componentLog) DefaultConfig(indent string) []byte {
|
||||||
return logdef.DefaultConfig(indent)
|
return logcfg.DefaultConfig(indent)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,10 +34,13 @@ import (
|
|||||||
libctx "github.com/nabbar/golib/context"
|
libctx "github.com/nabbar/golib/context"
|
||||||
liberr "github.com/nabbar/golib/errors"
|
liberr "github.com/nabbar/golib/errors"
|
||||||
liblog "github.com/nabbar/golib/logger"
|
liblog "github.com/nabbar/golib/logger"
|
||||||
|
logcfg "github.com/nabbar/golib/logger/config"
|
||||||
|
logfld "github.com/nabbar/golib/logger/fields"
|
||||||
|
loglvl "github.com/nabbar/golib/logger/level"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
DefaultLevel = liblog.InfoLevel
|
DefaultLevel = loglvl.InfoLevel
|
||||||
)
|
)
|
||||||
|
|
||||||
type ComponentLog interface {
|
type ComponentLog interface {
|
||||||
@@ -45,17 +48,17 @@ type ComponentLog interface {
|
|||||||
|
|
||||||
Log() liblog.Logger
|
Log() liblog.Logger
|
||||||
|
|
||||||
SetLevel(lvl liblog.Level)
|
SetLevel(lvl loglvl.Level)
|
||||||
GetLevel() liblog.Level
|
GetLevel() loglvl.Level
|
||||||
|
|
||||||
SetField(fields liblog.Fields)
|
SetField(fields logfld.Fields)
|
||||||
GetField() liblog.Fields
|
GetField() logfld.Fields
|
||||||
|
|
||||||
SetOptions(opt *liblog.Options) liberr.Error
|
SetOptions(opt *logcfg.Options) liberr.Error
|
||||||
GetOptions() *liblog.Options
|
GetOptions() *logcfg.Options
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(ctx libctx.FuncContext, lvl liblog.Level) ComponentLog {
|
func New(ctx libctx.FuncContext, lvl loglvl.Level) ComponentLog {
|
||||||
return &componentLog{
|
return &componentLog{
|
||||||
m: sync.RWMutex{},
|
m: sync.RWMutex{},
|
||||||
x: libctx.NewConfig[uint8](ctx),
|
x: libctx.NewConfig[uint8](ctx),
|
||||||
@@ -68,7 +71,7 @@ func Register(cfg libcfg.Config, key string, cpt ComponentLog) {
|
|||||||
cfg.ComponentSet(key, cpt)
|
cfg.ComponentSet(key, cpt)
|
||||||
}
|
}
|
||||||
|
|
||||||
func RegisterNew(ctx libctx.FuncContext, cfg libcfg.Config, key string, lvl liblog.Level) {
|
func RegisterNew(ctx libctx.FuncContext, cfg libcfg.Config, key string, lvl loglvl.Level) {
|
||||||
cfg.ComponentSet(key, New(ctx, lvl))
|
cfg.ComponentSet(key, New(ctx, lvl))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,6 +32,9 @@ import (
|
|||||||
libctx "github.com/nabbar/golib/context"
|
libctx "github.com/nabbar/golib/context"
|
||||||
liberr "github.com/nabbar/golib/errors"
|
liberr "github.com/nabbar/golib/errors"
|
||||||
liblog "github.com/nabbar/golib/logger"
|
liblog "github.com/nabbar/golib/logger"
|
||||||
|
logcfg "github.com/nabbar/golib/logger/config"
|
||||||
|
logfld "github.com/nabbar/golib/logger/fields"
|
||||||
|
loglvl "github.com/nabbar/golib/logger/level"
|
||||||
)
|
)
|
||||||
|
|
||||||
type componentLog struct {
|
type componentLog struct {
|
||||||
@@ -39,7 +42,7 @@ type componentLog struct {
|
|||||||
x libctx.Config[uint8]
|
x libctx.Config[uint8]
|
||||||
|
|
||||||
l liblog.Logger
|
l liblog.Logger
|
||||||
v liblog.Level
|
v loglvl.Level
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *componentLog) Log() liblog.Logger {
|
func (o *componentLog) Log() liblog.Logger {
|
||||||
@@ -53,7 +56,7 @@ func (o *componentLog) Log() liblog.Logger {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *componentLog) SetLevel(lvl liblog.Level) {
|
func (o *componentLog) SetLevel(lvl loglvl.Level) {
|
||||||
o.m.Lock()
|
o.m.Lock()
|
||||||
defer o.m.Unlock()
|
defer o.m.Unlock()
|
||||||
|
|
||||||
@@ -66,14 +69,14 @@ func (o *componentLog) SetLevel(lvl liblog.Level) {
|
|||||||
o.l.SetLevel(lvl)
|
o.l.SetLevel(lvl)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *componentLog) GetLevel() liblog.Level {
|
func (o *componentLog) GetLevel() loglvl.Level {
|
||||||
o.m.RLock()
|
o.m.RLock()
|
||||||
defer o.m.RUnlock()
|
defer o.m.RUnlock()
|
||||||
|
|
||||||
return o.v
|
return o.v
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *componentLog) SetField(fields liblog.Fields) {
|
func (o *componentLog) SetField(fields logfld.Fields) {
|
||||||
o.m.Lock()
|
o.m.Lock()
|
||||||
defer o.m.Unlock()
|
defer o.m.Unlock()
|
||||||
|
|
||||||
@@ -84,7 +87,7 @@ func (o *componentLog) SetField(fields liblog.Fields) {
|
|||||||
o.l.SetFields(fields)
|
o.l.SetFields(fields)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *componentLog) GetField() liblog.Fields {
|
func (o *componentLog) GetField() logfld.Fields {
|
||||||
o.m.RLock()
|
o.m.RLock()
|
||||||
defer o.m.RUnlock()
|
defer o.m.RUnlock()
|
||||||
|
|
||||||
@@ -95,7 +98,7 @@ func (o *componentLog) GetField() liblog.Fields {
|
|||||||
return o.l.GetFields()
|
return o.l.GetFields()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *componentLog) GetOptions() *liblog.Options {
|
func (o *componentLog) GetOptions() *logcfg.Options {
|
||||||
o.m.RLock()
|
o.m.RLock()
|
||||||
defer o.m.RUnlock()
|
defer o.m.RUnlock()
|
||||||
|
|
||||||
@@ -106,7 +109,7 @@ func (o *componentLog) GetOptions() *liblog.Options {
|
|||||||
return o.l.GetOptions()
|
return o.l.GetOptions()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *componentLog) SetOptions(opt *liblog.Options) liberr.Error {
|
func (o *componentLog) SetOptions(opt *logcfg.Options) liberr.Error {
|
||||||
o.m.Lock()
|
o.m.Lock()
|
||||||
defer o.m.Unlock()
|
defer o.m.Unlock()
|
||||||
|
|
||||||
|
|||||||
@@ -197,7 +197,6 @@ func (o *componentRequest) _runCli() liberr.Error {
|
|||||||
cfg.SetDefaultLog(o.getLogger)
|
cfg.SetDefaultLog(o.getLogger)
|
||||||
|
|
||||||
if req != nil {
|
if req != nil {
|
||||||
req.RegisterDefaultLogger(o.getLogger)
|
|
||||||
if req, e = cfg.Update(o.x.GetContext, req); err != nil {
|
if req, e = cfg.Update(o.x.GetContext, req); err != nil {
|
||||||
return prt.ErrorParent(e)
|
return prt.ErrorParent(e)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -89,6 +89,10 @@ func (o *componentRequest) _registerMonitor(cfg *libreq.Options) error {
|
|||||||
|
|
||||||
mon.RegisterLoggerDefault(o.getLogger)
|
mon.RegisterLoggerDefault(o.getLogger)
|
||||||
|
|
||||||
|
if cfg.Health.Monitor.Name != key {
|
||||||
|
cfg.Health.Monitor.Name = key
|
||||||
|
}
|
||||||
|
|
||||||
if e = mon.SetConfig(o.x.GetContext, cfg.Health.Monitor); e != nil {
|
if e = mon.SetConfig(o.x.GetContext, cfg.Health.Monitor); e != nil {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -85,6 +85,10 @@ func (o *componentSmtp) _registerMonitor(cfg *montps.Config) error {
|
|||||||
|
|
||||||
mon.RegisterLoggerDefault(o.getLogger)
|
mon.RegisterLoggerDefault(o.getLogger)
|
||||||
|
|
||||||
|
if cfg.Name != key {
|
||||||
|
cfg.Name = key
|
||||||
|
}
|
||||||
|
|
||||||
if e = mon.SetConfig(o.x.GetContext, *cfg); e != nil {
|
if e = mon.SetConfig(o.x.GetContext, *cfg); e != nil {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,6 +30,8 @@ import (
|
|||||||
"os/signal"
|
"os/signal"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/nabbar/golib/logger/level"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
liblog "github.com/nabbar/golib/logger"
|
liblog "github.com/nabbar/golib/logger"
|
||||||
)
|
)
|
||||||
@@ -41,7 +43,7 @@ type ctxGinTonic struct {
|
|||||||
c context.CancelFunc
|
c context.CancelFunc
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewGinTonic(c *gin.Context) GinTonic {
|
func NewGinTonic(c *gin.Context, log liblog.FuncLog) GinTonic {
|
||||||
if c == nil {
|
if c == nil {
|
||||||
c = &gin.Context{
|
c = &gin.Context{
|
||||||
Request: nil,
|
Request: nil,
|
||||||
@@ -65,7 +67,7 @@ func NewGinTonic(c *gin.Context) GinTonic {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return &ctxGinTonic{
|
return &ctxGinTonic{
|
||||||
l: liblog.GetDefault,
|
l: log,
|
||||||
g: c,
|
g: c,
|
||||||
x: x,
|
x: x,
|
||||||
c: l,
|
c: l,
|
||||||
@@ -76,11 +78,15 @@ func (c *ctxGinTonic) SetLogger(fct liblog.FuncLog) {
|
|||||||
c.l = fct
|
c.l = fct
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ctxGinTonic) log(lvl liblog.Level, msg string, args ...interface{}) {
|
func (c *ctxGinTonic) log(lvl level.Level, msg string, args ...interface{}) {
|
||||||
if c.l != nil {
|
if c.l != nil {
|
||||||
c.l().Entry(lvl, msg, args...).Log()
|
c.l().Entry(lvl, msg, args...).Log()
|
||||||
} else {
|
} else {
|
||||||
liblog.GetDefault().Entry(lvl, msg, args...).Log()
|
l := liblog.New(func() context.Context {
|
||||||
|
return c
|
||||||
|
})
|
||||||
|
|
||||||
|
l.Entry(lvl, msg, args...).Log()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -91,11 +97,11 @@ func (c *ctxGinTonic) CancelOnSignal(s ...os.Signal) {
|
|||||||
|
|
||||||
select {
|
select {
|
||||||
case <-sc:
|
case <-sc:
|
||||||
c.log(liblog.InfoLevel, "OS Signal received, calling context cancel !")
|
c.log(level.InfoLevel, "OS Signal received, calling context cancel !")
|
||||||
c.c()
|
c.c()
|
||||||
return
|
return
|
||||||
case <-c.Done():
|
case <-c.Done():
|
||||||
c.log(liblog.InfoLevel, "Context has been closed !")
|
c.log(level.InfoLevel, "Context has been closed !")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|||||||
@@ -31,12 +31,12 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
moncfg "github.com/nabbar/golib/monitor/types"
|
|
||||||
|
|
||||||
libval "github.com/go-playground/validator/v10"
|
libval "github.com/go-playground/validator/v10"
|
||||||
libctx "github.com/nabbar/golib/context"
|
libctx "github.com/nabbar/golib/context"
|
||||||
liberr "github.com/nabbar/golib/errors"
|
liberr "github.com/nabbar/golib/errors"
|
||||||
liblog "github.com/nabbar/golib/logger"
|
liblog "github.com/nabbar/golib/logger"
|
||||||
|
loggrm "github.com/nabbar/golib/logger/gorm"
|
||||||
|
moncfg "github.com/nabbar/golib/monitor/types"
|
||||||
gormdb "gorm.io/gorm"
|
gormdb "gorm.io/gorm"
|
||||||
gorcls "gorm.io/gorm/clause"
|
gorcls "gorm.io/gorm/clause"
|
||||||
gorlog "gorm.io/gorm/logger"
|
gorlog "gorm.io/gorm/logger"
|
||||||
@@ -131,7 +131,7 @@ func (c *Config) Validate() liberr.Error {
|
|||||||
|
|
||||||
func (c *Config) RegisterLogger(fct func() liblog.Logger, ignoreRecordNotFoundError bool, slowThreshold time.Duration) {
|
func (c *Config) RegisterLogger(fct func() liblog.Logger, ignoreRecordNotFoundError bool, slowThreshold time.Duration) {
|
||||||
c.flog = func() gorlog.Interface {
|
c.flog = func() gorlog.Interface {
|
||||||
return liblog.NewGormLogger(fct, ignoreRecordNotFoundError, slowThreshold)
|
return loggrm.New(fct, ignoreRecordNotFoundError, slowThreshold)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
100
go.mod
100
go.mod
@@ -3,67 +3,67 @@ module github.com/nabbar/golib
|
|||||||
go 1.20
|
go 1.20
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/aws/aws-sdk-go-v2 v1.18.0
|
github.com/aws/aws-sdk-go-v2 v1.18.1
|
||||||
github.com/aws/aws-sdk-go-v2/config v1.18.25
|
github.com/aws/aws-sdk-go-v2/config v1.18.27
|
||||||
github.com/aws/aws-sdk-go-v2/credentials v1.13.24
|
github.com/aws/aws-sdk-go-v2/credentials v1.13.26
|
||||||
github.com/aws/aws-sdk-go-v2/service/iam v1.19.12
|
github.com/aws/aws-sdk-go-v2/service/iam v1.20.3
|
||||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.33.1
|
github.com/aws/aws-sdk-go-v2/service/s3 v1.35.0
|
||||||
github.com/bits-and-blooms/bitset v1.7.0
|
github.com/bits-and-blooms/bitset v1.8.0
|
||||||
github.com/c-bata/go-prompt v0.2.6
|
github.com/c-bata/go-prompt v0.2.6
|
||||||
github.com/fatih/color v1.15.0
|
github.com/fatih/color v1.15.0
|
||||||
github.com/fsnotify/fsnotify v1.6.0
|
github.com/fsnotify/fsnotify v1.6.0
|
||||||
github.com/fxamacker/cbor/v2 v2.4.0
|
github.com/fxamacker/cbor/v2 v2.4.0
|
||||||
github.com/gin-gonic/gin v1.9.1
|
github.com/gin-gonic/gin v1.9.1
|
||||||
github.com/go-ldap/ldap/v3 v3.4.4
|
github.com/go-ldap/ldap/v3 v3.4.5
|
||||||
github.com/go-playground/validator/v10 v10.14.0
|
github.com/go-playground/validator/v10 v10.14.1
|
||||||
github.com/google/go-github/v33 v33.0.0
|
github.com/google/go-github/v33 v33.0.0
|
||||||
github.com/hashicorp/go-hclog v1.5.0
|
github.com/hashicorp/go-hclog v1.5.0
|
||||||
github.com/hashicorp/go-retryablehttp v0.7.2
|
github.com/hashicorp/go-retryablehttp v0.7.4
|
||||||
github.com/hashicorp/go-uuid v1.0.3
|
github.com/hashicorp/go-uuid v1.0.3
|
||||||
github.com/hashicorp/go-version v1.6.0
|
github.com/hashicorp/go-version v1.6.0
|
||||||
github.com/jlaffaye/ftp v0.2.0
|
github.com/jlaffaye/ftp v0.2.0
|
||||||
github.com/lni/dragonboat/v3 v3.3.6
|
github.com/lni/dragonboat/v3 v3.3.7
|
||||||
github.com/matcornic/hermes/v2 v2.1.0
|
github.com/matcornic/hermes/v2 v2.1.0
|
||||||
github.com/mattn/go-colorable v0.1.13
|
github.com/mattn/go-colorable v0.1.13
|
||||||
github.com/mitchellh/go-homedir v1.1.0
|
github.com/mitchellh/go-homedir v1.1.0
|
||||||
github.com/mitchellh/mapstructure v1.5.0
|
github.com/mitchellh/mapstructure v1.5.0
|
||||||
github.com/nats-io/jwt/v2 v2.4.1
|
github.com/nats-io/jwt/v2 v2.4.1
|
||||||
github.com/nats-io/nats-server/v2 v2.9.17
|
github.com/nats-io/nats-server/v2 v2.9.18
|
||||||
github.com/nats-io/nats.go v1.26.0
|
github.com/nats-io/nats.go v1.27.0
|
||||||
github.com/nutsdb/nutsdb v0.12.2
|
github.com/nutsdb/nutsdb v0.12.2
|
||||||
github.com/onsi/ginkgo/v2 v2.9.7
|
github.com/onsi/ginkgo/v2 v2.11.0
|
||||||
github.com/onsi/gomega v1.27.7
|
github.com/onsi/gomega v1.27.8
|
||||||
github.com/pelletier/go-toml v1.9.5
|
github.com/pelletier/go-toml v1.9.5
|
||||||
github.com/prometheus/client_golang v1.15.1
|
github.com/prometheus/client_golang v1.16.0
|
||||||
github.com/shirou/gopsutil v3.21.11+incompatible
|
github.com/shirou/gopsutil v3.21.11+incompatible
|
||||||
github.com/sirupsen/logrus v1.9.2
|
github.com/sirupsen/logrus v1.9.3
|
||||||
github.com/spf13/cobra v1.7.0
|
github.com/spf13/cobra v1.7.0
|
||||||
github.com/spf13/jwalterweatherman v1.1.0
|
github.com/spf13/jwalterweatherman v1.1.0
|
||||||
github.com/spf13/viper v1.16.0
|
github.com/spf13/viper v1.16.0
|
||||||
github.com/ugorji/go/codec v1.2.11
|
github.com/ugorji/go/codec v1.2.11
|
||||||
github.com/vbauerster/mpb/v5 v5.4.0
|
github.com/vbauerster/mpb/v5 v5.4.0
|
||||||
github.com/xanzy/go-gitlab v0.84.0
|
github.com/xanzy/go-gitlab v0.85.0
|
||||||
github.com/xhit/go-simple-mail v2.2.2+incompatible
|
github.com/xhit/go-simple-mail v2.2.2+incompatible
|
||||||
github.com/xujiajun/utils v0.0.0-20220904132955-5f7c5b914235
|
github.com/xujiajun/utils v0.0.0-20220904132955-5f7c5b914235
|
||||||
golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1
|
golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1
|
||||||
golang.org/x/net v0.10.0
|
golang.org/x/net v0.11.0
|
||||||
golang.org/x/oauth2 v0.8.0
|
golang.org/x/oauth2 v0.9.0
|
||||||
golang.org/x/sync v0.2.0
|
golang.org/x/sync v0.3.0
|
||||||
golang.org/x/sys v0.8.0
|
golang.org/x/sys v0.9.0
|
||||||
golang.org/x/term v0.8.0
|
golang.org/x/term v0.9.0
|
||||||
gopkg.in/yaml.v3 v3.0.1
|
gopkg.in/yaml.v3 v3.0.1
|
||||||
gorm.io/driver/clickhouse v0.5.1
|
gorm.io/driver/clickhouse v0.5.1
|
||||||
gorm.io/driver/mysql v1.5.1
|
gorm.io/driver/mysql v1.5.1
|
||||||
gorm.io/driver/postgres v1.5.2
|
gorm.io/driver/postgres v1.5.2
|
||||||
gorm.io/driver/sqlite v1.5.1
|
gorm.io/driver/sqlite v1.5.1
|
||||||
gorm.io/driver/sqlserver v1.5.0
|
gorm.io/driver/sqlserver v1.5.1
|
||||||
gorm.io/gorm v1.25.1
|
gorm.io/gorm v1.25.1
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 // indirect
|
github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 // indirect
|
||||||
github.com/ClickHouse/ch-go v0.56.0 // indirect
|
github.com/ClickHouse/ch-go v0.56.1 // indirect
|
||||||
github.com/ClickHouse/clickhouse-go/v2 v2.10.0 // indirect
|
github.com/ClickHouse/clickhouse-go/v2 v2.10.1 // indirect
|
||||||
github.com/Masterminds/goutils v1.1.1 // indirect
|
github.com/Masterminds/goutils v1.1.1 // indirect
|
||||||
github.com/Masterminds/semver v1.5.0 // indirect
|
github.com/Masterminds/semver v1.5.0 // indirect
|
||||||
github.com/Masterminds/sprig v2.22.0+incompatible // indirect
|
github.com/Masterminds/sprig v2.22.0+incompatible // indirect
|
||||||
@@ -75,30 +75,30 @@ require (
|
|||||||
github.com/andybalholm/cascadia v1.3.2 // indirect
|
github.com/andybalholm/cascadia v1.3.2 // indirect
|
||||||
github.com/armon/go-metrics v0.4.1 // indirect
|
github.com/armon/go-metrics v0.4.1 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.10 // indirect
|
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.10 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.3 // indirect
|
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.4 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.33 // indirect
|
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.34 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.27 // indirect
|
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.28 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.34 // indirect
|
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.35 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.25 // indirect
|
github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.26 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.11 // indirect
|
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.11 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.28 // indirect
|
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.29 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.27 // indirect
|
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.28 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.14.2 // indirect
|
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.14.3 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/service/sso v1.12.10 // indirect
|
github.com/aws/aws-sdk-go-v2/service/sso v1.12.12 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.14.10 // indirect
|
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.14.12 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/service/sts v1.19.0 // indirect
|
github.com/aws/aws-sdk-go-v2/service/sts v1.19.2 // indirect
|
||||||
github.com/aws/smithy-go v1.13.5 // indirect
|
github.com/aws/smithy-go v1.13.5 // indirect
|
||||||
github.com/beorn7/perks v1.0.1 // indirect
|
github.com/beorn7/perks v1.0.1 // indirect
|
||||||
github.com/bwmarrin/snowflake v0.3.0 // indirect
|
github.com/bwmarrin/snowflake v0.3.0 // indirect
|
||||||
github.com/bytedance/sonic v1.9.1 // indirect
|
github.com/bytedance/sonic v1.9.1 // indirect
|
||||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||||
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
|
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
|
||||||
github.com/cockroachdb/errors v1.9.1 // indirect
|
github.com/cockroachdb/errors v1.10.0 // indirect
|
||||||
github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect
|
github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect
|
||||||
github.com/cockroachdb/pebble v0.0.0-20210331181633-27fc006b8bfb // indirect
|
github.com/cockroachdb/pebble v0.0.0-20210331181633-27fc006b8bfb // indirect
|
||||||
github.com/cockroachdb/redact v1.1.4 // indirect
|
github.com/cockroachdb/redact v1.1.5 // indirect
|
||||||
github.com/gabriel-vasile/mimetype v1.4.2 // indirect
|
github.com/gabriel-vasile/mimetype v1.4.2 // indirect
|
||||||
github.com/getsentry/sentry-go v0.21.0 // indirect
|
github.com/getsentry/sentry-go v0.22.0 // indirect
|
||||||
github.com/gin-contrib/sse v0.1.0 // indirect
|
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||||
github.com/go-asn1-ber/asn1-ber v1.5.4 // indirect
|
github.com/go-asn1-ber/asn1-ber v1.5.4 // indirect
|
||||||
github.com/go-faster/city v1.0.1 // indirect
|
github.com/go-faster/city v1.0.1 // indirect
|
||||||
@@ -118,7 +118,7 @@ require (
|
|||||||
github.com/google/btree v1.1.2 // indirect
|
github.com/google/btree v1.1.2 // indirect
|
||||||
github.com/google/go-cmp v0.5.9 // indirect
|
github.com/google/go-cmp v0.5.9 // indirect
|
||||||
github.com/google/go-querystring v1.1.0 // indirect
|
github.com/google/go-querystring v1.1.0 // indirect
|
||||||
github.com/google/pprof v0.0.0-20230602010524-ada837c32108 // indirect
|
github.com/google/pprof v0.0.0-20230602150820-91b7bce49751 // indirect
|
||||||
github.com/google/uuid v1.3.0 // indirect
|
github.com/google/uuid v1.3.0 // indirect
|
||||||
github.com/gorilla/css v1.0.0 // indirect
|
github.com/gorilla/css v1.0.0 // indirect
|
||||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||||
@@ -135,14 +135,14 @@ require (
|
|||||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||||
github.com/jackc/pgpassfile v1.0.0 // indirect
|
github.com/jackc/pgpassfile v1.0.0 // indirect
|
||||||
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect
|
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect
|
||||||
github.com/jackc/pgx/v5 v5.3.1 // indirect
|
github.com/jackc/pgx/v5 v5.4.1 // indirect
|
||||||
github.com/jaytaylor/html2text v0.0.0-20230321000545-74c2419ad056 // indirect
|
github.com/jaytaylor/html2text v0.0.0-20230321000545-74c2419ad056 // indirect
|
||||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||||
github.com/jinzhu/now v1.1.5 // indirect
|
github.com/jinzhu/now v1.1.5 // indirect
|
||||||
github.com/json-iterator/go v1.1.12 // indirect
|
github.com/json-iterator/go v1.1.12 // indirect
|
||||||
github.com/juju/ratelimit v1.0.2 // indirect
|
github.com/juju/ratelimit v1.0.2 // indirect
|
||||||
github.com/klauspost/compress v1.16.5 // indirect
|
github.com/klauspost/compress v1.16.6 // indirect
|
||||||
github.com/klauspost/cpuid/v2 v2.2.4 // indirect
|
github.com/klauspost/cpuid/v2 v2.2.5 // indirect
|
||||||
github.com/kr/pretty v0.3.1 // indirect
|
github.com/kr/pretty v0.3.1 // indirect
|
||||||
github.com/kr/text v0.2.0 // indirect
|
github.com/kr/text v0.2.0 // indirect
|
||||||
github.com/leodido/go-urn v1.2.4 // indirect
|
github.com/leodido/go-urn v1.2.4 // indirect
|
||||||
@@ -154,7 +154,7 @@ require (
|
|||||||
github.com/mattn/go-tty v0.0.5 // indirect
|
github.com/mattn/go-tty v0.0.5 // indirect
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
|
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
|
||||||
github.com/microsoft/go-mssqldb v1.1.0 // indirect
|
github.com/microsoft/go-mssqldb v1.1.0 // indirect
|
||||||
github.com/miekg/dns v1.1.54 // indirect
|
github.com/miekg/dns v1.1.55 // indirect
|
||||||
github.com/minio/highwayhash v1.0.2 // indirect
|
github.com/minio/highwayhash v1.0.2 // indirect
|
||||||
github.com/mitchellh/copystructure v1.2.0 // indirect
|
github.com/mitchellh/copystructure v1.2.0 // indirect
|
||||||
github.com/mitchellh/reflectwalk v1.0.2 // indirect
|
github.com/mitchellh/reflectwalk v1.0.2 // indirect
|
||||||
@@ -165,12 +165,12 @@ require (
|
|||||||
github.com/olekukonko/tablewriter v0.0.5 // indirect
|
github.com/olekukonko/tablewriter v0.0.5 // indirect
|
||||||
github.com/paulmach/orb v0.9.2 // indirect
|
github.com/paulmach/orb v0.9.2 // indirect
|
||||||
github.com/pelletier/go-toml/v2 v2.0.8 // indirect
|
github.com/pelletier/go-toml/v2 v2.0.8 // indirect
|
||||||
github.com/pierrec/lz4/v4 v4.1.17 // indirect
|
github.com/pierrec/lz4/v4 v4.1.18 // indirect
|
||||||
github.com/pkg/errors v0.9.1 // indirect
|
github.com/pkg/errors v0.9.1 // indirect
|
||||||
github.com/pkg/term v1.2.0-beta.2 // indirect
|
github.com/pkg/term v1.2.0-beta.2 // indirect
|
||||||
github.com/prometheus/client_model v0.4.0 // indirect
|
github.com/prometheus/client_model v0.4.0 // indirect
|
||||||
github.com/prometheus/common v0.44.0 // indirect
|
github.com/prometheus/common v0.44.0 // indirect
|
||||||
github.com/prometheus/procfs v0.10.1 // indirect
|
github.com/prometheus/procfs v0.11.0 // indirect
|
||||||
github.com/rivo/uniseg v0.4.4 // indirect
|
github.com/rivo/uniseg v0.4.4 // indirect
|
||||||
github.com/rogpeppe/go-internal v1.10.0 // indirect
|
github.com/rogpeppe/go-internal v1.10.0 // indirect
|
||||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||||
@@ -193,11 +193,11 @@ require (
|
|||||||
go.opentelemetry.io/otel v1.16.0 // indirect
|
go.opentelemetry.io/otel v1.16.0 // indirect
|
||||||
go.opentelemetry.io/otel/trace v1.16.0 // indirect
|
go.opentelemetry.io/otel/trace v1.16.0 // indirect
|
||||||
golang.org/x/arch v0.3.0 // indirect
|
golang.org/x/arch v0.3.0 // indirect
|
||||||
golang.org/x/crypto v0.9.0 // indirect
|
golang.org/x/crypto v0.10.0 // indirect
|
||||||
golang.org/x/mod v0.10.0 // indirect
|
golang.org/x/mod v0.11.0 // indirect
|
||||||
golang.org/x/text v0.9.0 // indirect
|
golang.org/x/text v0.10.0 // indirect
|
||||||
golang.org/x/time v0.3.0 // indirect
|
golang.org/x/time v0.3.0 // indirect
|
||||||
golang.org/x/tools v0.9.3 // indirect
|
golang.org/x/tools v0.10.0 // indirect
|
||||||
google.golang.org/appengine v1.6.7 // indirect
|
google.golang.org/appengine v1.6.7 // indirect
|
||||||
google.golang.org/protobuf v1.30.0 // indirect
|
google.golang.org/protobuf v1.30.0 // indirect
|
||||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||||
|
|||||||
@@ -33,6 +33,8 @@ import (
|
|||||||
"net/url"
|
"net/url"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
libptc "github.com/nabbar/golib/network/protocol"
|
||||||
|
|
||||||
"golang.org/x/net/http2"
|
"golang.org/x/net/http2"
|
||||||
|
|
||||||
libtls "github.com/nabbar/golib/certificates"
|
libtls "github.com/nabbar/golib/certificates"
|
||||||
@@ -97,7 +99,7 @@ func GetClientTls(serverName string, tls libtls.TLSConfig, http2Tr bool, GlobalT
|
|||||||
return getclient(tr, http2Tr, GlobalTimeout)
|
return getclient(tr, http2Tr, GlobalTimeout)
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetClientTlsForceIp(netw Network, ip string, serverName string, tls libtls.TLSConfig, http2Tr bool, GlobalTimeout time.Duration) (*http.Client, liberr.Error) {
|
func GetClientTlsForceIp(netw libptc.NetworkProtocol, ip string, serverName string, tls libtls.TLSConfig, http2Tr bool, GlobalTimeout time.Duration) (*http.Client, liberr.Error) {
|
||||||
u := &url.URL{
|
u := &url.URL{
|
||||||
Host: ip,
|
Host: ip,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,63 +0,0 @@
|
|||||||
/*
|
|
||||||
* MIT License
|
|
||||||
*
|
|
||||||
* Copyright (c) 2020 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 httpcli
|
|
||||||
|
|
||||||
import "strings"
|
|
||||||
|
|
||||||
type Network uint8
|
|
||||||
|
|
||||||
const (
|
|
||||||
NetworkTCP Network = iota
|
|
||||||
NetworkUDP
|
|
||||||
NetworkUnix
|
|
||||||
)
|
|
||||||
|
|
||||||
func GetNetworkFromString(str string) Network {
|
|
||||||
switch {
|
|
||||||
case strings.EqualFold(NetworkUDP.Code(), str):
|
|
||||||
return NetworkUDP
|
|
||||||
case strings.EqualFold(NetworkUnix.Code(), str):
|
|
||||||
return NetworkUnix
|
|
||||||
default:
|
|
||||||
return NetworkTCP
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n Network) String() string {
|
|
||||||
switch n {
|
|
||||||
case NetworkUDP:
|
|
||||||
return "UDP"
|
|
||||||
case NetworkUnix:
|
|
||||||
return "unix"
|
|
||||||
default:
|
|
||||||
return "TCP"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n Network) Code() string {
|
|
||||||
return strings.ToLower(n.String())
|
|
||||||
}
|
|
||||||
@@ -33,6 +33,8 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
libptc "github.com/nabbar/golib/network/protocol"
|
||||||
|
|
||||||
cmptls "github.com/nabbar/golib/config/components/tls"
|
cmptls "github.com/nabbar/golib/config/components/tls"
|
||||||
cfgcst "github.com/nabbar/golib/config/const"
|
cfgcst "github.com/nabbar/golib/config/const"
|
||||||
|
|
||||||
@@ -112,7 +114,7 @@ func (o Options) GetClient(def libtls.TLSConfig, servername string) (*http.Clien
|
|||||||
}
|
}
|
||||||
|
|
||||||
if o.ForceIP.Enable {
|
if o.ForceIP.Enable {
|
||||||
return GetClientTlsForceIp(GetNetworkFromString(o.ForceIP.Net), o.ForceIP.IP, servername, tls, o.Http2, o.Timeout)
|
return GetClientTlsForceIp(libptc.Parse(o.ForceIP.Net), o.ForceIP.IP, servername, tls, o.Http2, o.Timeout)
|
||||||
} else {
|
} else {
|
||||||
return GetClientTls(servername, tls, o.Http2, o.Timeout)
|
return GetClientTls(servername, tls, o.Http2, o.Timeout)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,15 +34,14 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
srvtps "github.com/nabbar/golib/httpserver/types"
|
|
||||||
|
|
||||||
moncfg "github.com/nabbar/golib/monitor/types"
|
|
||||||
|
|
||||||
libval "github.com/go-playground/validator/v10"
|
libval "github.com/go-playground/validator/v10"
|
||||||
libtls "github.com/nabbar/golib/certificates"
|
libtls "github.com/nabbar/golib/certificates"
|
||||||
libctx "github.com/nabbar/golib/context"
|
libctx "github.com/nabbar/golib/context"
|
||||||
liberr "github.com/nabbar/golib/errors"
|
liberr "github.com/nabbar/golib/errors"
|
||||||
|
srvtps "github.com/nabbar/golib/httpserver/types"
|
||||||
liblog "github.com/nabbar/golib/logger"
|
liblog "github.com/nabbar/golib/logger"
|
||||||
|
logcfg "github.com/nabbar/golib/logger/config"
|
||||||
|
moncfg "github.com/nabbar/golib/monitor/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -183,7 +182,7 @@ type Config struct {
|
|||||||
DisableKeepAlive bool `mapstructure:"disable_keep_alive" json:"disable_keep_alive" yaml:"disable_keep_alive" toml:"disable_keep_alive"`
|
DisableKeepAlive bool `mapstructure:"disable_keep_alive" json:"disable_keep_alive" yaml:"disable_keep_alive" toml:"disable_keep_alive"`
|
||||||
|
|
||||||
// Logger is used to define the logger options.
|
// Logger is used to define the logger options.
|
||||||
Logger liblog.Options `mapstructure:"logger" json:"logger" yaml:"logger" toml:"logger"`
|
Logger logcfg.Options `mapstructure:"logger" json:"logger" yaml:"logger" toml:"logger"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Config) Clone() Config {
|
func (c *Config) Clone() Config {
|
||||||
@@ -414,11 +413,16 @@ func (o *srv) SetConfig(cfg Config, defLog liblog.FuncLog) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *srv) setLogger(def liblog.FuncLog, opt liblog.Options) error {
|
func (o *srv) setLogger(def liblog.FuncLog, opt logcfg.Options) error {
|
||||||
o.m.Lock()
|
o.m.Lock()
|
||||||
defer o.m.Unlock()
|
defer o.m.Unlock()
|
||||||
|
|
||||||
var l liblog.Logger
|
var (
|
||||||
|
l liblog.Logger
|
||||||
|
f = func() liblog.Logger {
|
||||||
|
return liblog.New(o.c.GetContext)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
if def != nil {
|
if def != nil {
|
||||||
if n := def(); n != nil {
|
if n := def(); n != nil {
|
||||||
@@ -427,7 +431,7 @@ func (o *srv) setLogger(def liblog.FuncLog, opt liblog.Options) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if l == nil {
|
if l == nil {
|
||||||
l = liblog.GetDefault()
|
l = f()
|
||||||
}
|
}
|
||||||
|
|
||||||
if e := l.SetOptions(&opt); e == nil {
|
if e := l.SetOptions(&opt); e == nil {
|
||||||
@@ -436,7 +440,9 @@ func (o *srv) setLogger(def liblog.FuncLog, opt liblog.Options) error {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
} else if o.l == nil {
|
} else if o.l == nil {
|
||||||
o.l = liblog.GetDefault
|
o.l = func() liblog.Logger {
|
||||||
|
return l
|
||||||
|
}
|
||||||
return e
|
return e
|
||||||
} else {
|
} else {
|
||||||
return e
|
return e
|
||||||
@@ -451,10 +457,18 @@ func (o *srv) logger() liblog.Logger {
|
|||||||
|
|
||||||
if o.l != nil {
|
if o.l != nil {
|
||||||
log = o.l()
|
log = o.l()
|
||||||
|
} else {
|
||||||
|
log = liblog.New(o.c.GetContext)
|
||||||
|
|
||||||
|
o.m.RUnlock()
|
||||||
|
o.m.Lock()
|
||||||
|
|
||||||
|
o.l = func() liblog.Logger {
|
||||||
|
return log
|
||||||
}
|
}
|
||||||
|
|
||||||
if log == nil {
|
o.m.Unlock()
|
||||||
log = liblog.GetDefault()
|
o.m.RLock()
|
||||||
}
|
}
|
||||||
|
|
||||||
log.SetFields(log.GetFields().Add("bind", o.GetBindable()))
|
log.SetFields(log.GetFields().Add("bind", o.GetBindable()))
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ type Server interface {
|
|||||||
SetConfig(cfg Config, defLog liblog.FuncLog) error
|
SetConfig(cfg Config, defLog liblog.FuncLog) error
|
||||||
|
|
||||||
Monitor(vrs libver.Version) (montps.Monitor, error)
|
Monitor(vrs libver.Version) (montps.Monitor, error)
|
||||||
|
MonitorName() string
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(cfg Config, defLog liblog.FuncLog) (Server, error) {
|
func New(cfg Config, defLog liblog.FuncLog) (Server, error) {
|
||||||
|
|||||||
@@ -32,6 +32,9 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
|
||||||
|
logent "github.com/nabbar/golib/logger/entry"
|
||||||
|
loglvl "github.com/nabbar/golib/logger/level"
|
||||||
|
|
||||||
libmon "github.com/nabbar/golib/monitor"
|
libmon "github.com/nabbar/golib/monitor"
|
||||||
moninf "github.com/nabbar/golib/monitor/info"
|
moninf "github.com/nabbar/golib/monitor/info"
|
||||||
montps "github.com/nabbar/golib/monitor/types"
|
montps "github.com/nabbar/golib/monitor/types"
|
||||||
@@ -39,7 +42,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
defaultNameMonitor = "HTTP Server"
|
DefaultNameMonitor = "HTTP Server"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -47,16 +50,34 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (o *srv) HealthCheck(ctx context.Context) error {
|
func (o *srv) HealthCheck(ctx context.Context) error {
|
||||||
|
var ent logent.Entry
|
||||||
|
|
||||||
|
if l := o.logger(); l != nil {
|
||||||
|
ent = l.Entry(loglvl.ErrorLevel, "Healthcheck")
|
||||||
|
}
|
||||||
|
|
||||||
o.m.RLock()
|
o.m.RLock()
|
||||||
defer o.m.RUnlock()
|
defer o.m.RUnlock()
|
||||||
|
|
||||||
if o.r == nil {
|
if o.r == nil {
|
||||||
|
if ent != nil {
|
||||||
|
ent.ErrorAdd(true, errNotRunning).Check(loglvl.InfoLevel)
|
||||||
|
}
|
||||||
return errNotRunning
|
return errNotRunning
|
||||||
} else if e := o.runAndHealthy(ctx); e != nil {
|
} else if e := o.runAndHealthy(ctx); e != nil {
|
||||||
|
if ent != nil {
|
||||||
|
ent.ErrorAdd(true, e).Check(loglvl.InfoLevel)
|
||||||
|
}
|
||||||
return e
|
return e
|
||||||
} else if e = o.r.ErrorsLast(); e != nil {
|
} else if e = o.r.ErrorsLast(); e != nil {
|
||||||
|
if ent != nil {
|
||||||
|
ent.ErrorAdd(true, e).Check(loglvl.InfoLevel)
|
||||||
|
}
|
||||||
return e
|
return e
|
||||||
} else {
|
} else {
|
||||||
|
if ent != nil {
|
||||||
|
ent.Check(loglvl.InfoLevel)
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -74,6 +95,10 @@ func (o *srv) runAndHealthy(ctx context.Context) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (o *srv) MonitorName() string {
|
||||||
|
return fmt.Sprintf("%s [%s]", DefaultNameMonitor, o.GetBindable())
|
||||||
|
}
|
||||||
|
|
||||||
func (o *srv) Monitor(vrs libver.Version) (montps.Monitor, error) {
|
func (o *srv) Monitor(vrs libver.Version) (montps.Monitor, error) {
|
||||||
var (
|
var (
|
||||||
e error
|
e error
|
||||||
@@ -93,11 +118,11 @@ func (o *srv) Monitor(vrs libver.Version) (montps.Monitor, error) {
|
|||||||
res["date"] = vrs.GetDate()
|
res["date"] = vrs.GetDate()
|
||||||
res["handler"] = o.HandlerGetValidKey()
|
res["handler"] = o.HandlerGetValidKey()
|
||||||
|
|
||||||
if inf, e = moninf.New(defaultNameMonitor); e != nil {
|
if inf, e = moninf.New(DefaultNameMonitor); e != nil {
|
||||||
return nil, e
|
return nil, e
|
||||||
} else {
|
} else {
|
||||||
inf.RegisterName(func() (string, error) {
|
inf.RegisterName(func() (string, error) {
|
||||||
return fmt.Sprintf("%s [%s]", defaultNameMonitor, o.GetBindable()), nil
|
return o.MonitorName(), nil
|
||||||
})
|
})
|
||||||
inf.RegisterInfo(func() (map[string]interface{}, error) {
|
inf.RegisterInfo(func() (map[string]interface{}, error) {
|
||||||
return res, nil
|
return res, nil
|
||||||
|
|||||||
@@ -54,6 +54,8 @@ type Manage interface {
|
|||||||
|
|
||||||
StoreNew(cfg libhtp.Config, defLog liblog.FuncLog) error
|
StoreNew(cfg libhtp.Config, defLog liblog.FuncLog) error
|
||||||
LoadAndDelete(bindAddress string) (val libhtp.Server, loaded bool)
|
LoadAndDelete(bindAddress string) (val libhtp.Server, loaded bool)
|
||||||
|
|
||||||
|
MonitorNames() []string
|
||||||
}
|
}
|
||||||
|
|
||||||
type Filter interface {
|
type Filter interface {
|
||||||
|
|||||||
@@ -108,6 +108,17 @@ func (o *pool) context() context.Context {
|
|||||||
return o.p.GetContext()
|
return o.p.GetContext()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (o *pool) MonitorNames() []string {
|
||||||
|
var res = make([]string, 0)
|
||||||
|
|
||||||
|
o.Walk(func(bindAddress string, srv libhtp.Server) bool {
|
||||||
|
res = append(res, srv.MonitorName())
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
func (o *pool) Monitor(vrs libver.Version) ([]montps.Monitor, liberr.Error) {
|
func (o *pool) Monitor(vrs libver.Version) ([]montps.Monitor, liberr.Error) {
|
||||||
var (
|
var (
|
||||||
res = make([]montps.Monitor, 0)
|
res = make([]montps.Monitor, 0)
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
srvtps "github.com/nabbar/golib/httpserver/types"
|
srvtps "github.com/nabbar/golib/httpserver/types"
|
||||||
liblog "github.com/nabbar/golib/logger"
|
loglvl "github.com/nabbar/golib/logger/level"
|
||||||
librun "github.com/nabbar/golib/server/runner/startStop"
|
librun "github.com/nabbar/golib/server/runner/startStop"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -141,11 +141,11 @@ func (o *srv) runFuncStart(ctx context.Context) (err error) {
|
|||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
if tls {
|
if tls {
|
||||||
ent := o.logger().Entry(liblog.InfoLevel, "TLS HTTP Server stopped")
|
ent := o.logger().Entry(loglvl.InfoLevel, "TLS HTTP Server stopped")
|
||||||
ent.ErrorAdd(true, err)
|
ent.ErrorAdd(true, err)
|
||||||
ent.Log()
|
ent.Log()
|
||||||
} else {
|
} else {
|
||||||
ent := o.logger().Entry(liblog.InfoLevel, "HTTP Server stopped")
|
ent := o.logger().Entry(loglvl.InfoLevel, "HTTP Server stopped")
|
||||||
ent.ErrorAdd(true, err)
|
ent.ErrorAdd(true, err)
|
||||||
ent.Log()
|
ent.Log()
|
||||||
}
|
}
|
||||||
@@ -153,13 +153,13 @@ func (o *srv) runFuncStart(ctx context.Context) (err error) {
|
|||||||
|
|
||||||
if ser = o.getServer(); ser == nil {
|
if ser = o.getServer(); ser == nil {
|
||||||
if err = o.setServer(ctx); err != nil {
|
if err = o.setServer(ctx); err != nil {
|
||||||
ent := o.logger().Entry(liblog.ErrorLevel, "starting http server")
|
ent := o.logger().Entry(loglvl.ErrorLevel, "starting http server")
|
||||||
ent.ErrorAdd(true, err)
|
ent.ErrorAdd(true, err)
|
||||||
ent.Log()
|
ent.Log()
|
||||||
return err
|
return err
|
||||||
} else if ser = o.getServer(); ser == nil {
|
} else if ser = o.getServer(); ser == nil {
|
||||||
err = ErrorServerStart.ErrorParent(fmt.Errorf("cannot create new server, cannot retrieve server"))
|
err = ErrorServerStart.ErrorParent(fmt.Errorf("cannot create new server, cannot retrieve server"))
|
||||||
ent := o.logger().Entry(liblog.ErrorLevel, "starting http server")
|
ent := o.logger().Entry(loglvl.ErrorLevel, "starting http server")
|
||||||
ent.ErrorAdd(true, err)
|
ent.ErrorAdd(true, err)
|
||||||
ent.Log()
|
ent.Log()
|
||||||
return err
|
return err
|
||||||
@@ -175,10 +175,10 @@ func (o *srv) runFuncStart(ctx context.Context) (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if tls {
|
if tls {
|
||||||
o.logger().Entry(liblog.InfoLevel, "TLS HTTP Server is starting").Log()
|
o.logger().Entry(loglvl.InfoLevel, "TLS HTTP Server is starting").Log()
|
||||||
err = ser.ListenAndServeTLS("", "")
|
err = ser.ListenAndServeTLS("", "")
|
||||||
} else {
|
} else {
|
||||||
o.logger().Entry(liblog.InfoLevel, "HTTP Server is starting").Log()
|
o.logger().Entry(loglvl.InfoLevel, "HTTP Server is starting").Log()
|
||||||
err = ser.ListenAndServe()
|
err = ser.ListenAndServe()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -197,11 +197,11 @@ func (o *srv) runFuncStop(ctx context.Context) (err error) {
|
|||||||
defer func() {
|
defer func() {
|
||||||
o.delServer()
|
o.delServer()
|
||||||
if tls {
|
if tls {
|
||||||
ent := o.logger().Entry(liblog.InfoLevel, "Shutdown of TLS HTTP Server has been called")
|
ent := o.logger().Entry(loglvl.InfoLevel, "Shutdown of TLS HTTP Server has been called")
|
||||||
ent.ErrorAdd(true, err)
|
ent.ErrorAdd(true, err)
|
||||||
ent.Log()
|
ent.Log()
|
||||||
} else {
|
} else {
|
||||||
ent := o.logger().Entry(liblog.InfoLevel, "Shutdown of HTTP Server has been called")
|
ent := o.logger().Entry(loglvl.InfoLevel, "Shutdown of HTTP Server has been called")
|
||||||
ent.ErrorAdd(true, err)
|
ent.ErrorAdd(true, err)
|
||||||
ent.Log()
|
ent.Log()
|
||||||
}
|
}
|
||||||
@@ -209,7 +209,7 @@ func (o *srv) runFuncStop(ctx context.Context) (err error) {
|
|||||||
|
|
||||||
if ser = o.getServer(); ser == nil {
|
if ser = o.getServer(); ser == nil {
|
||||||
err = ErrorServerStart.ErrorParent(fmt.Errorf("cannot retrieve server"))
|
err = ErrorServerStart.ErrorParent(fmt.Errorf("cannot retrieve server"))
|
||||||
ent := o.logger().Entry(liblog.ErrorLevel, "starting http server")
|
ent := o.logger().Entry(loglvl.ErrorLevel, "starting http server")
|
||||||
ent.ErrorAdd(true, err)
|
ent.ErrorAdd(true, err)
|
||||||
ent.Log()
|
ent.Log()
|
||||||
return err
|
return err
|
||||||
@@ -218,9 +218,9 @@ func (o *srv) runFuncStop(ctx context.Context) (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if tls {
|
if tls {
|
||||||
o.logger().Entry(liblog.InfoLevel, "Calling TLS HTTP Server shutdown").Log()
|
o.logger().Entry(loglvl.InfoLevel, "Calling TLS HTTP Server shutdown").Log()
|
||||||
} else {
|
} else {
|
||||||
o.logger().Entry(liblog.InfoLevel, "Calling HTTP Server shutdown").Log()
|
o.logger().Entry(loglvl.InfoLevel, "Calling HTTP Server shutdown").Log()
|
||||||
}
|
}
|
||||||
|
|
||||||
err = ser.Shutdown(x)
|
err = ser.Shutdown(x)
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ import (
|
|||||||
|
|
||||||
liberr "github.com/nabbar/golib/errors"
|
liberr "github.com/nabbar/golib/errors"
|
||||||
srvtps "github.com/nabbar/golib/httpserver/types"
|
srvtps "github.com/nabbar/golib/httpserver/types"
|
||||||
liblog "github.com/nabbar/golib/logger"
|
loglvl "github.com/nabbar/golib/logger/level"
|
||||||
libsrv "github.com/nabbar/golib/server"
|
libsrv "github.com/nabbar/golib/server"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -83,7 +83,7 @@ func (o *srv) setServer(ctx context.Context) error {
|
|||||||
|
|
||||||
if o.IsTLS() && ssl == nil {
|
if o.IsTLS() && ssl == nil {
|
||||||
err := ErrorServerValidate.ErrorParent(fmt.Errorf("TLS Config is not well defined"))
|
err := ErrorServerValidate.ErrorParent(fmt.Errorf("TLS Config is not well defined"))
|
||||||
ent := o.logger().Entry(liblog.ErrorLevel, "starting http server")
|
ent := o.logger().Entry(loglvl.ErrorLevel, "starting http server")
|
||||||
ent.ErrorAdd(true, err)
|
ent.ErrorAdd(true, err)
|
||||||
ent.Log()
|
ent.Log()
|
||||||
return err
|
return err
|
||||||
@@ -102,13 +102,13 @@ func (o *srv) setServer(ctx context.Context) error {
|
|||||||
s.TLSConfig = ssl.TlsConfig("")
|
s.TLSConfig = ssl.TlsConfig("")
|
||||||
stdlog.SetIOWriterFilter("http: TLS handshake error from 127.0.0.1")
|
stdlog.SetIOWriterFilter("http: TLS handshake error from 127.0.0.1")
|
||||||
} else if e := o.cfgGetServer().initServer(s); e != nil {
|
} else if e := o.cfgGetServer().initServer(s); e != nil {
|
||||||
ent := o.logger().Entry(liblog.ErrorLevel, "init http2 server")
|
ent := o.logger().Entry(loglvl.ErrorLevel, "init http2 server")
|
||||||
ent.ErrorAdd(true, e)
|
ent.ErrorAdd(true, e)
|
||||||
ent.Log()
|
ent.Log()
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
s.ErrorLog = stdlog.GetStdLogger(liblog.ErrorLevel, log.LstdFlags|log.Lmicroseconds)
|
s.ErrorLog = stdlog.GetStdLogger(loglvl.ErrorLevel, log.LstdFlags|log.Lmicroseconds)
|
||||||
|
|
||||||
if e := o.RunIfPortInUse(ctx, o.GetBindable(), 5, fctStop); e != nil {
|
if e := o.RunIfPortInUse(ctx, o.GetBindable(), 5, fctStop); e != nil {
|
||||||
return e
|
return e
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ package ioutils
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
)
|
)
|
||||||
@@ -36,21 +37,28 @@ import (
|
|||||||
func PathCheckCreate(isFile bool, path string, permFile os.FileMode, permDir os.FileMode) error {
|
func PathCheckCreate(isFile bool, path string, permFile os.FileMode, permDir os.FileMode) error {
|
||||||
if inf, err := os.Stat(path); err != nil && !errors.Is(err, os.ErrNotExist) {
|
if inf, err := os.Stat(path); err != nil && !errors.Is(err, os.ErrNotExist) {
|
||||||
return err
|
return err
|
||||||
} else if err == nil {
|
} else if err == nil && inf.IsDir() {
|
||||||
if inf.IsDir() {
|
if isFile {
|
||||||
|
return fmt.Errorf("path '%s' still exising but is a directory", path)
|
||||||
|
}
|
||||||
|
if inf.Mode() != permDir {
|
||||||
_ = os.Chmod(path, permDir)
|
_ = os.Chmod(path, permDir)
|
||||||
} else {
|
}
|
||||||
|
return nil
|
||||||
|
} else if err == nil && !inf.IsDir() {
|
||||||
|
if !isFile {
|
||||||
|
return fmt.Errorf("path '%s' still exising but is not a directory", path)
|
||||||
|
}
|
||||||
|
if inf.Mode() != permFile {
|
||||||
_ = os.Chmod(path, permFile)
|
_ = os.Chmod(path, permFile)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
} else if !isFile {
|
||||||
|
|
||||||
if !isFile {
|
|
||||||
return os.MkdirAll(path, permDir)
|
return os.MkdirAll(path, permDir)
|
||||||
} else if e := PathCheckCreate(false, filepath.Dir(path), permFile, permDir); e != nil {
|
} else if err = PathCheckCreate(false, filepath.Dir(path), permFile, permDir); err != nil {
|
||||||
return e
|
|
||||||
} else if hf, err := os.Create(path); err != nil {
|
|
||||||
return err
|
return err
|
||||||
|
} else if hf, e := os.Create(path); e != nil {
|
||||||
|
return e
|
||||||
} else {
|
} else {
|
||||||
_ = hf.Close()
|
_ = hf.Close()
|
||||||
}
|
}
|
||||||
|
|||||||
66
ldap/ldap.go
66
ldap/ldap.go
@@ -37,6 +37,8 @@ import (
|
|||||||
libctx "github.com/nabbar/golib/context"
|
libctx "github.com/nabbar/golib/context"
|
||||||
liberr "github.com/nabbar/golib/errors"
|
liberr "github.com/nabbar/golib/errors"
|
||||||
liblog "github.com/nabbar/golib/logger"
|
liblog "github.com/nabbar/golib/logger"
|
||||||
|
logent "github.com/nabbar/golib/logger/entry"
|
||||||
|
loglvl "github.com/nabbar/golib/logger/level"
|
||||||
)
|
)
|
||||||
|
|
||||||
type FuncLogger liblog.FuncLog
|
type FuncLogger liblog.FuncLog
|
||||||
@@ -75,29 +77,49 @@ func (lc *HelperLDAP) SetLogger(fct liblog.FuncLog) {
|
|||||||
lc.log = fct
|
lc.log = fct
|
||||||
}
|
}
|
||||||
|
|
||||||
func (lc HelperLDAP) getLogEntry(lvl liblog.Level, msg string, args ...interface{}) *liblog.Entry {
|
func (lc *HelperLDAP) getLogDefault() liblog.Logger {
|
||||||
|
return liblog.New(func() context.Context {
|
||||||
|
return lc.ctx
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (lc *HelperLDAP) getLogEntry(lvl loglvl.Level, msg string, args ...interface{}) logent.Entry {
|
||||||
var log liblog.Logger
|
var log liblog.Logger
|
||||||
if lc.log == nil {
|
if lc.log == nil {
|
||||||
log = liblog.GetDefault()
|
log = lc.getLogDefault()
|
||||||
} else if l := lc.log(); l == nil {
|
lc.log = func() liblog.Logger {
|
||||||
log = liblog.GetDefault()
|
return log
|
||||||
} else {
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if l := lc.log(); l != nil {
|
||||||
log = l
|
log = l
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if log == nil {
|
||||||
|
return logent.New(lvl)
|
||||||
|
}
|
||||||
|
|
||||||
return log.Entry(lvl, msg, args...).FieldAdd("ldap.host", lc.config.ServerAddr(lc.tlsMode == TLSModeTLS)).FieldAdd("ldap.tlsMode", lc.tlsMode.String())
|
return log.Entry(lvl, msg, args...).FieldAdd("ldap.host", lc.config.ServerAddr(lc.tlsMode == TLSModeTLS)).FieldAdd("ldap.tlsMode", lc.tlsMode.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (lc HelperLDAP) getLogEntryErr(lvlKO liblog.Level, err error, msg string, args ...interface{}) *liblog.Entry {
|
func (lc *HelperLDAP) getLogEntryErr(lvlKO loglvl.Level, err error, msg string, args ...interface{}) logent.Entry {
|
||||||
var log liblog.Logger
|
var log liblog.Logger
|
||||||
if lc.log == nil {
|
if lc.log == nil {
|
||||||
log = liblog.GetDefault()
|
log = lc.getLogDefault()
|
||||||
} else if l := lc.log(); l == nil {
|
lc.log = func() liblog.Logger {
|
||||||
log = liblog.GetDefault()
|
return log
|
||||||
} else {
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if l := lc.log(); l != nil {
|
||||||
log = l
|
log = l
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if log == nil {
|
||||||
|
return logent.New(lvlKO).ErrorAdd(true, err)
|
||||||
|
}
|
||||||
|
|
||||||
return log.Entry(lvlKO, msg, args...).FieldAdd("ldap.host", lc.config.ServerAddr(lc.tlsMode == TLSModeTLS)).ErrorAdd(true, err)
|
return log.Entry(lvlKO, msg, args...).FieldAdd("ldap.host", lc.config.ServerAddr(lc.tlsMode == TLSModeTLS)).ErrorAdd(true, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -227,7 +249,7 @@ func (lc *HelperLDAP) tryConnect() (TLSMode, liberr.Error) {
|
|||||||
if lc.config.Portldaps != 0 {
|
if lc.config.Portldaps != 0 {
|
||||||
l, err = lc.dialTLS()
|
l, err = lc.dialTLS()
|
||||||
|
|
||||||
lc.getLogEntryErr(liblog.DebugLevel, err, "connecting ldap with tls mode '%s'", TLSModeTLS.String()).Check(liblog.DebugLevel)
|
lc.getLogEntryErr(loglvl.DebugLevel, err, "connecting ldap with tls mode '%s'", TLSModeTLS.String()).Check(loglvl.DebugLevel)
|
||||||
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return TLSModeTLS, nil
|
return TLSModeTLS, nil
|
||||||
@@ -239,14 +261,14 @@ func (lc *HelperLDAP) tryConnect() (TLSMode, liberr.Error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
l, err = lc.dial()
|
l, err = lc.dial()
|
||||||
lc.getLogEntryErr(liblog.DebugLevel, err, "connecting ldap with tls mode '%s'", TLSModeNone.String()).Check(liblog.DebugLevel)
|
lc.getLogEntryErr(loglvl.DebugLevel, err, "connecting ldap with tls mode '%s'", TLSModeNone.String()).Check(loglvl.DebugLevel)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return _TLSModeInit, err
|
return _TLSModeInit, err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = lc.starttls(l)
|
err = lc.starttls(l)
|
||||||
lc.getLogEntryErr(liblog.DebugLevel, err, "connecting ldap with tls mode '%s'", TLSModeStarttls.String()).Check(liblog.DebugLevel)
|
lc.getLogEntryErr(loglvl.DebugLevel, err, "connecting ldap with tls mode '%s'", TLSModeStarttls.String()).Check(loglvl.DebugLevel)
|
||||||
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return TLSModeStarttls, nil
|
return TLSModeStarttls, nil
|
||||||
@@ -310,7 +332,7 @@ func (lc *HelperLDAP) connect() liberr.Error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lc.getLogEntry(liblog.DebugLevel, "ldap connected").Log()
|
lc.getLogEntry(loglvl.DebugLevel, "ldap connected").Log()
|
||||||
lc.conn = l
|
lc.conn = l
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -381,7 +403,7 @@ func (lc *HelperLDAP) Connect() liberr.Error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
lc.getLogEntry(liblog.DebugLevel, "ldap bind success").FieldAdd("bind.dn", lc.bindDN).Log()
|
lc.getLogEntry(loglvl.DebugLevel, "ldap bind success").FieldAdd("bind.dn", lc.bindDN).Log()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -411,7 +433,7 @@ func (lc *HelperLDAP) runSearch(filter string, attributes []string) (*ldap.Searc
|
|||||||
return nil, ErrorLDAPSearch.ErrorParent(err)
|
return nil, ErrorLDAPSearch.ErrorParent(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
lc.getLogEntry(liblog.DebugLevel, "ldap search success").FieldAdd("ldap.filter", filter).FieldAdd("ldap.attributes", attributes).Log()
|
lc.getLogEntry(loglvl.DebugLevel, "ldap search success").FieldAdd("ldap.filter", filter).FieldAdd("ldap.attributes", attributes).Log()
|
||||||
return src, nil
|
return src, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -480,7 +502,7 @@ func (lc *HelperLDAP) UserInfoByField(username string, fieldOfUnicValue string)
|
|||||||
userRes["DN"] = src.Entries[0].DN
|
userRes["DN"] = src.Entries[0].DN
|
||||||
}
|
}
|
||||||
|
|
||||||
lc.getLogEntry(liblog.DebugLevel, "ldap user find success").FieldAdd("ldap.user", username).FieldAdd("ldap.map", userRes).Log()
|
lc.getLogEntry(loglvl.DebugLevel, "ldap user find success").FieldAdd("ldap.user", username).FieldAdd("ldap.map", userRes).Log()
|
||||||
return userRes, nil
|
return userRes, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -513,7 +535,7 @@ func (lc *HelperLDAP) GroupInfoByField(groupname string, fieldForUnicValue strin
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lc.getLogEntry(liblog.DebugLevel, "ldap group find success").FieldAdd("ldap.group", groupname).FieldAdd("ldap.map", grpInfo).Log()
|
lc.getLogEntry(loglvl.DebugLevel, "ldap group find success").FieldAdd("ldap.group", groupname).FieldAdd("ldap.map", grpInfo).Log()
|
||||||
return grpInfo, nil
|
return grpInfo, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -538,13 +560,13 @@ func (lc *HelperLDAP) UserMemberOf(username string) ([]string, liberr.Error) {
|
|||||||
|
|
||||||
for _, entry := range src.Entries {
|
for _, entry := range src.Entries {
|
||||||
for _, mmb := range entry.GetAttributeValues("memberOf") {
|
for _, mmb := range entry.GetAttributeValues("memberOf") {
|
||||||
lc.getLogEntry(liblog.DebugLevel, "ldap find user group list building").FieldAdd("ldap.user", username).FieldAdd("ldap.raw.groups", mmb).Log()
|
lc.getLogEntry(loglvl.DebugLevel, "ldap find user group list building").FieldAdd("ldap.user", username).FieldAdd("ldap.raw.groups", mmb).Log()
|
||||||
mmo := lc.ParseEntries(mmb)
|
mmo := lc.ParseEntries(mmb)
|
||||||
grp = append(grp, mmo["cn"]...)
|
grp = append(grp, mmo["cn"]...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lc.getLogEntry(liblog.DebugLevel, "ldap user group list success").FieldAdd("ldap.user", username).FieldAdd("ldap.grouplist", grp).Log()
|
lc.getLogEntry(loglvl.DebugLevel, "ldap user group list success").FieldAdd("ldap.user", username).FieldAdd("ldap.grouplist", grp).Log()
|
||||||
return grp, nil
|
return grp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -594,12 +616,12 @@ func (lc *HelperLDAP) UsersOfGroup(groupname string) ([]string, liberr.Error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lc.getLogEntry(liblog.DebugLevel, "ldap group user list success").FieldAdd("ldap.group", groupname).FieldAdd("ldap.userlist", grp).Log()
|
lc.getLogEntry(loglvl.DebugLevel, "ldap group user list success").FieldAdd("ldap.group", groupname).FieldAdd("ldap.userlist", grp).Log()
|
||||||
return grp, nil
|
return grp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ParseEntries used to clean attributes of an object class.
|
// ParseEntries used to clean attributes of an object class.
|
||||||
func (lc HelperLDAP) ParseEntries(entry string) map[string][]string {
|
func (lc *HelperLDAP) ParseEntries(entry string) map[string][]string {
|
||||||
var listEntries = make(map[string][]string)
|
var listEntries = make(map[string][]string)
|
||||||
|
|
||||||
for _, ent := range strings.Split(entry, ",") {
|
for _, ent := range strings.Split(entry, ",") {
|
||||||
|
|||||||
281
logger/compat.go
281
logger/compat.go
@@ -1,281 +0,0 @@
|
|||||||
/***********************************************************************************************************************
|
|
||||||
*
|
|
||||||
* 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 (
|
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
)
|
|
||||||
|
|
||||||
// @deprecated: only for retro compatibility
|
|
||||||
var defaultLogger Logger
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
defaultLogger = New(context.Background)
|
|
||||||
defaultLogger.SetLevel(InfoLevel)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetDefault return the default logger
|
|
||||||
// @deprecated: create a logger and call GetLevel() like New().GetLevel()
|
|
||||||
func GetDefault() Logger {
|
|
||||||
return defaultLogger
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetCurrentLevel return the current loglevel setting in the logger. All log entry matching this level or below will be logged.
|
|
||||||
// @deprecated: create a logger and call GetLevel() like New().GetLevel()
|
|
||||||
func GetCurrentLevel() Level {
|
|
||||||
return defaultLogger.GetLevel()
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetLevel Change the Level of all log entry with the Level type given in parameter. The change is apply for next log entry only.
|
|
||||||
// If the given Level type is not matching a correct Level type, no change will be apply.
|
|
||||||
// @deprecated: create a logger and call GetLevel() like New().GetLevel...
|
|
||||||
func SetLevel(level Level) {
|
|
||||||
defaultLogger.SetLevel(level)
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddGID Reconfigure the current logger to add or not the thread GID before each message.
|
|
||||||
// @deprecated: create a logger and update the options like New().SetOptions...
|
|
||||||
func AddGID(enable bool) {
|
|
||||||
opt := defaultLogger.GetOptions()
|
|
||||||
opt.DisableStack = !enable
|
|
||||||
_ = defaultLogger.SetOptions(opt)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Timestamp Reconfigure the current logger to add or not the timestamp before each message.
|
|
||||||
// @deprecated: create a logger and update the options like New().SetOptions...
|
|
||||||
func Timestamp(enable bool) {
|
|
||||||
opt := defaultLogger.GetOptions()
|
|
||||||
opt.DisableTimestamp = !enable
|
|
||||||
_ = defaultLogger.SetOptions(opt)
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsTimeStamp will return true if timestamp is added or not on log message
|
|
||||||
// @deprecated: create a logger and get the options like New().GetOptions...
|
|
||||||
func IsTimeStamp() bool {
|
|
||||||
return !defaultLogger.GetOptions().DisableTimestamp
|
|
||||||
}
|
|
||||||
|
|
||||||
// FileTrace Reconfigure the current logger to add or not the origin file/line of each message.
|
|
||||||
// This option is apply for all message except info message.
|
|
||||||
// @deprecated: create a logger and update the options like New().SetOptions...
|
|
||||||
func FileTrace(enable bool) {
|
|
||||||
opt := defaultLogger.GetOptions()
|
|
||||||
opt.EnableTrace = enable
|
|
||||||
_ = defaultLogger.SetOptions(opt)
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsFileTrace will return true if trace is added or not on log message
|
|
||||||
// @deprecated: create a logger and get the options like New().GetOptions...
|
|
||||||
func IsFileTrace() bool {
|
|
||||||
return defaultLogger.GetOptions().EnableTrace
|
|
||||||
}
|
|
||||||
|
|
||||||
// ModeColor will reconfigure the current logger to use or not color in messages format.
|
|
||||||
// This apply only for next message and only for TextFormat.
|
|
||||||
// @deprecated: create a logger and update the options like New().SetOptions...
|
|
||||||
func ModeColor(enable bool) {
|
|
||||||
opt := defaultLogger.GetOptions()
|
|
||||||
opt.DisableColor = !enable
|
|
||||||
_ = defaultLogger.SetOptions(opt)
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsModeColor will return true if color is configured on log message
|
|
||||||
// @deprecated: create a logger and get the options like New().GetOptions...
|
|
||||||
func IsModeColor() bool {
|
|
||||||
return !defaultLogger.GetOptions().DisableColor
|
|
||||||
}
|
|
||||||
|
|
||||||
// EnableColor Reconfigure the current logger to use color in messages format.
|
|
||||||
// This apply only for next message and only for TextFormat.
|
|
||||||
// @deprecated: create a logger and update the options like New().SetOptions...
|
|
||||||
func EnableColor() {
|
|
||||||
ModeColor(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
// DisableColor Reconfigure the current logger to not use color in messages format.
|
|
||||||
// This apply only for next message and only for TextFormat.
|
|
||||||
// @deprecated: create a logger and update the options like New().SetOptions...
|
|
||||||
func DisableColor() {
|
|
||||||
ModeColor(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
// EnableViperLog enable or not the Gin Logger configuration.
|
|
||||||
// @deprecated: create a logger and call function SetSPF13Level like New().SetSPF13Level...
|
|
||||||
func EnableViperLog(enable bool) {
|
|
||||||
defaultLogger.SetSPF13Level(defaultLogger.GetLevel(), nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetTracePathFilter customize the filter apply to filepath on trace.
|
|
||||||
// @deprecated: create a logger and update the options like New().SetOptions...
|
|
||||||
func SetTracePathFilter(path string) {
|
|
||||||
opt := defaultLogger.GetOptions()
|
|
||||||
opt.TraceFilter = path
|
|
||||||
_ = defaultLogger.SetOptions(opt)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Log Simple function to log directly the given message with the attached log Level.
|
|
||||||
/*
|
|
||||||
message a string message to be logged with the attached log Level
|
|
||||||
*/
|
|
||||||
//@deprecated: create a logger and call one of this function : New().Debug, New().Info, New().Warning, New().Error, New().Fatal, New().Panic, New().LogDetails or New().Entry
|
|
||||||
func (l Level) Log(message string) {
|
|
||||||
defaultLogger.LogDetails(l, message, nil, nil, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Logf Simple function to log (to the attached log Level) with a fmt function a given pattern and arguments in parameters.
|
|
||||||
/*
|
|
||||||
format a string pattern for fmt function
|
|
||||||
args a list of interface to match the references in the pattern
|
|
||||||
*/
|
|
||||||
//@deprecated: create a logger and call one of this function : New().Debug, New().Info, New().Warning, New().Error, New().Fatal, New().Panic, New().LogDetails or New().Entry
|
|
||||||
func (l Level) Logf(format string, args ...interface{}) {
|
|
||||||
defaultLogger.LogDetails(l, fmt.Sprintf(format, args...), nil, nil, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
// LogData Simple function to log directly the given message with given data with the attached log Level.
|
|
||||||
/*
|
|
||||||
message a string message to be logged with the attached log Level
|
|
||||||
data an interface of data to be logged with the message. (In Text format, the data will be json marshaled)
|
|
||||||
*/
|
|
||||||
//@deprecated: create a logger and call one of this function : New().Debug, New().Info, New().Warning, New().Error, New().Fatal, New().Panic, New().LogDetails or New().Entry
|
|
||||||
func (l Level) LogData(message string, data interface{}) {
|
|
||||||
defaultLogger.LogDetails(l, message, data, nil, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithFields Simple function to log directly the given message with given fields with the attached log Level.
|
|
||||||
/*
|
|
||||||
message a string message to be logged with the attached log Level
|
|
||||||
fields a map of string key and interfaces value for a complete list of field ("field name" => value interface)
|
|
||||||
*/
|
|
||||||
//@deprecated: create a logger and call one of this function : New().Debug, New().Info, New().Warning, New().Error, New().Fatal, New().Panic, New().LogDetails or New().Entry
|
|
||||||
func (l Level) WithFields(message string, fields Fields) {
|
|
||||||
defaultLogger.LogDetails(l, message, nil, nil, fields)
|
|
||||||
}
|
|
||||||
|
|
||||||
// LogError Simple function to log directly the given error with the attached log Level.
|
|
||||||
//
|
|
||||||
// How iot works :
|
|
||||||
// + when the err is a valid error, this function will :
|
|
||||||
// +--- log the Error with the attached log Level
|
|
||||||
// +--- return true
|
|
||||||
// + when the err is nil, this function will :
|
|
||||||
// +--- return false
|
|
||||||
/*
|
|
||||||
err an error object message to be logged with the attached log Level
|
|
||||||
*/
|
|
||||||
//@deprecated: create a logger and call one of this function : New().CheckError or New().Entry.Check
|
|
||||||
func (l Level) LogError(err error) bool {
|
|
||||||
return defaultLogger.CheckError(l, NilLevel, "", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// LogErrorCtx Function to test, log and inform about the given error object.
|
|
||||||
//
|
|
||||||
// How iot works :
|
|
||||||
// + when the err is a valid error, this function will :
|
|
||||||
// +--- log the Error with the attached log Level
|
|
||||||
// +--- return true
|
|
||||||
// + when the err is nil, this function will :
|
|
||||||
// +--- use the levelElse if valid to inform with context there is no error found
|
|
||||||
// +--- return false
|
|
||||||
/*
|
|
||||||
levelElse level used if the err is nil before returning a False result
|
|
||||||
context a string for the context of the current test of the error
|
|
||||||
err a error object to be log with the attached log level before return true, if the err is nil, the levelElse is used to log there are no error and return false
|
|
||||||
*/
|
|
||||||
//@deprecated: create a logger and call one of this function : New().CheckError or New().Entry.Check
|
|
||||||
func (l Level) LogErrorCtx(levelElse Level, context string, err error) bool {
|
|
||||||
return defaultLogger.Entry(l, context).ErrorAdd(true, err).Check(levelElse)
|
|
||||||
}
|
|
||||||
|
|
||||||
// LogErrorCtxf Function to test, log and inform about the given error object, but with a context based on a pattern and matching args.
|
|
||||||
//
|
|
||||||
// How iot works :
|
|
||||||
// + when the err is a valid error, this function will :
|
|
||||||
// +--- log the Error with the attached log Level
|
|
||||||
// +--- return true
|
|
||||||
// + when the err is nil, this function will :
|
|
||||||
// +--- use the levelElse if valid to inform with context there is no error found
|
|
||||||
// +--- return false
|
|
||||||
/*
|
|
||||||
levelElse level used if the err is nil before returning a False result
|
|
||||||
contextPattern a pattern string for the context of the current test of the error. This string will be used in a fmt function as pattern string
|
|
||||||
err a error object to be log with the attached log level before return true, if the err is nil, the levelElse is used to log there are no error and return false
|
|
||||||
args a list of interface for the context of the current test of the error. This list of interface will be used in a fmt function as the matching args for the pattern string
|
|
||||||
*/
|
|
||||||
//@deprecated: create a logger and call one of this function : New().CheckError or New().Entry.Check
|
|
||||||
func (l Level) LogErrorCtxf(levelElse Level, contextPattern string, err error, args ...interface{}) bool {
|
|
||||||
return defaultLogger.Entry(l, contextPattern, args...).ErrorAdd(true, err).Check(levelElse)
|
|
||||||
}
|
|
||||||
|
|
||||||
// LogGinErrorCtxf Function to test, log and inform about the given error object, but with a context based on a couple of pattern and matching args.
|
|
||||||
// This function will also add an Gin Tonic Error if the c parameters is a valid GinTonic Context reference.
|
|
||||||
//
|
|
||||||
// How iot works :
|
|
||||||
// + when the err is a valid error, this function will :
|
|
||||||
// +--- log the Error with the attached log Level
|
|
||||||
// +--- if the Context Gin Tonic is valid, add the Error into this context
|
|
||||||
// +--- return true
|
|
||||||
// + when the err is nil, this function will :
|
|
||||||
// +--- use the levelElse if valid to inform with context there is no error found
|
|
||||||
// +--- return false
|
|
||||||
/*
|
|
||||||
levelElse level used if the err is nil before returning a False result
|
|
||||||
contextPattern a pattern string for the context of the current test of the error. This string will be used in a fmt function as pattern string
|
|
||||||
err a error object to be log with the attached log level before return true, if the err is nil, the levelElse is used to log there are no error and return false
|
|
||||||
c a valid Go GinTonic Context reference to add current error to the Gin Tonic Error Context
|
|
||||||
args a list of interface for the context of the current test of the error. This list of interface will be used in a fmt function as the matching args for the pattern string
|
|
||||||
*/
|
|
||||||
//@deprecated: create a logger and call one of this function : New().CheckError or New().Entry.SetGinContext.Check
|
|
||||||
func (l Level) LogGinErrorCtxf(levelElse Level, contextPattern string, err error, c *gin.Context, args ...interface{}) bool {
|
|
||||||
return defaultLogger.Entry(l, contextPattern, args...).SetGinContext(c).ErrorAdd(true, err).Check(levelElse)
|
|
||||||
}
|
|
||||||
|
|
||||||
// LogGinErrorCtx Function to test, log and inform about the given error object.
|
|
||||||
// This function will also add an Gin Tonic Error if the c parameters is a valid GinTonic Context reference.
|
|
||||||
//
|
|
||||||
// How iot works :
|
|
||||||
// + when the err is a valid error, this function will :
|
|
||||||
// +--- log the Error with the attached log Level
|
|
||||||
// +--- if the Context Gin Tonic is valid, add the Error into this context
|
|
||||||
// +--- return true
|
|
||||||
// + when the err is nil, this function will :
|
|
||||||
// +--- use the levelElse if valid to inform with context there is no error found
|
|
||||||
// +--- return false
|
|
||||||
/*
|
|
||||||
levelElse level used if the err is nil before returning a False result
|
|
||||||
context a string for the context of the current test of the error
|
|
||||||
err a error object to be log with the attached log level before return true, if the err is nil, the levelElse is used to log there are no error and return false
|
|
||||||
c a valid Go GinTonic Context reference to add current error to the Gin Tonic Error Context.
|
|
||||||
*/
|
|
||||||
//@deprecated: create a logger and call one of this function : New().CheckError or New().Entry.SetGinContext.Check
|
|
||||||
func (l Level) LogGinErrorCtx(levelElse Level, context string, err error, c *gin.Context) bool {
|
|
||||||
return defaultLogger.Entry(l, context).SetGinContext(c).ErrorAdd(true, err).Check(levelElse)
|
|
||||||
}
|
|
||||||
@@ -1,7 +1,8 @@
|
|||||||
/*
|
/***********************************************************************************************************************
|
||||||
|
*
|
||||||
* MIT License
|
* MIT License
|
||||||
*
|
*
|
||||||
* Copyright (c) 2022 Nicolas JUHEL
|
* Copyright (c) 2021 Nicolas JUHEL
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -22,7 +23,7 @@
|
|||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*/
|
**********************************************************************************************************************/
|
||||||
|
|
||||||
package config
|
package config
|
||||||
|
|
||||||
@@ -35,12 +36,15 @@ import (
|
|||||||
|
|
||||||
var _defaultConfig = []byte(`
|
var _defaultConfig = []byte(`
|
||||||
{
|
{
|
||||||
|
"inheritDefault": false,
|
||||||
|
"traceFilter":"",
|
||||||
|
"stdout":{
|
||||||
"disableStandard":false,
|
"disableStandard":false,
|
||||||
"disableStack":false,
|
"disableStack":false,
|
||||||
"disableTimestamp":false,
|
"disableTimestamp":false,
|
||||||
"enableTrace":true,
|
"enableTrace":true,
|
||||||
"traceFilter":"",
|
|
||||||
"disableColor":false,
|
"disableColor":false,
|
||||||
|
},
|
||||||
"logFile":[
|
"logFile":[
|
||||||
{
|
{
|
||||||
"logLevel":[
|
"logLevel":[
|
||||||
|
|||||||
57
logger/config/error.go
Normal file
57
logger/config/error.go
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
/***********************************************************************************************************************
|
||||||
|
*
|
||||||
|
* 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 config
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
liberr "github.com/nabbar/golib/errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
ErrorParamEmpty liberr.CodeError = iota + liberr.MinPkgLogger
|
||||||
|
ErrorValidatorError
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
if liberr.ExistInMapMessage(ErrorParamEmpty) {
|
||||||
|
panic(fmt.Errorf("error code collision with package golib/logger"))
|
||||||
|
}
|
||||||
|
liberr.RegisterIdFctMessage(ErrorParamEmpty, getMessage)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getMessage(code liberr.CodeError) (message string) {
|
||||||
|
switch code {
|
||||||
|
case ErrorParamEmpty:
|
||||||
|
return "given parameters is empty"
|
||||||
|
case ErrorValidatorError:
|
||||||
|
return "logger : invalid config"
|
||||||
|
}
|
||||||
|
|
||||||
|
return liberr.NullMessage
|
||||||
|
}
|
||||||
204
logger/config/model.go
Normal file
204
logger/config/model.go
Normal file
@@ -0,0 +1,204 @@
|
|||||||
|
/***********************************************************************************************************************
|
||||||
|
*
|
||||||
|
* 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 config
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
libval "github.com/go-playground/validator/v10"
|
||||||
|
liberr "github.com/nabbar/golib/errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
type FuncOpt func() *Options
|
||||||
|
|
||||||
|
type Options struct {
|
||||||
|
// InheritDefault define if the current options will override a default options
|
||||||
|
InheritDefault bool `json:"inheritDefault" yaml:"inheritDefault" toml:"inheritDefault" mapstructure:"inheritDefault"`
|
||||||
|
|
||||||
|
// TraceFilter define the path to clean for trace.
|
||||||
|
TraceFilter string `json:"traceFilter,omitempty" yaml:"traceFilter,omitempty" toml:"traceFilter,omitempty" mapstructure:"traceFilter,omitempty"`
|
||||||
|
|
||||||
|
// Stdout define the options for stdout/stderr log.
|
||||||
|
Stdout *OptionsStd `json:"stdout,omitempty" yaml:"stdout,omitempty" toml:"stdout,omitempty" mapstructure:"stdout,omitempty"`
|
||||||
|
|
||||||
|
// LogFileExtend define if the logFile given is in addition of default LogFile or a replacement.
|
||||||
|
LogFileExtend bool `json:"logFileExtend,omitempty" yaml:"logFileExtend,omitempty" toml:"logFileExtend,omitempty" mapstructure:"logFileExtend,omitempty"`
|
||||||
|
|
||||||
|
// LogFile define a list of log file configuration to allow log to files.
|
||||||
|
LogFile OptionsFiles `json:"logFile,omitempty" yaml:"logFile,omitempty" toml:"logFile,omitempty" mapstructure:"logFile,omitempty"`
|
||||||
|
|
||||||
|
// LogSyslogExtend define if the logFile given is in addition of default LogSyslog or a replacement.
|
||||||
|
LogSyslogExtend bool `json:"logSyslogExtend,omitempty" yaml:"logSyslogExtend,omitempty" toml:"logSyslogExtend,omitempty" mapstructure:"logSyslogExtend,omitempty"`
|
||||||
|
|
||||||
|
// LogSyslog define a list of syslog configuration to allow log to syslog.
|
||||||
|
LogSyslog OptionsSyslogs `json:"logSyslog,omitempty" yaml:"logSyslog,omitempty" toml:"logSyslog,omitempty" mapstructure:"logSyslog,omitempty"`
|
||||||
|
|
||||||
|
// default options
|
||||||
|
opts FuncOpt
|
||||||
|
}
|
||||||
|
|
||||||
|
// RegisterDefaultFunc allow to register a function called to retrieve default options for inheritDefault.
|
||||||
|
// If not set, the previous options will be used as default options.
|
||||||
|
// To clean function, just call RegisterDefaultFunc with nil as param.
|
||||||
|
func (o *Options) RegisterDefaultFunc(fct FuncOpt) {
|
||||||
|
o.opts = fct
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate allow checking if the options' struct is valid with the awaiting model
|
||||||
|
func (o *Options) Validate() liberr.Error {
|
||||||
|
var e = ErrorValidatorError.Error(nil)
|
||||||
|
|
||||||
|
if err := libval.New().Struct(o); err != nil {
|
||||||
|
if er, ok := err.(*libval.InvalidValidationError); ok {
|
||||||
|
e.AddParent(er)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, er := range err.(libval.ValidationErrors) {
|
||||||
|
//nolint #goerr113
|
||||||
|
e.AddParent(fmt.Errorf("config field '%s' is not validated by constraint '%s'", er.Namespace(), er.ActualTag()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !e.HasParent() {
|
||||||
|
e = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *Options) Clone() Options {
|
||||||
|
var s *OptionsStd
|
||||||
|
|
||||||
|
if o.Stdout != nil {
|
||||||
|
s = o.Stdout.Clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
return Options{
|
||||||
|
InheritDefault: o.InheritDefault,
|
||||||
|
TraceFilter: o.TraceFilter,
|
||||||
|
Stdout: s,
|
||||||
|
LogFile: o.LogFile.Clone(),
|
||||||
|
LogSyslog: o.LogSyslog.Clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *Options) Merge(opt *Options) {
|
||||||
|
if len(opt.TraceFilter) > 0 {
|
||||||
|
o.TraceFilter = opt.TraceFilter
|
||||||
|
}
|
||||||
|
|
||||||
|
if opt.Stdout != nil {
|
||||||
|
if o.Stdout == nil {
|
||||||
|
o.Stdout = &OptionsStd{}
|
||||||
|
}
|
||||||
|
if opt.Stdout.DisableStandard {
|
||||||
|
o.Stdout.DisableStandard = opt.Stdout.DisableStandard
|
||||||
|
}
|
||||||
|
if opt.Stdout.DisableColor {
|
||||||
|
o.Stdout.DisableColor = opt.Stdout.DisableColor
|
||||||
|
}
|
||||||
|
if opt.Stdout.DisableTimestamp {
|
||||||
|
o.Stdout.DisableTimestamp = opt.Stdout.DisableTimestamp
|
||||||
|
}
|
||||||
|
if opt.Stdout.DisableStack {
|
||||||
|
o.Stdout.DisableStack = opt.Stdout.DisableStack
|
||||||
|
}
|
||||||
|
if opt.Stdout.EnableTrace {
|
||||||
|
o.Stdout.EnableTrace = opt.Stdout.EnableTrace
|
||||||
|
}
|
||||||
|
if opt.Stdout.EnableAccessLog {
|
||||||
|
o.Stdout.EnableAccessLog = opt.Stdout.EnableAccessLog
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if opt.LogFileExtend {
|
||||||
|
o.LogFile = append(o.LogFile, opt.LogFile...)
|
||||||
|
} else {
|
||||||
|
o.LogFile = opt.LogFile
|
||||||
|
}
|
||||||
|
|
||||||
|
if opt.LogSyslogExtend {
|
||||||
|
o.LogSyslog = append(o.LogSyslog, opt.LogSyslog...)
|
||||||
|
} else {
|
||||||
|
o.LogSyslog = opt.LogSyslog
|
||||||
|
}
|
||||||
|
|
||||||
|
if opt.opts != nil {
|
||||||
|
o.opts = opt.opts
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *Options) Options() *Options {
|
||||||
|
var no Options
|
||||||
|
|
||||||
|
if o.opts != nil && o.InheritDefault {
|
||||||
|
no = *o.opts()
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(o.TraceFilter) > 0 {
|
||||||
|
no.TraceFilter = o.TraceFilter
|
||||||
|
}
|
||||||
|
|
||||||
|
if o.Stdout != nil {
|
||||||
|
if no.Stdout == nil {
|
||||||
|
no.Stdout = &OptionsStd{}
|
||||||
|
}
|
||||||
|
if o.Stdout.DisableStandard {
|
||||||
|
no.Stdout.DisableStandard = o.Stdout.DisableStandard
|
||||||
|
}
|
||||||
|
if o.Stdout.DisableColor {
|
||||||
|
no.Stdout.DisableColor = o.Stdout.DisableColor
|
||||||
|
}
|
||||||
|
if o.Stdout.DisableTimestamp {
|
||||||
|
no.Stdout.DisableTimestamp = o.Stdout.DisableTimestamp
|
||||||
|
}
|
||||||
|
if o.Stdout.DisableStack {
|
||||||
|
no.Stdout.DisableStack = o.Stdout.DisableStack
|
||||||
|
}
|
||||||
|
if o.Stdout.EnableTrace {
|
||||||
|
no.Stdout.EnableTrace = o.Stdout.EnableTrace
|
||||||
|
}
|
||||||
|
if o.Stdout.EnableAccessLog {
|
||||||
|
no.Stdout.EnableAccessLog = o.Stdout.EnableAccessLog
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if o.LogFileExtend {
|
||||||
|
no.LogFile = append(no.LogFile, o.LogFile...)
|
||||||
|
} else {
|
||||||
|
no.LogFile = o.LogFile
|
||||||
|
}
|
||||||
|
|
||||||
|
if o.LogSyslogExtend {
|
||||||
|
no.LogSyslog = append(no.LogSyslog, o.LogSyslog...)
|
||||||
|
} else {
|
||||||
|
no.LogSyslog = o.LogSyslog
|
||||||
|
}
|
||||||
|
|
||||||
|
return &no
|
||||||
|
}
|
||||||
87
logger/config/optionsFile.go
Normal file
87
logger/config/optionsFile.go
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
/***********************************************************************************************************************
|
||||||
|
*
|
||||||
|
* 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 config
|
||||||
|
|
||||||
|
import "os"
|
||||||
|
|
||||||
|
type OptionsFile struct {
|
||||||
|
// LogLevel define the allowed level of log for this file.
|
||||||
|
LogLevel []string `json:"logLevel,omitempty" yaml:"logLevel,omitempty" toml:"logLevel,omitempty" mapstructure:"logLevel,omitempty"`
|
||||||
|
|
||||||
|
// Filepath define the file path for log to file.
|
||||||
|
Filepath string `json:"filepath,omitempty" yaml:"filepath,omitempty" toml:"filepath,omitempty" mapstructure:"filepath,omitempty"`
|
||||||
|
|
||||||
|
// Create define if the log file must exist or can create it.
|
||||||
|
Create bool `json:"create,omitempty" yaml:"create,omitempty" toml:"create,omitempty" mapstructure:"create,omitempty"`
|
||||||
|
|
||||||
|
// CreatePath define if the path of the log file must exist or can try to create it.
|
||||||
|
CreatePath bool `json:"createPath,omitempty" yaml:"createPath,omitempty" toml:"createPath,omitempty" mapstructure:"createPath,omitempty"`
|
||||||
|
|
||||||
|
// FileMode define mode to be used for the log file if the create it.
|
||||||
|
FileMode os.FileMode `json:"fileMode,omitempty" yaml:"fileMode,omitempty" toml:"fileMode,omitempty" mapstructure:"fileMode,omitempty"`
|
||||||
|
|
||||||
|
// PathMode define mode to be used for the path of the log file if create it.
|
||||||
|
PathMode os.FileMode `json:"pathMode,omitempty" yaml:"pathMode,omitempty" toml:"pathMode,omitempty" mapstructure:"pathMode,omitempty"`
|
||||||
|
|
||||||
|
// DisableStack allow to disable the goroutine id before each message.
|
||||||
|
DisableStack bool `json:"disableStack,omitempty" yaml:"disableStack,omitempty" toml:"disableStack,omitempty" mapstructure:"disableStack,omitempty"`
|
||||||
|
|
||||||
|
// DisableTimestamp allow to disable the timestamp before each message.
|
||||||
|
DisableTimestamp bool `json:"disableTimestamp,omitempty" yaml:"disableTimestamp,omitempty" toml:"disableTimestamp,omitempty" mapstructure:"disableTimestamp,omitempty"`
|
||||||
|
|
||||||
|
// EnableTrace allow to add the origin caller/file/line of each message.
|
||||||
|
EnableTrace bool `json:"enableTrace,omitempty" yaml:"enableTrace,omitempty" toml:"enableTrace,omitempty" mapstructure:"enableTrace,omitempty"`
|
||||||
|
|
||||||
|
// EnableAccessLog allow to add all message from api router for access log and error log.
|
||||||
|
EnableAccessLog bool `json:"enableAccessLog,omitempty" yaml:"enableAccessLog,omitempty" toml:"enableAccessLog,omitempty" mapstructure:"enableAccessLog,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type OptionsFiles []OptionsFile
|
||||||
|
|
||||||
|
func (o OptionsFile) Clone() OptionsFile {
|
||||||
|
return OptionsFile{
|
||||||
|
LogLevel: o.LogLevel,
|
||||||
|
Filepath: o.Filepath,
|
||||||
|
Create: o.Create,
|
||||||
|
CreatePath: o.CreatePath,
|
||||||
|
FileMode: o.FileMode,
|
||||||
|
PathMode: o.PathMode,
|
||||||
|
DisableStack: o.DisableStack,
|
||||||
|
DisableTimestamp: o.DisableTimestamp,
|
||||||
|
EnableTrace: o.EnableTrace,
|
||||||
|
EnableAccessLog: o.EnableAccessLog,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o OptionsFiles) Clone() OptionsFiles {
|
||||||
|
var c = make([]OptionsFile, 0)
|
||||||
|
for _, i := range o {
|
||||||
|
c = append(c, i.Clone())
|
||||||
|
}
|
||||||
|
return c
|
||||||
|
}
|
||||||
60
logger/config/optionsStd.go
Normal file
60
logger/config/optionsStd.go
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
/***********************************************************************************************************************
|
||||||
|
*
|
||||||
|
* 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 config
|
||||||
|
|
||||||
|
type OptionsStd struct {
|
||||||
|
// DisableStandard allow disabling to write log to standard output stdout/stderr.
|
||||||
|
DisableStandard bool `json:"disableStandard,omitempty" yaml:"disableStandard,omitempty" toml:"disableStandard,omitempty" mapstructure:"disableStandard,omitempty"`
|
||||||
|
|
||||||
|
// DisableStack allow to disable the goroutine id before each message.
|
||||||
|
DisableStack bool `json:"disableStack,omitempty" yaml:"disableStack,omitempty" toml:"disableStack,omitempty" mapstructure:"disableStack,omitempty"`
|
||||||
|
|
||||||
|
// DisableTimestamp allow to disable the timestamp before each message.
|
||||||
|
DisableTimestamp bool `json:"disableTimestamp,omitempty" yaml:"disableTimestamp,omitempty" toml:"disableTimestamp,omitempty" mapstructure:"disableTimestamp,omitempty"`
|
||||||
|
|
||||||
|
// EnableTrace allow to add the origin caller/file/line of each message.
|
||||||
|
EnableTrace bool `json:"enableTrace,omitempty" yaml:"enableTrace,omitempty" toml:"enableTrace,omitempty" mapstructure:"enableTrace,omitempty"`
|
||||||
|
|
||||||
|
// DisableColor define if color could be use or not in messages format.
|
||||||
|
// If the running process is not a tty, no color will be used.
|
||||||
|
DisableColor bool `json:"disableColor,omitempty" yaml:"disableColor,omitempty" toml:"disableColor,omitempty" mapstructure:"disableColor,omitempty"`
|
||||||
|
|
||||||
|
// EnableAccessLog allow to add all message from api router for access log and error log.
|
||||||
|
EnableAccessLog bool `json:"enableAccessLog,omitempty" yaml:"enableAccessLog,omitempty" toml:"enableAccessLog,omitempty" mapstructure:"enableAccessLog,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *OptionsStd) Clone() *OptionsStd {
|
||||||
|
return &OptionsStd{
|
||||||
|
DisableStandard: o.DisableStandard,
|
||||||
|
DisableStack: o.DisableStack,
|
||||||
|
DisableTimestamp: o.DisableTimestamp,
|
||||||
|
EnableTrace: o.EnableTrace,
|
||||||
|
DisableColor: o.DisableColor,
|
||||||
|
EnableAccessLog: o.EnableAccessLog,
|
||||||
|
}
|
||||||
|
}
|
||||||
86
logger/config/optionsSyslog.go
Normal file
86
logger/config/optionsSyslog.go
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
/***********************************************************************************************************************
|
||||||
|
*
|
||||||
|
* 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 config
|
||||||
|
|
||||||
|
type OptionsSyslog struct {
|
||||||
|
// LogLevel define the allowed level of log for this syslog.
|
||||||
|
LogLevel []string `json:"logLevel,omitempty" yaml:"logLevel,omitempty" toml:"logLevel,omitempty" mapstructure:"logLevel,omitempty"`
|
||||||
|
|
||||||
|
// Network define the network used to connect to this syslog (tcp, udp, or any other to a local connection).
|
||||||
|
Network string `json:"network,omitempty" yaml:"network,omitempty" toml:"network,omitempty" mapstructure:"network,omitempty"`
|
||||||
|
|
||||||
|
// Host define the remote syslog to use.
|
||||||
|
// If Host and Network are empty, local syslog will be used.
|
||||||
|
Host string `json:"host,omitempty" yaml:"host,omitempty" toml:"host,omitempty" mapstructure:"host,omitempty"`
|
||||||
|
/*
|
||||||
|
// Severity define the severity syslog to be used.
|
||||||
|
Severity string `json:"severity,omitempty" yaml:"severity,omitempty" toml:"severity,omitempty" mapstructure:"severity,omitempty"`
|
||||||
|
*/
|
||||||
|
// Facility define the facility syslog to be used.
|
||||||
|
Facility string `json:"facility,omitempty" yaml:"facility,omitempty" toml:"facility,omitempty" mapstructure:"facility,omitempty"`
|
||||||
|
|
||||||
|
// Tag define the syslog tag used in linux syslog system or name of logger for windows event logger.
|
||||||
|
// For window, this value must be unic for each syslog config
|
||||||
|
Tag string `json:"tag,omitempty" yaml:"tag,omitempty" toml:"tag,omitempty" mapstructure:"tag,omitempty"`
|
||||||
|
|
||||||
|
// DisableStack allow to disable the goroutine id before each message.
|
||||||
|
DisableStack bool `json:"disableStack,omitempty" yaml:"disableStack,omitempty" toml:"disableStack,omitempty" mapstructure:"disableStack,omitempty"`
|
||||||
|
|
||||||
|
// DisableTimestamp allow to disable the timestamp before each message.
|
||||||
|
DisableTimestamp bool `json:"disableTimestamp,omitempty" yaml:"disableTimestamp,omitempty" toml:"disableTimestamp,omitempty" mapstructure:"disableTimestamp,omitempty"`
|
||||||
|
|
||||||
|
// EnableTrace allow to add the origin caller/file/line of each message.
|
||||||
|
EnableTrace bool `json:"enableTrace,omitempty" yaml:"enableTrace,omitempty" toml:"enableTrace,omitempty" mapstructure:"enableTrace,omitempty"`
|
||||||
|
|
||||||
|
// EnableAccessLog allow to add all message from api router for access log and error log.
|
||||||
|
EnableAccessLog bool `json:"enableAccessLog,omitempty" yaml:"enableAccessLog,omitempty" toml:"enableAccessLog,omitempty" mapstructure:"enableAccessLog,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type OptionsSyslogs []OptionsSyslog
|
||||||
|
|
||||||
|
func (o OptionsSyslog) Clone() OptionsSyslog {
|
||||||
|
return OptionsSyslog{
|
||||||
|
LogLevel: o.LogLevel,
|
||||||
|
Network: o.Network,
|
||||||
|
Host: o.Host,
|
||||||
|
Facility: o.Facility,
|
||||||
|
Tag: o.Tag,
|
||||||
|
DisableStack: o.DisableStack,
|
||||||
|
DisableTimestamp: o.DisableTimestamp,
|
||||||
|
EnableTrace: o.EnableTrace,
|
||||||
|
EnableAccessLog: o.EnableAccessLog,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o OptionsSyslogs) Clone() OptionsSyslogs {
|
||||||
|
var c = make([]OptionsSyslog, 0)
|
||||||
|
for _, i := range o {
|
||||||
|
c = append(c, i.Clone())
|
||||||
|
}
|
||||||
|
return c
|
||||||
|
}
|
||||||
68
logger/entry/errors.go
Normal file
68
logger/entry/errors.go
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
/***********************************************************************************************************************
|
||||||
|
*
|
||||||
|
* 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 entry
|
||||||
|
|
||||||
|
import (
|
||||||
|
liberr "github.com/nabbar/golib/errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (e *entry) ErrorClean() Entry {
|
||||||
|
e.Error = make([]error, 0)
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *entry) ErrorSet(err []error) Entry {
|
||||||
|
if len(err) < 1 {
|
||||||
|
err = make([]error, 0)
|
||||||
|
}
|
||||||
|
e.Error = err
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *entry) ErrorAdd(cleanNil bool, err ...error) Entry {
|
||||||
|
if len(e.Error) < 1 {
|
||||||
|
e.Error = make([]error, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, er := range err {
|
||||||
|
if cleanNil && er == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
e.Error = append(e.Error, er)
|
||||||
|
}
|
||||||
|
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *entry) ErrorAddLib(cleanNil bool, err ...liberr.Error) Entry {
|
||||||
|
for _, er := range err {
|
||||||
|
e.ErrorAdd(cleanNil, er.GetErrorSlice()...)
|
||||||
|
}
|
||||||
|
|
||||||
|
return e
|
||||||
|
}
|
||||||
58
logger/entry/field.go
Normal file
58
logger/entry/field.go
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
/***********************************************************************************************************************
|
||||||
|
*
|
||||||
|
* 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 entry
|
||||||
|
|
||||||
|
import (
|
||||||
|
logfld "github.com/nabbar/golib/logger/fields"
|
||||||
|
)
|
||||||
|
|
||||||
|
// FieldAdd allow to add one couple key/val as type string/interface into the custom field of the entry.
|
||||||
|
func (e *entry) FieldAdd(key string, val interface{}) Entry {
|
||||||
|
e.Fields.Add(key, val)
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
// FieldMerge allow to merge a Field pointer into the custom field of the entry.
|
||||||
|
func (e *entry) FieldMerge(fields logfld.Fields) Entry {
|
||||||
|
e.Fields.Merge(fields)
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
// FieldSet allow to change the custom field of the entry with the given Fields in parameter.
|
||||||
|
func (e *entry) FieldSet(fields logfld.Fields) Entry {
|
||||||
|
e.Fields = fields
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *entry) FieldClean(keys ...string) Entry {
|
||||||
|
for _, k := range keys {
|
||||||
|
e.Fields.Delete(k)
|
||||||
|
}
|
||||||
|
|
||||||
|
return e
|
||||||
|
}
|
||||||
73
logger/entry/interface.go
Normal file
73
logger/entry/interface.go
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
/***********************************************************************************************************************
|
||||||
|
*
|
||||||
|
* 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 entry
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
ginsdk "github.com/gin-gonic/gin"
|
||||||
|
liberr "github.com/nabbar/golib/errors"
|
||||||
|
logfld "github.com/nabbar/golib/logger/fields"
|
||||||
|
loglvl "github.com/nabbar/golib/logger/level"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Entry interface {
|
||||||
|
SetLogger(fct func() *logrus.Logger) Entry
|
||||||
|
SetLevel(lvl loglvl.Level) Entry
|
||||||
|
SetMessageOnly(flag bool) Entry
|
||||||
|
SetEntryContext(etime time.Time, stack uint64, caller, file string, line uint64, msg string) Entry
|
||||||
|
SetGinContext(ctx *ginsdk.Context) Entry
|
||||||
|
|
||||||
|
DataSet(data interface{}) Entry
|
||||||
|
Check(lvlNoErr loglvl.Level) bool
|
||||||
|
Log()
|
||||||
|
|
||||||
|
FieldAdd(key string, val interface{}) Entry
|
||||||
|
FieldMerge(fields logfld.Fields) Entry
|
||||||
|
FieldSet(fields logfld.Fields) Entry
|
||||||
|
FieldClean(keys ...string) Entry
|
||||||
|
|
||||||
|
ErrorClean() Entry
|
||||||
|
ErrorSet(err []error) Entry
|
||||||
|
ErrorAdd(cleanNil bool, err ...error) Entry
|
||||||
|
ErrorAddLib(cleanNil bool, err ...liberr.Error) Entry
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(lvl loglvl.Level) Entry {
|
||||||
|
return &entry{
|
||||||
|
log: nil,
|
||||||
|
gin: nil,
|
||||||
|
clean: false,
|
||||||
|
Level: lvl,
|
||||||
|
Time: time.Now(),
|
||||||
|
Error: make([]error, 0),
|
||||||
|
Data: nil,
|
||||||
|
Fields: nil,
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -25,41 +25,30 @@
|
|||||||
*
|
*
|
||||||
**********************************************************************************************************************/
|
**********************************************************************************************************************/
|
||||||
|
|
||||||
package logger
|
package entry
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
ginsdk "github.com/gin-gonic/gin"
|
||||||
|
logfld "github.com/nabbar/golib/logger/fields"
|
||||||
liberr "github.com/nabbar/golib/errors"
|
loglvl "github.com/nabbar/golib/logger/level"
|
||||||
|
logtps "github.com/nabbar/golib/logger/types"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
type entry struct {
|
||||||
FieldTime = "time"
|
|
||||||
FieldLevel = "level"
|
|
||||||
FieldStack = "stack"
|
|
||||||
FieldCaller = "caller"
|
|
||||||
FieldFile = "file"
|
|
||||||
FieldLine = "line"
|
|
||||||
FieldMessage = "message"
|
|
||||||
FieldError = "error"
|
|
||||||
FieldData = "data"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Entry struct {
|
|
||||||
log func() *logrus.Logger
|
log func() *logrus.Logger
|
||||||
gin *gin.Context
|
gin *ginsdk.Context
|
||||||
clean bool
|
clean bool
|
||||||
|
|
||||||
//Time is the time of the event (can be empty time if disabled timestamp)
|
//Time is the time of the event (can be empty time if disabled timestamp)
|
||||||
Time time.Time `json:"time"`
|
Time time.Time `json:"time"`
|
||||||
|
|
||||||
//Level define the level of the entry (cannot be empty or nil)
|
//Level define the level of the entry (cannot be empty or nil)
|
||||||
Level Level `json:"level"`
|
Level loglvl.Level `json:"level"`
|
||||||
|
|
||||||
//Stack define the process goroutine number (can be 0 if disabled)
|
//Stack define the process goroutine number (can be 0 if disabled)
|
||||||
Stack uint64 `json:"stack"`
|
Stack uint64 `json:"stack"`
|
||||||
@@ -71,7 +60,7 @@ type Entry struct {
|
|||||||
File string `json:"file"`
|
File string `json:"file"`
|
||||||
|
|
||||||
//Caller define the line in file caller of the entry (can be 0 if trace disabled, not found or anonymous function)
|
//Caller define the line in file caller of the entry (can be 0 if trace disabled, not found or anonymous function)
|
||||||
Line uint32 `json:"line"`
|
Line uint64 `json:"line"`
|
||||||
|
|
||||||
//Message define the main message of the entry (can be empty)
|
//Message define the main message of the entry (can be empty)
|
||||||
Message string `json:"message"`
|
Message string `json:"message"`
|
||||||
@@ -83,74 +72,46 @@ type Entry struct {
|
|||||||
Data interface{} `json:"data"`
|
Data interface{} `json:"data"`
|
||||||
|
|
||||||
//Fields are a list of custom information to add to log entry (can be nil or can overwrite Entry values)
|
//Fields are a list of custom information to add to log entry (can be nil or can overwrite Entry values)
|
||||||
Fields Fields `json:"fields"`
|
Fields logfld.Fields `json:"fields"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *entry) SetEntryContext(etime time.Time, stack uint64, caller, file string, line uint64, msg string) Entry {
|
||||||
|
e.Time = etime
|
||||||
|
e.Stack = stack
|
||||||
|
e.Caller = caller
|
||||||
|
e.File = file
|
||||||
|
e.Line = line
|
||||||
|
e.Message = msg
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *entry) SetMessageOnly(flag bool) Entry {
|
||||||
|
e.clean = flag
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *entry) SetLevel(lvl loglvl.Level) Entry {
|
||||||
|
e.Level = lvl
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *entry) SetLogger(fct func() *logrus.Logger) Entry {
|
||||||
|
e.log = fct
|
||||||
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetGinContext allow to register a gin context pointer to register the errors of the current entry intro gin Context Error Slice.
|
// SetGinContext allow to register a gin context pointer to register the errors of the current entry intro gin Context Error Slice.
|
||||||
func (e *Entry) SetGinContext(ctx *gin.Context) *Entry {
|
func (e *entry) SetGinContext(ctx *ginsdk.Context) Entry {
|
||||||
e.gin = ctx
|
e.gin = ctx
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
// FieldAdd allow to add one couple key/val as type string/interface into the custom field of the entry.
|
func (e *entry) DataSet(data interface{}) Entry {
|
||||||
func (e *Entry) FieldAdd(key string, val interface{}) *Entry {
|
|
||||||
e.Fields.Add(key, val)
|
|
||||||
return e
|
|
||||||
}
|
|
||||||
|
|
||||||
// FieldMerge allow to merge a Field pointer into the custom field of the entry.
|
|
||||||
func (e *Entry) FieldMerge(fields Fields) *Entry {
|
|
||||||
e.Fields.Merge(fields)
|
|
||||||
return e
|
|
||||||
}
|
|
||||||
|
|
||||||
// FieldSet allow to change the custom field of the entry with the given Fields in parameter.
|
|
||||||
func (e *Entry) FieldSet(fields Fields) *Entry {
|
|
||||||
e.Fields = fields
|
|
||||||
return e
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *Entry) FieldClean(keys ...string) *Entry {
|
|
||||||
for _, k := range keys {
|
|
||||||
e.Fields.Delete(k)
|
|
||||||
}
|
|
||||||
|
|
||||||
return e
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *Entry) DataSet(data interface{}) *Entry {
|
|
||||||
e.Data = data
|
e.Data = data
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Entry) ErrorClean() *Entry {
|
func (e *entry) Check(lvlNoErr loglvl.Level) bool {
|
||||||
e.Error = make([]error, 0)
|
|
||||||
return e
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *Entry) ErrorSet(err []error) *Entry {
|
|
||||||
e.Error = err
|
|
||||||
return e
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *Entry) ErrorAdd(cleanNil bool, err ...error) *Entry {
|
|
||||||
for _, er := range err {
|
|
||||||
if cleanNil && er == nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
e.Error = append(e.Error, er)
|
|
||||||
}
|
|
||||||
return e
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *Entry) ErrorAddLib(cleanNil bool, err ...liberr.Error) *Entry {
|
|
||||||
for _, er := range err {
|
|
||||||
e.ErrorAdd(cleanNil, er.GetErrorSlice()...)
|
|
||||||
}
|
|
||||||
return e
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *Entry) Check(lvlNoErr Level) bool {
|
|
||||||
var found = false
|
var found = false
|
||||||
if len(e.Error) > 0 {
|
if len(e.Error) > 0 {
|
||||||
for _, er := range e.Error {
|
for _, er := range e.Error {
|
||||||
@@ -171,21 +132,7 @@ func (e *Entry) Check(lvlNoErr Level) bool {
|
|||||||
return found
|
return found
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Entry) _logClean() {
|
func (e *entry) Log() {
|
||||||
var (
|
|
||||||
log *logrus.Logger
|
|
||||||
)
|
|
||||||
|
|
||||||
if e.log == nil {
|
|
||||||
return
|
|
||||||
} else if log = e.log(); log == nil {
|
|
||||||
return
|
|
||||||
} else {
|
|
||||||
log.Info(e.Message)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *Entry) Log() {
|
|
||||||
if e == nil {
|
if e == nil {
|
||||||
return
|
return
|
||||||
} else if e.Fields == nil {
|
} else if e.Fields == nil {
|
||||||
@@ -201,36 +148,36 @@ func (e *Entry) Log() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if e.Level == NilLevel {
|
if e.Level == loglvl.NilLevel {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ent *logrus.Entry
|
ent *logrus.Entry
|
||||||
tag = NewFields(e.Fields.GetContext).Add(FieldLevel, e.Level.String())
|
tag = logfld.New(e.Fields.GetContext).Add(logtps.FieldLevel, e.Level.String())
|
||||||
log *logrus.Logger
|
log *logrus.Logger
|
||||||
)
|
)
|
||||||
|
|
||||||
if !e.Time.IsZero() {
|
if !e.Time.IsZero() {
|
||||||
tag = tag.Add(FieldTime, e.Time.Format(time.RFC3339Nano))
|
tag = tag.Add(logtps.FieldTime, e.Time.Format(time.RFC3339Nano))
|
||||||
}
|
}
|
||||||
|
|
||||||
if e.Stack > 0 {
|
if e.Stack > 0 {
|
||||||
tag = tag.Add(FieldStack, e.Stack)
|
tag = tag.Add(logtps.FieldStack, e.Stack)
|
||||||
}
|
}
|
||||||
|
|
||||||
if e.Caller != "" {
|
if e.Caller != "" {
|
||||||
tag = tag.Add(FieldCaller, e.Caller)
|
tag = tag.Add(logtps.FieldCaller, e.Caller)
|
||||||
} else if e.File != "" {
|
} else if e.File != "" {
|
||||||
tag = tag.Add(FieldFile, e.File)
|
tag = tag.Add(logtps.FieldFile, e.File)
|
||||||
}
|
}
|
||||||
|
|
||||||
if e.Line > 0 {
|
if e.Line > 0 {
|
||||||
tag = tag.Add(FieldLine, e.Line)
|
tag = tag.Add(logtps.FieldLine, e.Line)
|
||||||
}
|
}
|
||||||
|
|
||||||
if e.Message != "" {
|
if e.Message != "" {
|
||||||
tag = tag.Add(FieldMessage, e.Message)
|
tag = tag.Add(logtps.FieldMessage, e.Message)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(e.Error) > 0 {
|
if len(e.Error) > 0 {
|
||||||
@@ -243,11 +190,11 @@ func (e *Entry) Log() {
|
|||||||
msg = append(msg, er.Error())
|
msg = append(msg, er.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
tag = tag.Add(FieldError, strings.Join(msg, ", "))
|
tag = tag.Add(logtps.FieldError, strings.Join(msg, ", "))
|
||||||
}
|
}
|
||||||
|
|
||||||
if e.Data != nil {
|
if e.Data != nil {
|
||||||
tag = tag.Add(FieldData, e.Data)
|
tag = tag.Add(logtps.FieldData, e.Data)
|
||||||
}
|
}
|
||||||
|
|
||||||
tag.Merge(e.Fields)
|
tag.Merge(e.Fields)
|
||||||
@@ -262,7 +209,22 @@ func (e *Entry) Log() {
|
|||||||
|
|
||||||
ent.Log(e.Level.Logrus())
|
ent.Log(e.Level.Logrus())
|
||||||
|
|
||||||
if e.Level <= FatalLevel {
|
if e.Level <= loglvl.FatalLevel {
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *entry) _logClean() {
|
||||||
|
var (
|
||||||
|
log *logrus.Logger
|
||||||
|
)
|
||||||
|
|
||||||
|
if e.log == nil {
|
||||||
|
return
|
||||||
|
} else if log = e.log(); log == nil {
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
//log.SetLevel(logrus.InfoLevel)
|
||||||
|
log.Info(e.Message)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
/*
|
|
||||||
* MIT License
|
|
||||||
*
|
|
||||||
* Copyright (c) 2020 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"
|
|
||||||
|
|
||||||
liberr "github.com/nabbar/golib/errors"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
ErrorParamEmpty liberr.CodeError = iota + liberr.MinPkgLogger
|
|
||||||
ErrorValidatorError
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
if liberr.ExistInMapMessage(ErrorParamEmpty) {
|
|
||||||
panic(fmt.Errorf("error code collision with package golib/logger"))
|
|
||||||
}
|
|
||||||
liberr.RegisterIdFctMessage(ErrorParamEmpty, getMessage)
|
|
||||||
}
|
|
||||||
|
|
||||||
func getMessage(code liberr.CodeError) (message string) {
|
|
||||||
switch code {
|
|
||||||
case ErrorParamEmpty:
|
|
||||||
return "given parameters is empty"
|
|
||||||
case ErrorValidatorError:
|
|
||||||
return "logger : invalid config"
|
|
||||||
}
|
|
||||||
|
|
||||||
return liberr.NullMessage
|
|
||||||
}
|
|
||||||
53
logger/fields/interface.go
Normal file
53
logger/fields/interface.go
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
/***********************************************************************************************************************
|
||||||
|
*
|
||||||
|
* 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 fields
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
|
||||||
|
libctx "github.com/nabbar/golib/context"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Fields interface {
|
||||||
|
libctx.Config[string]
|
||||||
|
json.Marshaler
|
||||||
|
json.Unmarshaler
|
||||||
|
|
||||||
|
FieldsClone(ctx context.Context) Fields
|
||||||
|
Add(key string, val interface{}) Fields
|
||||||
|
Logrus() logrus.Fields
|
||||||
|
Map(fct func(key string, val interface{}) interface{}) Fields
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(ctx libctx.FuncContext) Fields {
|
||||||
|
return &fldModel{
|
||||||
|
libctx.NewConfig[string](ctx),
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
*
|
*
|
||||||
**********************************************************************************************************************/
|
**********************************************************************************************************************/
|
||||||
|
|
||||||
package logger
|
package fields
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
@@ -35,23 +35,6 @@ import (
|
|||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Fields interface {
|
|
||||||
libctx.Config[string]
|
|
||||||
json.Marshaler
|
|
||||||
json.Unmarshaler
|
|
||||||
|
|
||||||
FieldsClone(ctx context.Context) Fields
|
|
||||||
Add(key string, val interface{}) Fields
|
|
||||||
Logrus() logrus.Fields
|
|
||||||
Map(fct func(key string, val interface{}) interface{}) Fields
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewFields(ctx libctx.FuncContext) Fields {
|
|
||||||
return &fldModel{
|
|
||||||
libctx.NewConfig[string](ctx),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type fldModel struct {
|
type fldModel struct {
|
||||||
libctx.Config[string]
|
libctx.Config[string]
|
||||||
}
|
}
|
||||||
@@ -28,79 +28,19 @@
|
|||||||
package logger
|
package logger
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io"
|
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
"github.com/hashicorp/go-hclog"
|
loglvl "github.com/nabbar/golib/logger/level"
|
||||||
jww "github.com/spf13/jwalterweatherman"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func (o *logger) GetStdLogger(lvl Level, logFlags int) *log.Logger {
|
func (o *logger) GetStdLogger(lvl loglvl.Level, logFlags int) *log.Logger {
|
||||||
o.SetIOWriterLevel(lvl)
|
o.SetIOWriterLevel(lvl)
|
||||||
return log.New(o, "", logFlags)
|
return log.New(o, "", logFlags)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *logger) SetStdLogger(lvl Level, logFlags int) {
|
func (o *logger) SetStdLogger(lvl loglvl.Level, logFlags int) {
|
||||||
o.SetIOWriterLevel(lvl)
|
o.SetIOWriterLevel(lvl)
|
||||||
log.SetOutput(o)
|
log.SetOutput(o)
|
||||||
log.SetPrefix("")
|
log.SetPrefix("")
|
||||||
log.SetFlags(logFlags)
|
log.SetFlags(logFlags)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *logger) SetSPF13Level(lvl Level, log *jww.Notepad) {
|
|
||||||
var (
|
|
||||||
fOutLog func(handle io.Writer)
|
|
||||||
fLvl func(threshold jww.Threshold)
|
|
||||||
)
|
|
||||||
|
|
||||||
if log == nil {
|
|
||||||
jww.SetStdoutOutput(io.Discard)
|
|
||||||
fOutLog = jww.SetLogOutput
|
|
||||||
fLvl = jww.SetLogThreshold
|
|
||||||
} else {
|
|
||||||
fOutLog = log.SetLogOutput
|
|
||||||
fLvl = log.SetLogThreshold
|
|
||||||
}
|
|
||||||
|
|
||||||
switch lvl {
|
|
||||||
case NilLevel:
|
|
||||||
fOutLog(io.Discard)
|
|
||||||
fLvl(jww.LevelCritical)
|
|
||||||
|
|
||||||
case DebugLevel:
|
|
||||||
fOutLog(o)
|
|
||||||
if opt := o.GetOptions(); opt.EnableTrace {
|
|
||||||
fLvl(jww.LevelTrace)
|
|
||||||
} else {
|
|
||||||
fLvl(jww.LevelDebug)
|
|
||||||
}
|
|
||||||
|
|
||||||
case InfoLevel:
|
|
||||||
fOutLog(o)
|
|
||||||
fLvl(jww.LevelInfo)
|
|
||||||
case WarnLevel:
|
|
||||||
fOutLog(o)
|
|
||||||
fLvl(jww.LevelWarn)
|
|
||||||
case ErrorLevel:
|
|
||||||
fOutLog(o)
|
|
||||||
fLvl(jww.LevelError)
|
|
||||||
case FatalLevel:
|
|
||||||
fOutLog(o)
|
|
||||||
fLvl(jww.LevelFatal)
|
|
||||||
case PanicLevel:
|
|
||||||
fOutLog(o)
|
|
||||||
fLvl(jww.LevelCritical)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o *logger) SetHashicorpHCLog() {
|
|
||||||
hclog.SetDefault(&_hclog{
|
|
||||||
l: o,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o *logger) NewHashicorpHCLog() hclog.Logger {
|
|
||||||
return &_hclog{
|
|
||||||
l: o,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
106
logger/gorm.go
106
logger/gorm.go
@@ -1,106 +0,0 @@
|
|||||||
/*
|
|
||||||
* MIT License
|
|
||||||
*
|
|
||||||
* Copyright (c) 2022 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 (
|
|
||||||
"context"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
gorlog "gorm.io/gorm/logger"
|
|
||||||
)
|
|
||||||
|
|
||||||
type logGorm struct {
|
|
||||||
i bool
|
|
||||||
s time.Duration
|
|
||||||
l func() Logger
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewGormLogger(fct func() Logger, ignoreRecordNotFoundError bool, slowThreshold time.Duration) gorlog.Interface {
|
|
||||||
return &logGorm{
|
|
||||||
i: ignoreRecordNotFoundError,
|
|
||||||
s: slowThreshold,
|
|
||||||
l: fct,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *logGorm) LogMode(level gorlog.LogLevel) gorlog.Interface {
|
|
||||||
switch level {
|
|
||||||
case gorlog.Silent:
|
|
||||||
l.l().SetLevel(NilLevel)
|
|
||||||
case gorlog.Info:
|
|
||||||
l.l().SetLevel(InfoLevel)
|
|
||||||
case gorlog.Warn:
|
|
||||||
l.l().SetLevel(WarnLevel)
|
|
||||||
case gorlog.Error:
|
|
||||||
l.l().SetLevel(ErrorLevel)
|
|
||||||
}
|
|
||||||
|
|
||||||
return l
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *logGorm) Info(ctx context.Context, s string, i ...interface{}) {
|
|
||||||
l.l().Entry(InfoLevel, s, i...).Log()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *logGorm) Warn(ctx context.Context, s string, i ...interface{}) {
|
|
||||||
l.l().Entry(WarnLevel, s, i...).Log()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *logGorm) Error(ctx context.Context, s string, i ...interface{}) {
|
|
||||||
l.l().Entry(ErrorLevel, s, i...).Log()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *logGorm) Trace(ctx context.Context, begin time.Time, fc func() (sql string, rowsAffected int64), err error) {
|
|
||||||
var e *Entry
|
|
||||||
elapsed := time.Since(begin)
|
|
||||||
|
|
||||||
switch {
|
|
||||||
case err != nil && (!errors.Is(err, gorlog.ErrRecordNotFound) || !l.i):
|
|
||||||
e = l.l().Entry(ErrorLevel, "database error with trace")
|
|
||||||
e.ErrorAdd(true, err)
|
|
||||||
case elapsed > l.s && l.s != 0:
|
|
||||||
e = l.l().Entry(WarnLevel, "database warning with trace")
|
|
||||||
e.ErrorAdd(true, fmt.Errorf("SLOW Query >= %v", l.s))
|
|
||||||
default:
|
|
||||||
e = l.l().Entry(InfoLevel, "database trace")
|
|
||||||
}
|
|
||||||
|
|
||||||
e.FieldAdd("elapsed ms", float64(elapsed.Nanoseconds())/1e6)
|
|
||||||
|
|
||||||
sql, rows := fc()
|
|
||||||
if rows == -1 {
|
|
||||||
e.FieldAdd("rows", "-")
|
|
||||||
e.FieldAdd("query", sql)
|
|
||||||
} else {
|
|
||||||
e.FieldAdd("rows", rows)
|
|
||||||
e.FieldAdd("query", sql)
|
|
||||||
}
|
|
||||||
|
|
||||||
e.Log()
|
|
||||||
}
|
|
||||||
43
logger/gorm/interface.go
Normal file
43
logger/gorm/interface.go
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
/***********************************************************************************************************************
|
||||||
|
*
|
||||||
|
* 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 gorm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
liblog "github.com/nabbar/golib/logger"
|
||||||
|
gorlog "gorm.io/gorm/logger"
|
||||||
|
)
|
||||||
|
|
||||||
|
func New(fct func() liblog.Logger, ignoreRecordNotFoundError bool, slowThreshold time.Duration) gorlog.Interface {
|
||||||
|
return &logGorm{
|
||||||
|
i: ignoreRecordNotFoundError,
|
||||||
|
s: slowThreshold,
|
||||||
|
l: fct,
|
||||||
|
}
|
||||||
|
}
|
||||||
102
logger/gorm/model.go
Normal file
102
logger/gorm/model.go
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
/***********************************************************************************************************************
|
||||||
|
*
|
||||||
|
* 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 gorm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
liblog "github.com/nabbar/golib/logger"
|
||||||
|
logent "github.com/nabbar/golib/logger/entry"
|
||||||
|
loglvl "github.com/nabbar/golib/logger/level"
|
||||||
|
gorlog "gorm.io/gorm/logger"
|
||||||
|
)
|
||||||
|
|
||||||
|
type logGorm struct {
|
||||||
|
i bool
|
||||||
|
s time.Duration
|
||||||
|
l func() liblog.Logger
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *logGorm) LogMode(level gorlog.LogLevel) gorlog.Interface {
|
||||||
|
switch level {
|
||||||
|
case gorlog.Silent:
|
||||||
|
l.l().SetLevel(loglvl.NilLevel)
|
||||||
|
case gorlog.Info:
|
||||||
|
l.l().SetLevel(loglvl.InfoLevel)
|
||||||
|
case gorlog.Warn:
|
||||||
|
l.l().SetLevel(loglvl.WarnLevel)
|
||||||
|
case gorlog.Error:
|
||||||
|
l.l().SetLevel(loglvl.ErrorLevel)
|
||||||
|
}
|
||||||
|
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *logGorm) Info(ctx context.Context, s string, i ...interface{}) {
|
||||||
|
l.l().Entry(loglvl.InfoLevel, s, i...).Log()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *logGorm) Warn(ctx context.Context, s string, i ...interface{}) {
|
||||||
|
l.l().Entry(loglvl.WarnLevel, s, i...).Log()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *logGorm) Error(ctx context.Context, s string, i ...interface{}) {
|
||||||
|
l.l().Entry(loglvl.ErrorLevel, s, i...).Log()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *logGorm) Trace(ctx context.Context, begin time.Time, fc func() (sql string, rowsAffected int64), err error) {
|
||||||
|
var e logent.Entry
|
||||||
|
elapsed := time.Since(begin)
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case err != nil && (!errors.Is(err, gorlog.ErrRecordNotFound) || !l.i):
|
||||||
|
e = l.l().Entry(loglvl.ErrorLevel, "database error with trace")
|
||||||
|
e.ErrorAdd(true, err)
|
||||||
|
case elapsed > l.s && l.s != 0:
|
||||||
|
e = l.l().Entry(loglvl.WarnLevel, "database warning with trace")
|
||||||
|
e.ErrorAdd(true, fmt.Errorf("SLOW Query >= %v", l.s))
|
||||||
|
default:
|
||||||
|
e = l.l().Entry(loglvl.InfoLevel, "database trace")
|
||||||
|
}
|
||||||
|
|
||||||
|
e.FieldAdd("elapsed ms", float64(elapsed.Nanoseconds())/1e6)
|
||||||
|
|
||||||
|
sql, rows := fc()
|
||||||
|
if rows == -1 {
|
||||||
|
e.FieldAdd("rows", "-")
|
||||||
|
e.FieldAdd("query", sql)
|
||||||
|
} else {
|
||||||
|
e.FieldAdd("rows", rows)
|
||||||
|
e.FieldAdd("query", sql)
|
||||||
|
}
|
||||||
|
|
||||||
|
e.Log()
|
||||||
|
}
|
||||||
43
logger/hashicorp/interface.go
Normal file
43
logger/hashicorp/interface.go
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
/***********************************************************************************************************************
|
||||||
|
*
|
||||||
|
* 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 hashicorp
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/hashicorp/go-hclog"
|
||||||
|
liblog "github.com/nabbar/golib/logger"
|
||||||
|
)
|
||||||
|
|
||||||
|
func New(logger liblog.Logger) hclog.Logger {
|
||||||
|
return &_hclog{
|
||||||
|
l: logger,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetDefault(log liblog.Logger) {
|
||||||
|
hclog.SetDefault(New(log))
|
||||||
|
}
|
||||||
@@ -25,13 +25,16 @@
|
|||||||
*
|
*
|
||||||
**********************************************************************************************************************/
|
**********************************************************************************************************************/
|
||||||
|
|
||||||
package logger
|
package hashicorp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
"github.com/hashicorp/go-hclog"
|
"github.com/hashicorp/go-hclog"
|
||||||
|
liblog "github.com/nabbar/golib/logger"
|
||||||
|
logcfg "github.com/nabbar/golib/logger/config"
|
||||||
|
loglvl "github.com/nabbar/golib/logger/level"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -40,7 +43,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type _hclog struct {
|
type _hclog struct {
|
||||||
l Logger
|
l liblog.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *_hclog) Log(level hclog.Level, msg string, args ...interface{}) {
|
func (o *_hclog) Log(level hclog.Level, msg string, args ...interface{}) {
|
||||||
@@ -81,23 +84,29 @@ func (o *_hclog) Error(msg string, args ...interface{}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (o *_hclog) IsTrace() bool {
|
func (o *_hclog) IsTrace() bool {
|
||||||
return o.l.GetOptions().EnableTrace
|
if opt := o.l.GetOptions(); opt == nil {
|
||||||
|
return false
|
||||||
|
} else if opt.Stdout == nil {
|
||||||
|
return false
|
||||||
|
} else {
|
||||||
|
return opt.Stdout.EnableTrace
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *_hclog) IsDebug() bool {
|
func (o *_hclog) IsDebug() bool {
|
||||||
return o.l.GetLevel() >= DebugLevel
|
return o.l.GetLevel() >= loglvl.DebugLevel
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *_hclog) IsInfo() bool {
|
func (o *_hclog) IsInfo() bool {
|
||||||
return o.l.GetLevel() >= InfoLevel
|
return o.l.GetLevel() >= loglvl.InfoLevel
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *_hclog) IsWarn() bool {
|
func (o *_hclog) IsWarn() bool {
|
||||||
return o.l.GetLevel() >= WarnLevel
|
return o.l.GetLevel() >= loglvl.WarnLevel
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *_hclog) IsError() bool {
|
func (o *_hclog) IsError() bool {
|
||||||
return o.l.GetLevel() >= ErrorLevel
|
return o.l.GetLevel() >= loglvl.ErrorLevel
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *_hclog) ImpliedArgs() []interface{} {
|
func (o *_hclog) ImpliedArgs() []interface{} {
|
||||||
@@ -142,39 +151,41 @@ func (o *_hclog) ResetNamed(name string) hclog.Logger {
|
|||||||
func (o *_hclog) SetLevel(level hclog.Level) {
|
func (o *_hclog) SetLevel(level hclog.Level) {
|
||||||
switch level {
|
switch level {
|
||||||
case hclog.NoLevel, hclog.Off:
|
case hclog.NoLevel, hclog.Off:
|
||||||
o.l.SetLevel(NilLevel)
|
o.l.SetLevel(loglvl.NilLevel)
|
||||||
case hclog.Trace:
|
case hclog.Trace:
|
||||||
opt := o.l.GetOptions()
|
opt := o.l.GetOptions()
|
||||||
opt.EnableTrace = true
|
if opt.Stdout == nil {
|
||||||
|
opt.Stdout = &logcfg.OptionsStd{}
|
||||||
|
}
|
||||||
|
opt.Stdout.EnableTrace = true
|
||||||
_ = o.l.SetOptions(opt)
|
_ = o.l.SetOptions(opt)
|
||||||
o.l.SetLevel(DebugLevel)
|
o.l.SetLevel(loglvl.DebugLevel)
|
||||||
case hclog.Debug:
|
case hclog.Debug:
|
||||||
o.l.SetLevel(DebugLevel)
|
o.l.SetLevel(loglvl.DebugLevel)
|
||||||
case hclog.Info:
|
case hclog.Info:
|
||||||
o.l.SetLevel(InfoLevel)
|
o.l.SetLevel(loglvl.InfoLevel)
|
||||||
case hclog.Warn:
|
case hclog.Warn:
|
||||||
o.l.SetLevel(WarnLevel)
|
o.l.SetLevel(loglvl.WarnLevel)
|
||||||
case hclog.Error:
|
case hclog.Error:
|
||||||
o.l.SetLevel(ErrorLevel)
|
o.l.SetLevel(loglvl.ErrorLevel)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *_hclog) GetLevel() hclog.Level {
|
func (o *_hclog) GetLevel() hclog.Level {
|
||||||
switch o.l.GetLevel() {
|
switch o.l.GetLevel() {
|
||||||
case NilLevel:
|
case loglvl.NilLevel:
|
||||||
return hclog.NoLevel
|
return hclog.NoLevel
|
||||||
case DebugLevel:
|
case loglvl.DebugLevel:
|
||||||
opt := o.l.GetOptions()
|
if o.IsTrace() {
|
||||||
if opt.EnableTrace {
|
|
||||||
return hclog.Trace
|
return hclog.Trace
|
||||||
} else {
|
} else {
|
||||||
return hclog.Debug
|
return hclog.Debug
|
||||||
}
|
}
|
||||||
case InfoLevel:
|
case loglvl.InfoLevel:
|
||||||
return hclog.Info
|
return hclog.Info
|
||||||
case WarnLevel:
|
case loglvl.WarnLevel:
|
||||||
return hclog.Warn
|
return hclog.Warn
|
||||||
case ErrorLevel:
|
case loglvl.ErrorLevel:
|
||||||
return hclog.Error
|
return hclog.Error
|
||||||
default:
|
default:
|
||||||
return hclog.Off
|
return hclog.Off
|
||||||
@@ -182,20 +193,20 @@ func (o *_hclog) GetLevel() hclog.Level {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (o *_hclog) StandardLogger(opts *hclog.StandardLoggerOptions) *log.Logger {
|
func (o *_hclog) StandardLogger(opts *hclog.StandardLoggerOptions) *log.Logger {
|
||||||
var lvl Level
|
var lvl loglvl.Level
|
||||||
switch opts.ForceLevel {
|
switch opts.ForceLevel {
|
||||||
case hclog.NoLevel, hclog.Off:
|
case hclog.NoLevel, hclog.Off:
|
||||||
lvl = NilLevel
|
lvl = loglvl.NilLevel
|
||||||
case hclog.Trace:
|
case hclog.Trace:
|
||||||
lvl = DebugLevel
|
lvl = loglvl.DebugLevel
|
||||||
case hclog.Debug:
|
case hclog.Debug:
|
||||||
lvl = DebugLevel
|
lvl = loglvl.DebugLevel
|
||||||
case hclog.Info:
|
case hclog.Info:
|
||||||
lvl = InfoLevel
|
lvl = loglvl.InfoLevel
|
||||||
case hclog.Warn:
|
case hclog.Warn:
|
||||||
lvl = WarnLevel
|
lvl = loglvl.WarnLevel
|
||||||
case hclog.Error:
|
case hclog.Error:
|
||||||
lvl = ErrorLevel
|
lvl = loglvl.ErrorLevel
|
||||||
}
|
}
|
||||||
|
|
||||||
return o.l.GetStdLogger(lvl, 0)
|
return o.l.GetStdLogger(lvl, 0)
|
||||||
@@ -1,308 +0,0 @@
|
|||||||
/***********************************************************************************************************************
|
|
||||||
*
|
|
||||||
* 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"
|
|
||||||
"os"
|
|
||||||
"strings"
|
|
||||||
"sync"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/nabbar/golib/ioutils"
|
|
||||||
"github.com/sirupsen/logrus"
|
|
||||||
)
|
|
||||||
|
|
||||||
type HookFile interface {
|
|
||||||
logrus.Hook
|
|
||||||
io.WriteCloser
|
|
||||||
RegisterHook(log *logrus.Logger)
|
|
||||||
}
|
|
||||||
|
|
||||||
type _HookFile struct {
|
|
||||||
m sync.Mutex
|
|
||||||
h *os.File
|
|
||||||
w time.Time
|
|
||||||
r logrus.Formatter
|
|
||||||
l []logrus.Level
|
|
||||||
s bool
|
|
||||||
d bool
|
|
||||||
t bool
|
|
||||||
a bool
|
|
||||||
o _HookFileOptions
|
|
||||||
}
|
|
||||||
|
|
||||||
type _HookFileOptions struct {
|
|
||||||
Create bool
|
|
||||||
FilePath string
|
|
||||||
Flags int
|
|
||||||
ModeFile os.FileMode
|
|
||||||
ModePath os.FileMode
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewHookFile(opt OptionsFile, format logrus.Formatter) (HookFile, error) {
|
|
||||||
if opt.Filepath == "" {
|
|
||||||
return nil, fmt.Errorf("missing file path")
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
LVLs = make([]logrus.Level, 0)
|
|
||||||
flags = os.O_WRONLY | os.O_APPEND
|
|
||||||
)
|
|
||||||
|
|
||||||
if len(opt.LogLevel) > 0 {
|
|
||||||
for _, ls := range opt.LogLevel {
|
|
||||||
LVLs = append(LVLs, GetLevelString(ls).Logrus())
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
LVLs = logrus.AllLevels
|
|
||||||
}
|
|
||||||
|
|
||||||
if opt.Create {
|
|
||||||
flags = os.O_CREATE | flags
|
|
||||||
}
|
|
||||||
|
|
||||||
if opt.FileMode == 0 {
|
|
||||||
opt.FileMode = 0644
|
|
||||||
}
|
|
||||||
|
|
||||||
if opt.PathMode == 0 {
|
|
||||||
opt.PathMode = 0755
|
|
||||||
}
|
|
||||||
|
|
||||||
obj := &_HookFile{
|
|
||||||
m: sync.Mutex{},
|
|
||||||
h: nil,
|
|
||||||
w: time.Time{},
|
|
||||||
r: format,
|
|
||||||
l: LVLs,
|
|
||||||
s: opt.DisableStack,
|
|
||||||
d: opt.DisableTimestamp,
|
|
||||||
t: opt.EnableTrace,
|
|
||||||
a: opt.EnableAccessLog,
|
|
||||||
o: _HookFileOptions{
|
|
||||||
Create: opt.CreatePath,
|
|
||||||
FilePath: opt.Filepath,
|
|
||||||
Flags: flags,
|
|
||||||
ModeFile: opt.FileMode,
|
|
||||||
ModePath: opt.PathMode,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
if h, e := obj.openCreate(); e != nil {
|
|
||||||
return nil, e
|
|
||||||
} else {
|
|
||||||
_ = h.Close()
|
|
||||||
}
|
|
||||||
|
|
||||||
return obj, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o *_HookFile) openCreate() (*os.File, error) {
|
|
||||||
var err error
|
|
||||||
|
|
||||||
if o.o.Create {
|
|
||||||
if err = ioutils.PathCheckCreate(true, o.o.FilePath, o.o.ModeFile, o.o.ModePath); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if h, e := os.OpenFile(o.o.FilePath, o.o.Flags, o.o.ModeFile); e != nil {
|
|
||||||
return nil, e
|
|
||||||
} else if _, e = h.Seek(0, io.SeekEnd); e != nil {
|
|
||||||
return nil, e
|
|
||||||
} else {
|
|
||||||
return h, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o *_HookFile) isStack() bool {
|
|
||||||
o.m.Lock()
|
|
||||||
defer o.m.Unlock()
|
|
||||||
|
|
||||||
return o.s
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o *_HookFile) isTimeStamp() bool {
|
|
||||||
o.m.Lock()
|
|
||||||
defer o.m.Unlock()
|
|
||||||
|
|
||||||
return o.d
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o *_HookFile) isTrace() bool {
|
|
||||||
o.m.Lock()
|
|
||||||
defer o.m.Unlock()
|
|
||||||
|
|
||||||
return o.t
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o *_HookFile) isAccessLog() bool {
|
|
||||||
o.m.Lock()
|
|
||||||
defer o.m.Unlock()
|
|
||||||
|
|
||||||
return o.a
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o *_HookFile) RegisterHook(log *logrus.Logger) {
|
|
||||||
log.AddHook(o)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o *_HookFile) Levels() []logrus.Level {
|
|
||||||
return o.l
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o *_HookFile) 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.Write(p); e != nil {
|
|
||||||
return e
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o *_HookFile) write(p []byte) (n int, err error) {
|
|
||||||
o.m.Lock()
|
|
||||||
defer o.m.Unlock()
|
|
||||||
|
|
||||||
var e error
|
|
||||||
|
|
||||||
if o.h == nil {
|
|
||||||
if o.h, e = o.openCreate(); e != nil {
|
|
||||||
return 0, fmt.Errorf("logrus.hookfile: cannot open '%s': %v", o.o.FilePath, e)
|
|
||||||
}
|
|
||||||
} else if _, e = o.h.Seek(0, io.SeekEnd); e != nil {
|
|
||||||
return 0, fmt.Errorf("logrus.hookfile: cannot seek file '%s' to EOF: %v", o.o.FilePath, e)
|
|
||||||
}
|
|
||||||
|
|
||||||
return o.h.Write(p)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o *_HookFile) Write(p []byte) (n int, err error) {
|
|
||||||
if n, err = o.write(p); err != nil {
|
|
||||||
_ = o.Close()
|
|
||||||
n, err = o.write(p)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return n, err
|
|
||||||
}
|
|
||||||
|
|
||||||
o.m.Lock()
|
|
||||||
defer o.m.Unlock()
|
|
||||||
|
|
||||||
if o.w.IsZero() {
|
|
||||||
_ = o.h.Sync()
|
|
||||||
o.w = time.Now()
|
|
||||||
return n, err
|
|
||||||
} else if time.Since(o.w) > 30*time.Second {
|
|
||||||
_ = o.h.Sync()
|
|
||||||
o.w = time.Now()
|
|
||||||
return n, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return n, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o *_HookFile) Close() error {
|
|
||||||
o.m.Lock()
|
|
||||||
defer o.m.Unlock()
|
|
||||||
|
|
||||||
if o.h != nil {
|
|
||||||
var e error
|
|
||||||
|
|
||||||
if er := o.h.Sync(); er != nil {
|
|
||||||
e = fmt.Errorf("logrus.hookfile: sync file error '%s': %v", o.o.FilePath, er)
|
|
||||||
}
|
|
||||||
|
|
||||||
if er := o.h.Close(); er != nil {
|
|
||||||
if e != nil {
|
|
||||||
e = fmt.Errorf("%v, close file error '%s': %v", e, o.o.FilePath, er)
|
|
||||||
} else {
|
|
||||||
e = fmt.Errorf("logrus.hookfile: close file error '%s': %v", o.o.FilePath, er)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
o.h = nil
|
|
||||||
return e
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o *_HookFile) 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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
63
logger/hookfile/channel.go
Normal file
63
logger/hookfile/channel.go
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
/***********************************************************************************************************************
|
||||||
|
*
|
||||||
|
* 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 hookfile
|
||||||
|
|
||||||
|
var (
|
||||||
|
closeStruct = make(chan struct{})
|
||||||
|
closeByte = make(chan []byte)
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
close(closeStruct)
|
||||||
|
close(closeByte)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *hkf) prepareChan() {
|
||||||
|
o.d.Store(make(chan []byte))
|
||||||
|
o.s.Store(make(chan struct{}))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *hkf) Done() <-chan struct{} {
|
||||||
|
c := o.s.Load()
|
||||||
|
|
||||||
|
if c != nil {
|
||||||
|
return c.(chan struct{})
|
||||||
|
}
|
||||||
|
|
||||||
|
return closeStruct
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *hkf) Data() <-chan []byte {
|
||||||
|
c := o.d.Load()
|
||||||
|
|
||||||
|
if c != nil {
|
||||||
|
return c.(chan []byte)
|
||||||
|
}
|
||||||
|
|
||||||
|
return closeByte
|
||||||
|
}
|
||||||
35
logger/hookfile/errors.go
Normal file
35
logger/hookfile/errors.go
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
/***********************************************************************************************************************
|
||||||
|
*
|
||||||
|
* 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 hookfile
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
var (
|
||||||
|
errMissingFilePath = fmt.Errorf("missing file path")
|
||||||
|
errStreamClosed = fmt.Errorf("stream is closed")
|
||||||
|
)
|
||||||
112
logger/hookfile/interface.go
Normal file
112
logger/hookfile/interface.go
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
/***********************************************************************************************************************
|
||||||
|
*
|
||||||
|
* 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 hookfile
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"sync/atomic"
|
||||||
|
|
||||||
|
libiot "github.com/nabbar/golib/ioutils"
|
||||||
|
logcfg "github.com/nabbar/golib/logger/config"
|
||||||
|
loglvl "github.com/nabbar/golib/logger/level"
|
||||||
|
logtps "github.com/nabbar/golib/logger/types"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
type HookFile interface {
|
||||||
|
logtps.Hook
|
||||||
|
|
||||||
|
Done() <-chan struct{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(opt logcfg.OptionsFile, format logrus.Formatter) (HookFile, error) {
|
||||||
|
if opt.Filepath == "" {
|
||||||
|
return nil, errMissingFilePath
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
LVLs = make([]logrus.Level, 0)
|
||||||
|
flags = os.O_WRONLY | os.O_APPEND
|
||||||
|
)
|
||||||
|
|
||||||
|
if len(opt.LogLevel) > 0 {
|
||||||
|
for _, ls := range opt.LogLevel {
|
||||||
|
LVLs = append(LVLs, loglvl.Parse(ls).Logrus())
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
LVLs = logrus.AllLevels
|
||||||
|
}
|
||||||
|
|
||||||
|
if opt.Create {
|
||||||
|
flags = os.O_CREATE | flags
|
||||||
|
}
|
||||||
|
|
||||||
|
if opt.FileMode == 0 {
|
||||||
|
opt.FileMode = 0644
|
||||||
|
}
|
||||||
|
|
||||||
|
if opt.PathMode == 0 {
|
||||||
|
opt.PathMode = 0755
|
||||||
|
}
|
||||||
|
|
||||||
|
n := &hkf{
|
||||||
|
s: new(atomic.Value),
|
||||||
|
d: new(atomic.Value),
|
||||||
|
o: ohkf{
|
||||||
|
format: format,
|
||||||
|
flags: flags,
|
||||||
|
levels: LVLs,
|
||||||
|
disableStack: opt.DisableStack,
|
||||||
|
disableTimestamp: opt.DisableTimestamp,
|
||||||
|
enableTrace: opt.EnableTrace,
|
||||||
|
enableAccessLog: opt.EnableAccessLog,
|
||||||
|
createPath: opt.CreatePath,
|
||||||
|
filepath: opt.Filepath,
|
||||||
|
fileMode: opt.FileMode,
|
||||||
|
pathMode: opt.PathMode,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
if opt.CreatePath {
|
||||||
|
if e := libiot.PathCheckCreate(true, opt.Filepath, opt.FileMode, opt.PathMode); e != nil {
|
||||||
|
return nil, e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if h, e := os.OpenFile(opt.Filepath, flags, opt.FileMode); e != nil {
|
||||||
|
return nil, e
|
||||||
|
} else if _, e = h.Seek(0, io.SeekEnd); e != nil {
|
||||||
|
_ = h.Close()
|
||||||
|
return nil, e
|
||||||
|
} else if e = h.Close(); e != nil {
|
||||||
|
return nil, e
|
||||||
|
}
|
||||||
|
|
||||||
|
return n, nil
|
||||||
|
}
|
||||||
57
logger/hookfile/iowriter.go
Normal file
57
logger/hookfile/iowriter.go
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
/***********************************************************************************************************************
|
||||||
|
*
|
||||||
|
* 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 hookfile
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (o *hkf) Write(p []byte) (n int, err error) {
|
||||||
|
c := o.d.Load()
|
||||||
|
|
||||||
|
if c != nil {
|
||||||
|
if c.(chan []byte) != closeByte {
|
||||||
|
c.(chan []byte) <- p
|
||||||
|
return len(p), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0, fmt.Errorf("%v, path: %s", errStreamClosed, o.getFilepath())
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *hkf) Close() error {
|
||||||
|
fmt.Printf("closing hook for log file '%s'\n", o.getFilepath())
|
||||||
|
|
||||||
|
o.d.Store(closeByte)
|
||||||
|
time.Sleep(10 * time.Millisecond)
|
||||||
|
|
||||||
|
o.s.Store(closeStruct)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
133
logger/hookfile/model.go
Normal file
133
logger/hookfile/model.go
Normal file
@@ -0,0 +1,133 @@
|
|||||||
|
/***********************************************************************************************************************
|
||||||
|
*
|
||||||
|
* 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 hookfile
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
"sync/atomic"
|
||||||
|
|
||||||
|
logtps "github.com/nabbar/golib/logger/types"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ohkf struct {
|
||||||
|
format logrus.Formatter
|
||||||
|
flags int
|
||||||
|
levels []logrus.Level
|
||||||
|
disableStack bool
|
||||||
|
disableTimestamp bool
|
||||||
|
enableTrace bool
|
||||||
|
enableAccessLog bool
|
||||||
|
createPath bool
|
||||||
|
filepath string
|
||||||
|
fileMode os.FileMode
|
||||||
|
pathMode os.FileMode
|
||||||
|
}
|
||||||
|
|
||||||
|
type hkf struct {
|
||||||
|
s *atomic.Value // channel stop struct{}
|
||||||
|
d *atomic.Value // channel data []byte
|
||||||
|
o ohkf // config data
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *hkf) Levels() []logrus.Level {
|
||||||
|
return o.getLevel()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *hkf) RegisterHook(log *logrus.Logger) {
|
||||||
|
log.AddHook(o)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *hkf) Fire(entry *logrus.Entry) error {
|
||||||
|
ent := entry.Dup()
|
||||||
|
ent.Level = entry.Level
|
||||||
|
|
||||||
|
if o.getDisableStack() {
|
||||||
|
ent.Data = o.filterKey(ent.Data, logtps.FieldStack)
|
||||||
|
}
|
||||||
|
|
||||||
|
if o.getDisableTimestamp() {
|
||||||
|
ent.Data = o.filterKey(ent.Data, logtps.FieldTime)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !o.getEnableTrace() {
|
||||||
|
ent.Data = o.filterKey(ent.Data, logtps.FieldCaller)
|
||||||
|
ent.Data = o.filterKey(ent.Data, logtps.FieldFile)
|
||||||
|
ent.Data = o.filterKey(ent.Data, logtps.FieldLine)
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
p []byte
|
||||||
|
e error
|
||||||
|
)
|
||||||
|
|
||||||
|
if o.getEnableAccessLog() {
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
if f := o.getFormatter(); f != nil {
|
||||||
|
p, e = f.Format(ent)
|
||||||
|
} else {
|
||||||
|
p, e = ent.Bytes()
|
||||||
|
}
|
||||||
|
|
||||||
|
if e != nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, e = o.Write(p); e != nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *hkf) 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
|
||||||
|
}
|
||||||
|
}
|
||||||
78
logger/hookfile/options.go
Normal file
78
logger/hookfile/options.go
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
/***********************************************************************************************************************
|
||||||
|
*
|
||||||
|
* 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 hookfile
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (o *hkf) getFormatter() logrus.Formatter {
|
||||||
|
return o.o.format
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *hkf) getFlags() int {
|
||||||
|
return o.o.flags
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *hkf) getLevel() []logrus.Level {
|
||||||
|
return o.o.levels
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *hkf) getDisableStack() bool {
|
||||||
|
return o.o.disableStack
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *hkf) getDisableTimestamp() bool {
|
||||||
|
return o.o.disableTimestamp
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *hkf) getEnableTrace() bool {
|
||||||
|
return o.o.enableTrace
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *hkf) getEnableAccessLog() bool {
|
||||||
|
return o.o.enableAccessLog
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *hkf) getCreatePath() bool {
|
||||||
|
return o.o.createPath
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *hkf) getFilepath() string {
|
||||||
|
return o.o.filepath
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *hkf) getFileMode() os.FileMode {
|
||||||
|
return o.o.fileMode
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *hkf) getPathMode() os.FileMode {
|
||||||
|
return o.o.pathMode
|
||||||
|
}
|
||||||
134
logger/hookfile/system.go
Normal file
134
logger/hookfile/system.go
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
/***********************************************************************************************************************
|
||||||
|
*
|
||||||
|
* 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 hookfile
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
libiot "github.com/nabbar/golib/ioutils"
|
||||||
|
)
|
||||||
|
|
||||||
|
const sizeBuffer = 32 * 1024
|
||||||
|
|
||||||
|
func (o *hkf) writeBuffer(buf *bytes.Buffer) error {
|
||||||
|
var (
|
||||||
|
e error
|
||||||
|
h *os.File
|
||||||
|
p = o.getFilepath()
|
||||||
|
m = o.getFileMode()
|
||||||
|
n = o.getPathMode()
|
||||||
|
f = o.getFlags()
|
||||||
|
)
|
||||||
|
|
||||||
|
if o.getCreatePath() {
|
||||||
|
if e = libiot.PathCheckCreate(true, p, m, n); e != nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
if h != nil {
|
||||||
|
_ = h.Close()
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
if h, e = os.OpenFile(p, f, m); e != nil {
|
||||||
|
return e
|
||||||
|
} else if _, e = h.Seek(0, io.SeekEnd); e != nil {
|
||||||
|
return e
|
||||||
|
} else if _, e = h.Write(buf.Bytes()); e != nil {
|
||||||
|
return e
|
||||||
|
} else if e = h.Close(); e != nil {
|
||||||
|
h = nil
|
||||||
|
buf.Reset()
|
||||||
|
return e
|
||||||
|
} else {
|
||||||
|
h = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
buf.Reset()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *hkf) freeBuffer(buf *bytes.Buffer, size int) *bytes.Buffer {
|
||||||
|
var a = bytes.NewBuffer(buf.Bytes()[size:])
|
||||||
|
a.Grow(size)
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *hkf) Run(ctx context.Context) {
|
||||||
|
var (
|
||||||
|
b = bytes.NewBuffer(make([]byte, sizeBuffer))
|
||||||
|
t = time.NewTicker(time.Second)
|
||||||
|
e error
|
||||||
|
)
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
//flush buffer before exit function
|
||||||
|
if b.Len() > 0 {
|
||||||
|
if e = o.writeBuffer(b); e != nil {
|
||||||
|
fmt.Println(e.Error())
|
||||||
|
}
|
||||||
|
b.Reset()
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
o.prepareChan()
|
||||||
|
fmt.Printf("starting hook for log file '%s'\n", o.getFilepath())
|
||||||
|
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
return
|
||||||
|
|
||||||
|
case <-o.Done():
|
||||||
|
return
|
||||||
|
|
||||||
|
case <-t.C:
|
||||||
|
if b.Len() < 1 {
|
||||||
|
continue
|
||||||
|
} else if e = o.writeBuffer(b); e != nil {
|
||||||
|
fmt.Println(e.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
case p := <-o.Data():
|
||||||
|
// prevent buffer overflow
|
||||||
|
if b.Len()+len(p) >= sizeBuffer {
|
||||||
|
b = o.freeBuffer(b, len(p))
|
||||||
|
b.Write(p)
|
||||||
|
} else {
|
||||||
|
_, _ = b.Write(p)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
73
logger/hookstderr/interface.go
Normal file
73
logger/hookstderr/interface.go
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
/***********************************************************************************************************************
|
||||||
|
*
|
||||||
|
* 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 hookstderr
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/mattn/go-colorable"
|
||||||
|
logcfg "github.com/nabbar/golib/logger/config"
|
||||||
|
logtps "github.com/nabbar/golib/logger/types"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
type HookStdErr interface {
|
||||||
|
logtps.Hook
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(opt *logcfg.OptionsStd, lvls []logrus.Level, f logrus.Formatter) (HookStdErr, error) {
|
||||||
|
if opt == nil || opt.DisableStandard {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(lvls) < 1 {
|
||||||
|
lvls = logrus.AllLevels
|
||||||
|
}
|
||||||
|
|
||||||
|
var w io.Writer
|
||||||
|
|
||||||
|
if opt.DisableColor {
|
||||||
|
w = os.Stderr
|
||||||
|
} else {
|
||||||
|
w = colorable.NewColorableStderr()
|
||||||
|
}
|
||||||
|
|
||||||
|
n := &hkerr{
|
||||||
|
w: w,
|
||||||
|
l: lvls,
|
||||||
|
f: f,
|
||||||
|
s: opt.DisableStack,
|
||||||
|
d: opt.DisableTimestamp,
|
||||||
|
t: opt.EnableTrace,
|
||||||
|
c: opt.DisableColor,
|
||||||
|
a: opt.EnableAccessLog,
|
||||||
|
}
|
||||||
|
|
||||||
|
return n, nil
|
||||||
|
}
|
||||||
44
logger/hookstderr/iowriter.go
Normal file
44
logger/hookstderr/iowriter.go
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
/***********************************************************************************************************************
|
||||||
|
*
|
||||||
|
* 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 hookstderr
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (o *hkerr) Write(p []byte) (n int, err error) {
|
||||||
|
if o.w == nil {
|
||||||
|
return 0, fmt.Errorf("logrus.hookstd: writer not setup")
|
||||||
|
}
|
||||||
|
|
||||||
|
return o.w.Write(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *hkerr) Close() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -25,98 +25,60 @@
|
|||||||
*
|
*
|
||||||
**********************************************************************************************************************/
|
**********************************************************************************************************************/
|
||||||
|
|
||||||
package logger
|
package hookstderr
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"context"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/mattn/go-colorable"
|
logtps "github.com/nabbar/golib/logger/types"
|
||||||
|
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
type StdWriter uint8
|
type hkerr struct {
|
||||||
|
|
||||||
const (
|
|
||||||
StdOut StdWriter = iota
|
|
||||||
StdErr
|
|
||||||
)
|
|
||||||
|
|
||||||
type HookStandard interface {
|
|
||||||
logrus.Hook
|
|
||||||
io.WriteCloser
|
|
||||||
RegisterHook(log *logrus.Logger)
|
|
||||||
}
|
|
||||||
|
|
||||||
type _HookStd struct {
|
|
||||||
w io.Writer
|
w io.Writer
|
||||||
l []logrus.Level
|
l []logrus.Level
|
||||||
|
f logrus.Formatter
|
||||||
s bool // Disable Stack
|
s bool // Disable Stack
|
||||||
d bool // Disable Timestamp
|
d bool // Disable Timestamp
|
||||||
t bool // Disable Trace
|
t bool // Disable Trace
|
||||||
|
c bool // Disable Color
|
||||||
a bool // Enable AccessLog
|
a bool // Enable AccessLog
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewHookStandard(opt Options, s StdWriter, lvls []logrus.Level) HookStandard {
|
func (o *hkerr) getFormatter() logrus.Formatter {
|
||||||
if len(lvls) < 1 {
|
return o.f
|
||||||
lvls = logrus.AllLevels
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var w io.Writer
|
func (o *hkerr) Run(ctx context.Context) {
|
||||||
|
return
|
||||||
if opt.DisableColor {
|
|
||||||
switch s {
|
|
||||||
case StdErr:
|
|
||||||
w = os.Stderr
|
|
||||||
default:
|
|
||||||
w = os.Stdout
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
switch s {
|
|
||||||
case StdErr:
|
|
||||||
w = colorable.NewColorableStderr()
|
|
||||||
default:
|
|
||||||
w = colorable.NewColorableStderr()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return &_HookStd{
|
func (o *hkerr) Levels() []logrus.Level {
|
||||||
w: w,
|
|
||||||
l: lvls,
|
|
||||||
s: opt.DisableStack,
|
|
||||||
d: opt.DisableTimestamp,
|
|
||||||
t: opt.EnableTrace,
|
|
||||||
a: opt.EnableAccessLog,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o *_HookStd) RegisterHook(log *logrus.Logger) {
|
|
||||||
log.AddHook(o)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o *_HookStd) Levels() []logrus.Level {
|
|
||||||
return o.l
|
return o.l
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *_HookStd) Fire(entry *logrus.Entry) error {
|
func (o *hkerr) RegisterHook(log *logrus.Logger) {
|
||||||
|
log.AddHook(o)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *hkerr) Fire(entry *logrus.Entry) error {
|
||||||
ent := entry.Dup()
|
ent := entry.Dup()
|
||||||
ent.Level = entry.Level
|
ent.Level = entry.Level
|
||||||
|
|
||||||
if o.s {
|
if o.s {
|
||||||
ent.Data = o.filterKey(ent.Data, FieldStack)
|
ent.Data = o.filterKey(ent.Data, logtps.FieldStack)
|
||||||
}
|
}
|
||||||
|
|
||||||
if o.d {
|
if o.d {
|
||||||
ent.Data = o.filterKey(ent.Data, FieldTime)
|
ent.Data = o.filterKey(ent.Data, logtps.FieldTime)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !o.t {
|
if !o.t {
|
||||||
ent.Data = o.filterKey(ent.Data, FieldCaller)
|
ent.Data = o.filterKey(ent.Data, logtps.FieldCaller)
|
||||||
ent.Data = o.filterKey(ent.Data, FieldFile)
|
ent.Data = o.filterKey(ent.Data, logtps.FieldFile)
|
||||||
ent.Data = o.filterKey(ent.Data, FieldLine)
|
ent.Data = o.filterKey(ent.Data, logtps.FieldLine)
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -136,7 +98,15 @@ func (o *_HookStd) Fire(entry *logrus.Entry) error {
|
|||||||
} else {
|
} else {
|
||||||
if len(ent.Data) < 1 {
|
if len(ent.Data) < 1 {
|
||||||
return nil
|
return nil
|
||||||
} else if p, e = ent.Bytes(); e != nil {
|
}
|
||||||
|
|
||||||
|
if f := o.getFormatter(); f != nil {
|
||||||
|
p, e = f.Format(ent)
|
||||||
|
} else {
|
||||||
|
p, e = ent.Bytes()
|
||||||
|
}
|
||||||
|
|
||||||
|
if e != nil {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -148,19 +118,7 @@ func (o *_HookStd) Fire(entry *logrus.Entry) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *_HookStd) Write(p []byte) (n int, err error) {
|
func (o *hkerr) filterKey(f logrus.Fields, key string) logrus.Fields {
|
||||||
if o.w == nil {
|
|
||||||
return 0, fmt.Errorf("logrus.hookstd: writer not setup")
|
|
||||||
}
|
|
||||||
|
|
||||||
return o.w.Write(p)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o *_HookStd) Close() error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o *_HookStd) filterKey(f logrus.Fields, key string) logrus.Fields {
|
|
||||||
if len(f) < 1 {
|
if len(f) < 1 {
|
||||||
return f
|
return f
|
||||||
}
|
}
|
||||||
@@ -171,16 +129,4 @@ func (o *_HookStd) filterKey(f logrus.Fields, key string) logrus.Fields {
|
|||||||
delete(f, key)
|
delete(f, key)
|
||||||
return f
|
return f
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
var res = make(map[string]interface{}, 0)
|
|
||||||
|
|
||||||
for k, v := range f {
|
|
||||||
if k == key {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
res[k] = v
|
|
||||||
}
|
|
||||||
|
|
||||||
return res
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
73
logger/hookstdout/interface.go
Normal file
73
logger/hookstdout/interface.go
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
/***********************************************************************************************************************
|
||||||
|
*
|
||||||
|
* 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 hookstdout
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/mattn/go-colorable"
|
||||||
|
logcfg "github.com/nabbar/golib/logger/config"
|
||||||
|
logtps "github.com/nabbar/golib/logger/types"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
type HookStdOut interface {
|
||||||
|
logtps.Hook
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(opt *logcfg.OptionsStd, lvls []logrus.Level, f logrus.Formatter) (HookStdOut, error) {
|
||||||
|
if opt == nil || opt.DisableStandard {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(lvls) < 1 {
|
||||||
|
lvls = logrus.AllLevels
|
||||||
|
}
|
||||||
|
|
||||||
|
var w io.Writer
|
||||||
|
|
||||||
|
if opt.DisableColor {
|
||||||
|
w = os.Stdout
|
||||||
|
} else {
|
||||||
|
w = colorable.NewColorableStdout()
|
||||||
|
}
|
||||||
|
|
||||||
|
n := &hkstd{
|
||||||
|
w: w,
|
||||||
|
l: lvls,
|
||||||
|
f: f,
|
||||||
|
s: opt.DisableStack,
|
||||||
|
d: opt.DisableTimestamp,
|
||||||
|
t: opt.EnableTrace,
|
||||||
|
c: opt.DisableColor,
|
||||||
|
a: opt.EnableAccessLog,
|
||||||
|
}
|
||||||
|
|
||||||
|
return n, nil
|
||||||
|
}
|
||||||
44
logger/hookstdout/iowriter.go
Normal file
44
logger/hookstdout/iowriter.go
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
/***********************************************************************************************************************
|
||||||
|
*
|
||||||
|
* 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 hookstdout
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (o *hkstd) Write(p []byte) (n int, err error) {
|
||||||
|
if o.w == nil {
|
||||||
|
return 0, fmt.Errorf("logrus.hookstd: writer not setup")
|
||||||
|
}
|
||||||
|
|
||||||
|
return o.w.Write(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *hkstd) Close() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
132
logger/hookstdout/model.go
Normal file
132
logger/hookstdout/model.go
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
/***********************************************************************************************************************
|
||||||
|
*
|
||||||
|
* 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 hookstdout
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"io"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
logtps "github.com/nabbar/golib/logger/types"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
type hkstd struct {
|
||||||
|
w io.Writer
|
||||||
|
l []logrus.Level
|
||||||
|
f logrus.Formatter
|
||||||
|
s bool // Disable Stack
|
||||||
|
d bool // Disable Timestamp
|
||||||
|
t bool // Disable Trace
|
||||||
|
c bool // Disable Color
|
||||||
|
a bool // Enable AccessLog
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *hkstd) getFormatter() logrus.Formatter {
|
||||||
|
return o.f
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *hkstd) Run(ctx context.Context) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *hkstd) Levels() []logrus.Level {
|
||||||
|
return o.l
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *hkstd) RegisterHook(log *logrus.Logger) {
|
||||||
|
log.AddHook(o)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *hkstd) Fire(entry *logrus.Entry) error {
|
||||||
|
ent := entry.Dup()
|
||||||
|
ent.Level = entry.Level
|
||||||
|
|
||||||
|
if o.s {
|
||||||
|
ent.Data = o.filterKey(ent.Data, logtps.FieldStack)
|
||||||
|
}
|
||||||
|
|
||||||
|
if o.d {
|
||||||
|
ent.Data = o.filterKey(ent.Data, logtps.FieldTime)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !o.t {
|
||||||
|
ent.Data = o.filterKey(ent.Data, logtps.FieldCaller)
|
||||||
|
ent.Data = o.filterKey(ent.Data, logtps.FieldFile)
|
||||||
|
ent.Data = o.filterKey(ent.Data, logtps.FieldLine)
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
p []byte
|
||||||
|
e error
|
||||||
|
)
|
||||||
|
|
||||||
|
if o.a {
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
if f := o.getFormatter(); f != nil {
|
||||||
|
p, e = f.Format(ent)
|
||||||
|
} else {
|
||||||
|
p, e = ent.Bytes()
|
||||||
|
}
|
||||||
|
|
||||||
|
if e != nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, e = o.Write(p); e != nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *hkstd) 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
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,268 +0,0 @@
|
|||||||
/***********************************************************************************************************************
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
63
logger/hooksyslog/channel.go
Normal file
63
logger/hooksyslog/channel.go
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
/***********************************************************************************************************************
|
||||||
|
*
|
||||||
|
* 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 hooksyslog
|
||||||
|
|
||||||
|
var (
|
||||||
|
closeStruct = make(chan struct{})
|
||||||
|
closeByte = make(chan data)
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
close(closeStruct)
|
||||||
|
close(closeByte)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *hks) prepareChan() {
|
||||||
|
o.d.Store(make(chan data))
|
||||||
|
o.s.Store(make(chan struct{}))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *hks) Done() <-chan struct{} {
|
||||||
|
c := o.s.Load()
|
||||||
|
|
||||||
|
if c != nil {
|
||||||
|
return c.(chan struct{})
|
||||||
|
}
|
||||||
|
|
||||||
|
return closeStruct
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *hks) Data() <-chan data {
|
||||||
|
c := o.d.Load()
|
||||||
|
|
||||||
|
if c != nil {
|
||||||
|
return c.(chan data)
|
||||||
|
}
|
||||||
|
|
||||||
|
return closeByte
|
||||||
|
}
|
||||||
42
logger/hooksyslog/data.go
Normal file
42
logger/hooksyslog/data.go
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
/***********************************************************************************************************************
|
||||||
|
*
|
||||||
|
* 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 hooksyslog
|
||||||
|
|
||||||
|
type data struct {
|
||||||
|
s SyslogSeverity
|
||||||
|
p []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
type bufData []data
|
||||||
|
|
||||||
|
func newData(s SyslogSeverity, p []byte) data {
|
||||||
|
return data{
|
||||||
|
s: s,
|
||||||
|
p: p,
|
||||||
|
}
|
||||||
|
}
|
||||||
32
logger/hooksyslog/errors.go
Normal file
32
logger/hooksyslog/errors.go
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
/***********************************************************************************************************************
|
||||||
|
*
|
||||||
|
* 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 hooksyslog
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
var errStreamClosed = fmt.Errorf("stream is closed")
|
||||||
88
logger/hooksyslog/interface.go
Normal file
88
logger/hooksyslog/interface.go
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
/***********************************************************************************************************************
|
||||||
|
*
|
||||||
|
* 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 hooksyslog
|
||||||
|
|
||||||
|
import (
|
||||||
|
"sync/atomic"
|
||||||
|
|
||||||
|
logcfg "github.com/nabbar/golib/logger/config"
|
||||||
|
loglvl "github.com/nabbar/golib/logger/level"
|
||||||
|
logtps "github.com/nabbar/golib/logger/types"
|
||||||
|
libptc "github.com/nabbar/golib/network/protocol"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
type HookSyslog interface {
|
||||||
|
logtps.Hook
|
||||||
|
|
||||||
|
Done() <-chan struct{}
|
||||||
|
WriteSev(s SyslogSeverity, p []byte) (n int, err error)
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(opt logcfg.OptionsSyslog, format logrus.Formatter) (HookSyslog, error) {
|
||||||
|
var (
|
||||||
|
LVLs = make([]logrus.Level, 0)
|
||||||
|
)
|
||||||
|
|
||||||
|
if len(opt.LogLevel) > 0 {
|
||||||
|
for _, ls := range opt.LogLevel {
|
||||||
|
LVLs = append(LVLs, loglvl.Parse(ls).Logrus())
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
LVLs = logrus.AllLevels
|
||||||
|
}
|
||||||
|
|
||||||
|
n := &hks{
|
||||||
|
s: new(atomic.Value),
|
||||||
|
d: new(atomic.Value),
|
||||||
|
o: ohks{
|
||||||
|
format: format,
|
||||||
|
levels: LVLs,
|
||||||
|
disableStack: opt.DisableStack,
|
||||||
|
disableTimestamp: opt.DisableTimestamp,
|
||||||
|
enableTrace: opt.EnableTrace,
|
||||||
|
enableAccessLog: opt.EnableAccessLog,
|
||||||
|
network: libptc.Parse(opt.Network),
|
||||||
|
endpoint: opt.Host,
|
||||||
|
tag: opt.Tag,
|
||||||
|
fac: MakeFacility(opt.Facility),
|
||||||
|
//sev : MakeSeverity(opt.Severity),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
n.s.Store(make(chan struct{}))
|
||||||
|
n.d.Store(make(chan data))
|
||||||
|
|
||||||
|
if h, e := n.getSyslog(); e != nil {
|
||||||
|
return nil, e
|
||||||
|
} else {
|
||||||
|
_ = h.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
return n, nil
|
||||||
|
}
|
||||||
71
logger/hooksyslog/iowriter.go
Normal file
71
logger/hooksyslog/iowriter.go
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
/***********************************************************************************************************************
|
||||||
|
*
|
||||||
|
* 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 hooksyslog
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (o *hks) Write(p []byte) (n int, err error) {
|
||||||
|
c := o.d.Load()
|
||||||
|
|
||||||
|
if c != nil {
|
||||||
|
if c.(chan data) != closeByte {
|
||||||
|
c.(chan data) <- newData(0, p)
|
||||||
|
return len(p), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0, errStreamClosed
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *hks) WriteSev(s SyslogSeverity, p []byte) (n int, err error) {
|
||||||
|
c := o.d.Load()
|
||||||
|
|
||||||
|
if c != nil {
|
||||||
|
if c.(chan data) != closeByte {
|
||||||
|
c.(chan data) <- newData(s, p)
|
||||||
|
return len(p), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0, fmt.Errorf("%v, path: %s", errStreamClosed, o.getSyslogInfo())
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *hks) Close() error {
|
||||||
|
fmt.Printf("closing hook for log syslog '%s'\n", o.getSyslogInfo())
|
||||||
|
|
||||||
|
o.d.Store(closeByte)
|
||||||
|
time.Sleep(10 * time.Millisecond)
|
||||||
|
|
||||||
|
o.s.Store(closeStruct)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
153
logger/hooksyslog/model.go
Normal file
153
logger/hooksyslog/model.go
Normal file
@@ -0,0 +1,153 @@
|
|||||||
|
/***********************************************************************************************************************
|
||||||
|
*
|
||||||
|
* 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 hooksyslog
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
"sync/atomic"
|
||||||
|
|
||||||
|
libptc "github.com/nabbar/golib/network/protocol"
|
||||||
|
|
||||||
|
logtps "github.com/nabbar/golib/logger/types"
|
||||||
|
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ohks struct {
|
||||||
|
format logrus.Formatter
|
||||||
|
levels []logrus.Level
|
||||||
|
disableStack bool
|
||||||
|
disableTimestamp bool
|
||||||
|
enableTrace bool
|
||||||
|
enableAccessLog bool
|
||||||
|
|
||||||
|
network libptc.NetworkProtocol
|
||||||
|
endpoint string
|
||||||
|
|
||||||
|
tag string
|
||||||
|
fac SyslogFacility
|
||||||
|
// Sev SyslogSeverity
|
||||||
|
}
|
||||||
|
|
||||||
|
type hks struct {
|
||||||
|
s *atomic.Value // channel stop struct{}
|
||||||
|
d *atomic.Value // channel data []byte
|
||||||
|
o ohks // config data
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *hks) Levels() []logrus.Level {
|
||||||
|
return o.getLevel()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *hks) RegisterHook(log *logrus.Logger) {
|
||||||
|
log.AddHook(o)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *hks) Fire(entry *logrus.Entry) error {
|
||||||
|
ent := entry.Dup()
|
||||||
|
ent.Level = entry.Level
|
||||||
|
|
||||||
|
if o.getDisableStack() {
|
||||||
|
ent.Data = o.filterKey(ent.Data, logtps.FieldStack)
|
||||||
|
}
|
||||||
|
|
||||||
|
if o.getDisableTimestamp() {
|
||||||
|
ent.Data = o.filterKey(ent.Data, logtps.FieldTime)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !o.getEnableTrace() {
|
||||||
|
ent.Data = o.filterKey(ent.Data, logtps.FieldCaller)
|
||||||
|
ent.Data = o.filterKey(ent.Data, logtps.FieldFile)
|
||||||
|
ent.Data = o.filterKey(ent.Data, logtps.FieldLine)
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
p []byte
|
||||||
|
e error
|
||||||
|
)
|
||||||
|
|
||||||
|
if o.getEnableAccessLog() {
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
if f := o.getFormatter(); f != nil {
|
||||||
|
p, e = f.Format(ent)
|
||||||
|
} else {
|
||||||
|
p, e = ent.Bytes()
|
||||||
|
}
|
||||||
|
|
||||||
|
if e != nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ent.Level {
|
||||||
|
case logrus.PanicLevel:
|
||||||
|
_, e = o.WriteSev(SyslogSeverityAlert, p)
|
||||||
|
case logrus.FatalLevel:
|
||||||
|
_, e = o.WriteSev(SyslogSeverityCrit, p)
|
||||||
|
case logrus.ErrorLevel:
|
||||||
|
_, e = o.WriteSev(SyslogSeverityErr, p)
|
||||||
|
case logrus.WarnLevel:
|
||||||
|
_, e = o.WriteSev(SyslogSeverityWarning, p)
|
||||||
|
case logrus.InfoLevel:
|
||||||
|
_, e = o.WriteSev(SyslogSeverityInfo, p)
|
||||||
|
case logrus.DebugLevel:
|
||||||
|
_, e = o.WriteSev(SyslogSeverityDebug, p)
|
||||||
|
default:
|
||||||
|
_, e = o.Write(p)
|
||||||
|
}
|
||||||
|
if e != nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *hks) 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
|
||||||
|
}
|
||||||
|
}
|
||||||
66
logger/hooksyslog/options.go
Normal file
66
logger/hooksyslog/options.go
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
/***********************************************************************************************************************
|
||||||
|
*
|
||||||
|
* 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 hooksyslog
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (o *hks) getFormatter() logrus.Formatter {
|
||||||
|
return o.o.format
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *hks) getLevel() []logrus.Level {
|
||||||
|
return o.o.levels
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *hks) getDisableStack() bool {
|
||||||
|
return o.o.disableStack
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *hks) getDisableTimestamp() bool {
|
||||||
|
return o.o.disableTimestamp
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *hks) getEnableTrace() bool {
|
||||||
|
return o.o.enableTrace
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *hks) getEnableAccessLog() bool {
|
||||||
|
return o.o.enableAccessLog
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *hks) getSyslog() (Wrapper, error) {
|
||||||
|
return newSyslog(o.o.network, o.o.endpoint, o.o.tag, o.o.fac)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *hks) getSyslogInfo() string {
|
||||||
|
return fmt.Sprintf("syslog to '%s %s' with tag '%s'", o.o.network.Code(), o.o.endpoint, o.o.tag)
|
||||||
|
}
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
*
|
*
|
||||||
**********************************************************************************************************************/
|
**********************************************************************************************************************/
|
||||||
|
|
||||||
package logger
|
package hooksyslog
|
||||||
|
|
||||||
import "strings"
|
import "strings"
|
||||||
|
|
||||||
@@ -28,11 +28,13 @@
|
|||||||
*
|
*
|
||||||
**********************************************************************************************************************/
|
**********************************************************************************************************************/
|
||||||
|
|
||||||
package logger
|
package hooksyslog
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log/syslog"
|
"log/syslog"
|
||||||
|
|
||||||
|
libptc "github.com/nabbar/golib/network/protocol"
|
||||||
)
|
)
|
||||||
|
|
||||||
func makePriority(severity SyslogSeverity, facility SyslogFacility) syslog.Priority {
|
func makePriority(severity SyslogSeverity, facility SyslogFacility) syslog.Priority {
|
||||||
@@ -111,7 +113,7 @@ type _Syslog struct {
|
|||||||
w *syslog.Writer
|
w *syslog.Writer
|
||||||
}
|
}
|
||||||
|
|
||||||
func newSyslog(net NetworkType, host, tag string, fac SyslogFacility) (syslogWrapper, error) {
|
func newSyslog(net libptc.NetworkProtocol, host, tag string, fac SyslogFacility) (Wrapper, error) {
|
||||||
var (
|
var (
|
||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
@@ -128,7 +130,7 @@ func newSyslog(net NetworkType, host, tag string, fac SyslogFacility) (syslogWra
|
|||||||
return obj, nil
|
return obj, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *_Syslog) openSyslogSev(net NetworkType, host, tag string, prio syslog.Priority) (*syslog.Writer, error) {
|
func (o *_Syslog) openSyslogSev(net libptc.NetworkProtocol, host, tag string, prio syslog.Priority) (*syslog.Writer, error) {
|
||||||
return syslog.Dial(net.String(), host, prio, tag)
|
return syslog.Dial(net.String(), host, prio, tag)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,7 +140,7 @@ func (o *_Syslog) Write(p []byte) (n int, err error) {
|
|||||||
|
|
||||||
func (o *_Syslog) WriteSev(sev SyslogSeverity, p []byte) (n int, err error) {
|
func (o *_Syslog) WriteSev(sev SyslogSeverity, p []byte) (n int, err error) {
|
||||||
if o.w == nil {
|
if o.w == nil {
|
||||||
return 0, fmt.Errorf("logrus.hooksyslog: connection not setup")
|
return 0, fmt.Errorf("hooksyslog: connection not setup")
|
||||||
}
|
}
|
||||||
|
|
||||||
switch sev {
|
switch sev {
|
||||||
@@ -28,12 +28,14 @@
|
|||||||
*
|
*
|
||||||
**********************************************************************************************************************/
|
**********************************************************************************************************************/
|
||||||
|
|
||||||
package logger
|
package hooksyslog
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
libptc "github.com/nabbar/golib/network/protocol"
|
||||||
|
|
||||||
"golang.org/x/sys/windows/svc/eventlog"
|
"golang.org/x/sys/windows/svc/eventlog"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -125,13 +127,13 @@ type _WinLog struct {
|
|||||||
w *eventlog.Log
|
w *eventlog.Log
|
||||||
}
|
}
|
||||||
|
|
||||||
func newSyslog(net NetworkType, host, tag string, facility SyslogFacility) (syslogWrapper, error) {
|
func newSyslog(net libptc.NetworkProtocol, host, tag string, facility SyslogFacility) (Wrapper, error) {
|
||||||
var (
|
var (
|
||||||
sys *eventlog.Log
|
sys *eventlog.Log
|
||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
|
|
||||||
if net != NetworkEmpty {
|
if net != libptc.NetworkEmpty {
|
||||||
sys, err = eventlog.OpenRemote(host, tag)
|
sys, err = eventlog.OpenRemote(host, tag)
|
||||||
} else {
|
} else {
|
||||||
if err = windowsRegister(tag); err != nil {
|
if err = windowsRegister(tag); err != nil {
|
||||||
@@ -146,7 +148,7 @@ func newSyslog(net NetworkType, host, tag string, facility SyslogFacility) (sysl
|
|||||||
}
|
}
|
||||||
|
|
||||||
return &_WinLog{
|
return &_WinLog{
|
||||||
r: net != NetworkEmpty,
|
r: net != libptc.NetworkEmpty,
|
||||||
s: tag,
|
s: tag,
|
||||||
w: sys,
|
w: sys,
|
||||||
}, nil
|
}, nil
|
||||||
110
logger/hooksyslog/system.go
Normal file
110
logger/hooksyslog/system.go
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
/***********************************************************************************************************************
|
||||||
|
*
|
||||||
|
* 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 hooksyslog
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (o *hks) Run(ctx context.Context) {
|
||||||
|
var (
|
||||||
|
s Wrapper
|
||||||
|
w = sync.WaitGroup{}
|
||||||
|
e error
|
||||||
|
)
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
if s != nil {
|
||||||
|
w.Wait()
|
||||||
|
_ = s.Close()
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
for {
|
||||||
|
if s, e = o.getSyslog(); e != nil {
|
||||||
|
fmt.Println(e.Error())
|
||||||
|
} else {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
time.Sleep(time.Second)
|
||||||
|
}
|
||||||
|
|
||||||
|
o.prepareChan()
|
||||||
|
fmt.Printf("starting hook for log syslog '%s'\n", o.getSyslogInfo())
|
||||||
|
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
return
|
||||||
|
|
||||||
|
case <-o.Done():
|
||||||
|
return
|
||||||
|
|
||||||
|
case i := <-o.Data():
|
||||||
|
w.Add(1)
|
||||||
|
go o.writeWrapper(s, i, w.Done)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *hks) writeWrapper(w Wrapper, d data, done func()) {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
defer done()
|
||||||
|
|
||||||
|
if w == nil {
|
||||||
|
return
|
||||||
|
} else if len(d.p) < 1 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
switch d.s {
|
||||||
|
case SyslogSeverityAlert:
|
||||||
|
_, err = w.Panic(d.p)
|
||||||
|
case SyslogSeverityCrit:
|
||||||
|
_, err = w.Fatal(d.p)
|
||||||
|
case SyslogSeverityErr:
|
||||||
|
_, err = w.Error(d.p)
|
||||||
|
case SyslogSeverityWarning:
|
||||||
|
_, err = w.Warning(d.p)
|
||||||
|
case SyslogSeverityInfo:
|
||||||
|
_, err = w.Info(d.p)
|
||||||
|
case SyslogSeverityDebug:
|
||||||
|
_, err = w.Debug(d.p)
|
||||||
|
default:
|
||||||
|
_, err = w.Write(d.p)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
41
logger/hooksyslog/wrapper.go
Normal file
41
logger/hooksyslog/wrapper.go
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
/***********************************************************************************************************************
|
||||||
|
*
|
||||||
|
* 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 hooksyslog
|
||||||
|
|
||||||
|
import "io"
|
||||||
|
|
||||||
|
type Wrapper 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)
|
||||||
|
}
|
||||||
@@ -31,68 +31,64 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
"sync"
|
"sync"
|
||||||
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
libctx "github.com/nabbar/golib/context"
|
|
||||||
iotclo "github.com/nabbar/golib/ioutils/mapCloser"
|
iotclo "github.com/nabbar/golib/ioutils/mapCloser"
|
||||||
|
|
||||||
"github.com/hashicorp/go-hclog"
|
libctx "github.com/nabbar/golib/context"
|
||||||
|
logcfg "github.com/nabbar/golib/logger/config"
|
||||||
|
logent "github.com/nabbar/golib/logger/entry"
|
||||||
|
logfld "github.com/nabbar/golib/logger/fields"
|
||||||
|
loglvl "github.com/nabbar/golib/logger/level"
|
||||||
jww "github.com/spf13/jwalterweatherman"
|
jww "github.com/spf13/jwalterweatherman"
|
||||||
)
|
)
|
||||||
|
|
||||||
type FuncLog func() Logger
|
type FuncLog func() Logger
|
||||||
type FuncOpt func() *Options
|
|
||||||
|
|
||||||
type Logger interface {
|
type Logger interface {
|
||||||
io.WriteCloser
|
io.WriteCloser
|
||||||
|
|
||||||
//SetLevel allow to change the minimal level of log message
|
//SetLevel allow to change the minimal level of log message
|
||||||
SetLevel(lvl Level)
|
SetLevel(lvl loglvl.Level)
|
||||||
|
|
||||||
//GetLevel return the minimal level of log message
|
//GetLevel return the minimal level of log message
|
||||||
GetLevel() Level
|
GetLevel() loglvl.Level
|
||||||
|
|
||||||
//SetIOWriterLevel allow to change the minimal level of log message for io.WriterCloser interface
|
//SetIOWriterLevel allow to change the minimal level of log message for io.WriterCloser interface
|
||||||
SetIOWriterLevel(lvl Level)
|
SetIOWriterLevel(lvl loglvl.Level)
|
||||||
|
|
||||||
//GetIOWriterLevel return the minimal level of log message for io.WriterCloser interface
|
//GetIOWriterLevel return the minimal level of log message for io.WriterCloser interface
|
||||||
GetIOWriterLevel() Level
|
GetIOWriterLevel() loglvl.Level
|
||||||
|
|
||||||
// SetIOWriterFilter allow to filter message that contained the given pattern. If the pattern is found, the log is drop.
|
// SetIOWriterFilter allow to filter message that contained the given pattern. If the pattern is found, the log is drop.
|
||||||
SetIOWriterFilter(pattern string)
|
SetIOWriterFilter(pattern string)
|
||||||
|
|
||||||
//SetOptions allow to set or update the options for the logger
|
//SetOptions allow to set or update the options for the logger
|
||||||
SetOptions(opt *Options) error
|
SetOptions(opt *logcfg.Options) error
|
||||||
|
|
||||||
//GetOptions return the options for the logger
|
//GetOptions return the options for the logger
|
||||||
GetOptions() *Options
|
GetOptions() *logcfg.Options
|
||||||
|
|
||||||
//SetFields allow to set or update the default fields for all logger entry
|
//SetFields allow to set or update the default fields for all logger entry
|
||||||
// Fields are custom information added into log message
|
// Fields are custom information added into log message
|
||||||
SetFields(field Fields)
|
SetFields(field logfld.Fields)
|
||||||
|
|
||||||
//GetFields return the default fields for all logger entry
|
//GetFields return the default fields for all logger entry
|
||||||
// Fields are custom information added into log message
|
// Fields are custom information added into log message
|
||||||
GetFields() Fields
|
GetFields() logfld.Fields
|
||||||
|
|
||||||
//Clone allow to duplicate the logger with a copy of the logger
|
//Clone allow to duplicate the logger with a copy of the logger
|
||||||
Clone() Logger
|
Clone() Logger
|
||||||
|
|
||||||
//SetSPF13Level allow to plus spf13 logger (jww) to this logger
|
//SetSPF13Level allow to plus spf13 logger (jww) to this logger
|
||||||
SetSPF13Level(lvl Level, log *jww.Notepad)
|
SetSPF13Level(lvl loglvl.Level, log *jww.Notepad)
|
||||||
|
|
||||||
//GetStdLogger return a golang log.logger instance linked with this main logger.
|
//GetStdLogger return a golang log.logger instance linked with this main logger.
|
||||||
GetStdLogger(lvl Level, logFlags int) *log.Logger
|
GetStdLogger(lvl loglvl.Level, logFlags int) *log.Logger
|
||||||
|
|
||||||
//SetStdLogger force the default golang log.logger instance linked with this main logger.
|
//SetStdLogger force the default golang log.logger instance linked with this main logger.
|
||||||
SetStdLogger(lvl Level, logFlags int)
|
SetStdLogger(lvl loglvl.Level, logFlags int)
|
||||||
|
|
||||||
//SetHashicorpHCLog force mapping default Hshicorp logger hclog to current logger
|
|
||||||
SetHashicorpHCLog()
|
|
||||||
|
|
||||||
//NewHashicorpHCLog return a new Hshicorp logger hclog mapped current logger
|
|
||||||
NewHashicorpHCLog() hclog.Logger
|
|
||||||
|
|
||||||
//Debug add an entry with DebugLevel to the logger
|
//Debug add an entry with DebugLevel to the logger
|
||||||
Debug(message string, data interface{}, args ...interface{})
|
Debug(message string, data interface{}, args ...interface{})
|
||||||
@@ -115,17 +111,17 @@ type Logger interface {
|
|||||||
Panic(message string, data interface{}, args ...interface{})
|
Panic(message string, data interface{}, args ...interface{})
|
||||||
|
|
||||||
//LogDetails add an entry to the logger
|
//LogDetails add an entry to the logger
|
||||||
LogDetails(lvl Level, message string, data interface{}, err []error, fields Fields, args ...interface{})
|
LogDetails(lvl loglvl.Level, message string, data interface{}, err []error, fields logfld.Fields, args ...interface{})
|
||||||
|
|
||||||
//CheckError will check if a not nil error is given and if yes, will add an entry to the logger.
|
//CheckError will check if a not nil error is given and if yes, will add an entry to the logger.
|
||||||
// Othwise if the lvlOK is given (and not NilLevel) the function will add entry and said ok
|
// Othwise if the lvlOK is given (and not NilLevel) the function will add entry and said ok
|
||||||
CheckError(lvlKO, lvlOK Level, message string, err ...error) bool
|
CheckError(lvlKO, lvlOK loglvl.Level, message string, err ...error) bool
|
||||||
|
|
||||||
//Entry will return an entry struct to manage it (set gin context, add fields, log the entry...)
|
//Entry will return an entry struct to manage it (set gin context, add fields, log the entry...)
|
||||||
Entry(lvl Level, message string, args ...interface{}) *Entry
|
Entry(lvl loglvl.Level, message string, args ...interface{}) logent.Entry
|
||||||
|
|
||||||
//Access will return an entry struct to store info level access log message
|
//Access will return an entry struct to store info level access log message
|
||||||
Access(remoteAddr, remoteUser string, localtime time.Time, latency time.Duration, method, request, proto string, status int, size int64) *Entry
|
Access(remoteAddr, remoteUser string, localtime time.Time, latency time.Duration, method, request, proto string, status int, size int64) logent.Entry
|
||||||
}
|
}
|
||||||
|
|
||||||
// New return a new logger interface pointer
|
// New return a new logger interface pointer
|
||||||
@@ -133,11 +129,12 @@ func New(ctx libctx.FuncContext) Logger {
|
|||||||
l := &logger{
|
l := &logger{
|
||||||
m: sync.RWMutex{},
|
m: sync.RWMutex{},
|
||||||
x: libctx.NewConfig[uint8](ctx),
|
x: libctx.NewConfig[uint8](ctx),
|
||||||
f: NewFields(ctx),
|
f: logfld.New(ctx),
|
||||||
c: iotclo.New(ctx),
|
c: new(atomic.Value),
|
||||||
}
|
}
|
||||||
|
|
||||||
l.SetLevel(InfoLevel)
|
l.c.Store(iotclo.New(ctx))
|
||||||
|
l.SetLevel(loglvl.InfoLevel)
|
||||||
|
|
||||||
return l
|
return l
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
/*
|
/***********************************************************************************************************************
|
||||||
|
*
|
||||||
* MIT License
|
* MIT License
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020 Nicolas JUHEL
|
* Copyright (c) 2021 Nicolas JUHEL
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -21,7 +22,8 @@
|
|||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*
|
*
|
||||||
*/
|
*
|
||||||
|
**********************************************************************************************************************/
|
||||||
|
|
||||||
package logger_test
|
package logger_test
|
||||||
|
|
||||||
@@ -30,9 +32,11 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
liblog "github.com/nabbar/golib/logger"
|
||||||
|
logcfg "github.com/nabbar/golib/logger/config"
|
||||||
|
logfld "github.com/nabbar/golib/logger/fields"
|
||||||
|
loglvl "github.com/nabbar/golib/logger/level"
|
||||||
libsem "github.com/nabbar/golib/semaphore"
|
libsem "github.com/nabbar/golib/semaphore"
|
||||||
|
|
||||||
"github.com/nabbar/golib/logger"
|
|
||||||
. "github.com/onsi/ginkgo/v2"
|
. "github.com/onsi/ginkgo/v2"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
)
|
)
|
||||||
@@ -52,40 +56,58 @@ func getLogFileTemp() string {
|
|||||||
var _ = Describe("Logger", func() {
|
var _ = Describe("Logger", func() {
|
||||||
Context("Create New Logger with Default Config", func() {
|
Context("Create New Logger with Default Config", func() {
|
||||||
It("Must succeed", func() {
|
It("Must succeed", func() {
|
||||||
log := logger.New(GetContext)
|
log := liblog.New(GetContext)
|
||||||
log.SetLevel(logger.DebugLevel)
|
defer func() {
|
||||||
err := log.SetOptions(&logger.Options{})
|
Expect(log.Close()).ToNot(HaveOccurred())
|
||||||
|
}()
|
||||||
|
log.SetLevel(loglvl.DebugLevel)
|
||||||
|
err := log.SetOptions(&logcfg.Options{
|
||||||
|
Stdout: &logcfg.OptionsStd{},
|
||||||
|
})
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
log.LogDetails(logger.InfoLevel, "test logger", nil, nil, nil)
|
log.LogDetails(loglvl.InfoLevel, "test logger", nil, nil, nil)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
Context("Create New Logger with Default Config and trace", func() {
|
Context("Create New Logger with Default Config and trace", func() {
|
||||||
It("Must succeed", func() {
|
It("Must succeed", func() {
|
||||||
log := logger.New(GetContext)
|
log := liblog.New(GetContext)
|
||||||
log.SetLevel(logger.DebugLevel)
|
defer func() {
|
||||||
err := log.SetOptions(&logger.Options{
|
Expect(log.Close()).ToNot(HaveOccurred())
|
||||||
|
}()
|
||||||
|
log.SetLevel(loglvl.DebugLevel)
|
||||||
|
err := log.SetOptions(&logcfg.Options{
|
||||||
|
Stdout: &logcfg.OptionsStd{
|
||||||
EnableTrace: true,
|
EnableTrace: true,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
log.LogDetails(logger.InfoLevel, "test logger with trace", nil, nil, nil)
|
log.LogDetails(loglvl.InfoLevel, "test logger with trace", nil, nil, nil)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
Context("Create New Logger with field", func() {
|
Context("Create New Logger with field", func() {
|
||||||
It("Must succeed", func() {
|
It("Must succeed", func() {
|
||||||
log := logger.New(GetContext)
|
log := liblog.New(GetContext)
|
||||||
log.SetLevel(logger.DebugLevel)
|
defer func() {
|
||||||
err := log.SetOptions(&logger.Options{
|
Expect(log.Close()).ToNot(HaveOccurred())
|
||||||
|
}()
|
||||||
|
log.SetLevel(loglvl.DebugLevel)
|
||||||
|
err := log.SetOptions(&logcfg.Options{
|
||||||
|
Stdout: &logcfg.OptionsStd{
|
||||||
EnableTrace: true,
|
EnableTrace: true,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
log.SetFields(logger.NewFields(GetContext).Add("test-field", "ok"))
|
log.SetFields(logfld.New(GetContext).Add("test-field", "ok"))
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
log.LogDetails(logger.InfoLevel, "test logger with field", nil, nil, nil)
|
log.LogDetails(loglvl.InfoLevel, "test logger with field", nil, nil, nil)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
Context("Create New Logger with file", func() {
|
Context("Create New Logger with file", func() {
|
||||||
It("Must succeed", func() {
|
It("Must succeed", func() {
|
||||||
log := logger.New(GetContext)
|
log := liblog.New(GetContext)
|
||||||
log.SetLevel(logger.DebugLevel)
|
defer func() {
|
||||||
|
Expect(log.Close()).ToNot(HaveOccurred())
|
||||||
|
}()
|
||||||
|
log.SetLevel(loglvl.DebugLevel)
|
||||||
|
|
||||||
fsp, err := GetTempFile()
|
fsp, err := GetTempFile()
|
||||||
|
|
||||||
@@ -96,16 +118,16 @@ var _ = Describe("Logger", func() {
|
|||||||
|
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
err = log.SetOptions(&logger.Options{
|
err = log.SetOptions(&logcfg.Options{
|
||||||
|
Stdout: &logcfg.OptionsStd{
|
||||||
EnableTrace: true,
|
EnableTrace: true,
|
||||||
LogFile: []logger.OptionsFile{
|
},
|
||||||
|
LogFile: []logcfg.OptionsFile{
|
||||||
{
|
{
|
||||||
LogLevel: nil,
|
LogLevel: nil,
|
||||||
Filepath: fsp,
|
Filepath: fsp,
|
||||||
Create: true,
|
Create: true,
|
||||||
CreatePath: true,
|
CreatePath: true,
|
||||||
//FileMode: 0644,
|
|
||||||
//PathMode: 0755,
|
|
||||||
DisableStack: false,
|
DisableStack: false,
|
||||||
DisableTimestamp: false,
|
DisableTimestamp: false,
|
||||||
EnableTrace: true,
|
EnableTrace: true,
|
||||||
@@ -114,14 +136,17 @@ var _ = Describe("Logger", func() {
|
|||||||
})
|
})
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
log.SetFields(logger.NewFields(GetContext).Add("test-field", "ok"))
|
log.SetFields(logfld.New(GetContext).Add("test-field", "ok"))
|
||||||
log.LogDetails(logger.InfoLevel, "test logger with field", nil, nil, nil)
|
log.LogDetails(loglvl.InfoLevel, "test logger with field", nil, nil, nil)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
Context("Create New Logger with file in multithreading mode", func() {
|
Context("Create New Logger with file in multithreading mode", func() {
|
||||||
It("Must succeed", func() {
|
It("Must succeed", func() {
|
||||||
log := logger.New(GetContext)
|
log := liblog.New(GetContext)
|
||||||
log.SetLevel(logger.DebugLevel)
|
defer func() {
|
||||||
|
Expect(log.Close()).ToNot(HaveOccurred())
|
||||||
|
}()
|
||||||
|
log.SetLevel(loglvl.DebugLevel)
|
||||||
|
|
||||||
fsp, err := GetTempFile()
|
fsp, err := GetTempFile()
|
||||||
|
|
||||||
@@ -132,16 +157,16 @@ var _ = Describe("Logger", func() {
|
|||||||
|
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
err = log.SetOptions(&logger.Options{
|
err = log.SetOptions(&logcfg.Options{
|
||||||
|
Stdout: &logcfg.OptionsStd{
|
||||||
EnableTrace: true,
|
EnableTrace: true,
|
||||||
LogFile: []logger.OptionsFile{
|
},
|
||||||
|
LogFile: []logcfg.OptionsFile{
|
||||||
{
|
{
|
||||||
LogLevel: nil,
|
LogLevel: nil,
|
||||||
Filepath: fsp,
|
Filepath: fsp,
|
||||||
Create: true,
|
Create: true,
|
||||||
CreatePath: true,
|
CreatePath: true,
|
||||||
//FileMode: 0644,
|
|
||||||
//PathMode: 0755,
|
|
||||||
DisableStack: false,
|
DisableStack: false,
|
||||||
DisableTimestamp: false,
|
DisableTimestamp: false,
|
||||||
EnableTrace: true,
|
EnableTrace: true,
|
||||||
@@ -150,25 +175,25 @@ var _ = Describe("Logger", func() {
|
|||||||
})
|
})
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
log.SetFields(logger.NewFields(GetContext).Add("test-field", "ok"))
|
log.SetFields(logfld.New(GetContext).Add("test-field", "ok"))
|
||||||
log.LogDetails(logger.InfoLevel, "test logger with field", nil, nil, nil)
|
log.LogDetails(loglvl.InfoLevel, "test logger with field", nil, nil, nil)
|
||||||
|
|
||||||
var sub logger.Logger
|
var sub liblog.Logger
|
||||||
sub = log.Clone()
|
sub = log.Clone()
|
||||||
|
|
||||||
go func(log logger.Logger) {
|
go func(log liblog.Logger) {
|
||||||
defer func() {
|
defer func() {
|
||||||
se := log.Close()
|
se := log.Close()
|
||||||
Expect(se).ToNot(HaveOccurred())
|
Expect(se).ToNot(HaveOccurred())
|
||||||
}()
|
}()
|
||||||
|
|
||||||
log.SetFields(logger.NewFields(GetContext).Add("logger", "sub"))
|
log.SetFields(logfld.New(GetContext).Add("logger", "sub"))
|
||||||
for i := 0; i < 10; i++ {
|
for i := 0; i < 10; i++ {
|
||||||
log.Entry(logger.InfoLevel, "test multithreading logger").FieldAdd("id", i).Log()
|
log.Entry(loglvl.InfoLevel, "test multithreading logger").FieldAdd("id", i).Log()
|
||||||
}
|
}
|
||||||
}(sub)
|
}(sub)
|
||||||
|
|
||||||
log.SetFields(logger.NewFields(GetContext).Add("logger", "main"))
|
log.SetFields(logfld.New(GetContext).Add("logger", "main"))
|
||||||
sem := libsem.NewSemaphoreWithContext(context.Background(), 0)
|
sem := libsem.NewSemaphoreWithContext(context.Background(), 0)
|
||||||
defer sem.DeferMain()
|
defer sem.DeferMain()
|
||||||
|
|
||||||
@@ -177,7 +202,7 @@ var _ = Describe("Logger", func() {
|
|||||||
|
|
||||||
go func(id int) {
|
go func(id int) {
|
||||||
defer sem.DeferWorker()
|
defer sem.DeferWorker()
|
||||||
ent := log.Entry(logger.InfoLevel, "test multithreading logger")
|
ent := log.Entry(loglvl.InfoLevel, "test multithreading logger")
|
||||||
ent.FieldAdd("id", id)
|
ent.FieldAdd("id", id)
|
||||||
ent.Log()
|
ent.Log()
|
||||||
}(i)
|
}(i)
|
||||||
|
|||||||
@@ -29,21 +29,13 @@ package logger
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
loglvl "github.com/nabbar/golib/logger/level"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (o *logger) Close() error {
|
func (o *logger) Close() error {
|
||||||
if o == nil {
|
return o.switchCloser(o.newCloser()).Close()
|
||||||
return fmt.Errorf("not initialized")
|
|
||||||
} else if o.c == nil {
|
|
||||||
return fmt.Errorf("not initialized")
|
|
||||||
}
|
|
||||||
|
|
||||||
_ = o.c.Close()
|
|
||||||
o.c.Clean()
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *logger) Write(p []byte) (n int, err error) {
|
func (o *logger) Write(p []byte) (n int, err error) {
|
||||||
@@ -63,7 +55,7 @@ func (o *logger) Write(p []byte) (n int, err error) {
|
|||||||
return len(p), nil
|
return len(p), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *logger) SetIOWriterLevel(lvl Level) {
|
func (o *logger) SetIOWriterLevel(lvl loglvl.Level) {
|
||||||
if o == nil {
|
if o == nil {
|
||||||
return
|
return
|
||||||
} else if o.x == nil {
|
} else if o.x == nil {
|
||||||
@@ -72,15 +64,15 @@ func (o *logger) SetIOWriterLevel(lvl Level) {
|
|||||||
|
|
||||||
o.x.Store(keyWriter, lvl)
|
o.x.Store(keyWriter, lvl)
|
||||||
}
|
}
|
||||||
func (o *logger) GetIOWriterLevel() Level {
|
func (o *logger) GetIOWriterLevel() loglvl.Level {
|
||||||
if o == nil {
|
if o == nil {
|
||||||
return NilLevel
|
return loglvl.NilLevel
|
||||||
} else if o.x == nil {
|
} else if o.x == nil {
|
||||||
return NilLevel
|
return loglvl.NilLevel
|
||||||
} else if i, l := o.x.Load(keyWriter); !l {
|
} else if i, l := o.x.Load(keyWriter); !l {
|
||||||
return NilLevel
|
return loglvl.NilLevel
|
||||||
} else if v, k := i.(Level); !k {
|
} else if v, k := i.(loglvl.Level); !k {
|
||||||
return NilLevel
|
return loglvl.NilLevel
|
||||||
} else {
|
} else {
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
|
|||||||
140
logger/level.go
140
logger/level.go
@@ -1,140 +0,0 @@
|
|||||||
/*
|
|
||||||
MIT License
|
|
||||||
|
|
||||||
Copyright (c) 2019 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 (
|
|
||||||
"math"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/sirupsen/logrus"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Level a uint8 type customized with function to log message with the current log level.
|
|
||||||
type Level uint8
|
|
||||||
|
|
||||||
const (
|
|
||||||
// PanicLevel Panic level for entry log, will result on a Panic() call (trace + fatal).
|
|
||||||
PanicLevel Level = iota
|
|
||||||
// FatalLevel Fatal level for entry log, will result on os.Exit with error.
|
|
||||||
FatalLevel
|
|
||||||
// ErrorLevel Error level for entry log who's meaning the caller stop his process and return to the pre caller.
|
|
||||||
ErrorLevel
|
|
||||||
// WarnLevel Warning level for entry log who's meaning the caller don't stop his process and try to continue it.
|
|
||||||
WarnLevel
|
|
||||||
// InfoLevel Info level for entry log who's meaning it is just an information who's have no impact on caller's process but can be useful to inform human of a state, event, success, ...
|
|
||||||
InfoLevel
|
|
||||||
// DebugLevel Debug level for entry log who's meaning the caller has no problem and the information is only useful to identify a potential problem who's can arrive later.
|
|
||||||
DebugLevel
|
|
||||||
// NilLevel Nil level will never log anything and is used to completely disable current log entry. It cannot be used in the SetLogLevel function.
|
|
||||||
NilLevel
|
|
||||||
)
|
|
||||||
|
|
||||||
// GetLevelListString return a list ([]string) of all string loglevel available.
|
|
||||||
func GetLevelListString() []string {
|
|
||||||
return []string{
|
|
||||||
strings.ToLower(PanicLevel.String()),
|
|
||||||
strings.ToLower(FatalLevel.String()),
|
|
||||||
strings.ToLower(ErrorLevel.String()),
|
|
||||||
strings.ToLower(WarnLevel.String()),
|
|
||||||
strings.ToLower(InfoLevel.String()),
|
|
||||||
strings.ToLower(DebugLevel.String()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetLevelString return a valid Level Type matching the given string parameter.
|
|
||||||
// If the given parameter don't represent a valid level, the InfoLevel will be return.
|
|
||||||
/*
|
|
||||||
level the string representation of a Level type
|
|
||||||
*/
|
|
||||||
func GetLevelString(l string) Level {
|
|
||||||
switch {
|
|
||||||
case strings.EqualFold(PanicLevel.String(), l):
|
|
||||||
return PanicLevel
|
|
||||||
|
|
||||||
case strings.EqualFold(FatalLevel.String(), l):
|
|
||||||
return FatalLevel
|
|
||||||
|
|
||||||
case strings.EqualFold(ErrorLevel.String(), l):
|
|
||||||
return ErrorLevel
|
|
||||||
|
|
||||||
case strings.EqualFold(WarnLevel.String(), l):
|
|
||||||
return WarnLevel
|
|
||||||
|
|
||||||
case strings.EqualFold(InfoLevel.String(), l):
|
|
||||||
return InfoLevel
|
|
||||||
|
|
||||||
case strings.EqualFold(DebugLevel.String(), l):
|
|
||||||
return DebugLevel
|
|
||||||
}
|
|
||||||
|
|
||||||
return InfoLevel
|
|
||||||
}
|
|
||||||
|
|
||||||
// Uint8 Convert the current Level type to a uint8 value. E.g. FatalLevel becomes 1.
|
|
||||||
func (l Level) Uint8() uint8 {
|
|
||||||
return uint8(l)
|
|
||||||
}
|
|
||||||
|
|
||||||
// String Convert the current Level type to a string. E.g. PanicLevel becomes "Critical Error".
|
|
||||||
func (l Level) String() string {
|
|
||||||
//nolint exhaustive
|
|
||||||
switch l {
|
|
||||||
case DebugLevel:
|
|
||||||
return "Debug"
|
|
||||||
case InfoLevel:
|
|
||||||
return "Info"
|
|
||||||
case WarnLevel:
|
|
||||||
return "Warning"
|
|
||||||
case ErrorLevel:
|
|
||||||
return "Error"
|
|
||||||
case FatalLevel:
|
|
||||||
return "Fatal"
|
|
||||||
case PanicLevel:
|
|
||||||
return "Critical"
|
|
||||||
case NilLevel:
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
return "unknown"
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l Level) Logrus() logrus.Level {
|
|
||||||
switch l {
|
|
||||||
case DebugLevel:
|
|
||||||
return logrus.DebugLevel
|
|
||||||
case InfoLevel:
|
|
||||||
return logrus.InfoLevel
|
|
||||||
case WarnLevel:
|
|
||||||
return logrus.WarnLevel
|
|
||||||
case ErrorLevel:
|
|
||||||
return logrus.ErrorLevel
|
|
||||||
case FatalLevel:
|
|
||||||
return logrus.FatalLevel
|
|
||||||
case PanicLevel:
|
|
||||||
return logrus.PanicLevel
|
|
||||||
default:
|
|
||||||
return math.MaxInt32
|
|
||||||
}
|
|
||||||
}
|
|
||||||
93
logger/level/interface.go
Normal file
93
logger/level/interface.go
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
/***********************************************************************************************************************
|
||||||
|
*
|
||||||
|
* 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 level
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Level a uint8 type customized with function to log message with the current log level.
|
||||||
|
type Level uint8
|
||||||
|
|
||||||
|
const (
|
||||||
|
// PanicLevel Panic level for entry log, will result on a Panic() call (trace + fatal).
|
||||||
|
PanicLevel Level = iota
|
||||||
|
// FatalLevel Fatal level for entry log, will result on os.Exit with error.
|
||||||
|
FatalLevel
|
||||||
|
// ErrorLevel Error level for entry log who's meaning the caller stop his process and return to the pre caller.
|
||||||
|
ErrorLevel
|
||||||
|
// WarnLevel Warning level for entry log who's meaning the caller don't stop his process and try to continue it.
|
||||||
|
WarnLevel
|
||||||
|
// InfoLevel Info level for entry log who's meaning it is just an information who's have no impact on caller's process but can be useful to inform human of a state, event, success, ...
|
||||||
|
InfoLevel
|
||||||
|
// DebugLevel Debug level for entry log who's meaning the caller has no problem and the information is only useful to identify a potential problem who's can arrive later.
|
||||||
|
DebugLevel
|
||||||
|
// NilLevel Nil level will never log anything and is used to completely disable current log entry. It cannot be used in the SetLogLevel function.
|
||||||
|
NilLevel
|
||||||
|
)
|
||||||
|
|
||||||
|
// ListLevels return a list ([]string) of all string loglevel available.
|
||||||
|
func ListLevels() []string {
|
||||||
|
return []string{
|
||||||
|
strings.ToLower(PanicLevel.String()),
|
||||||
|
strings.ToLower(FatalLevel.String()),
|
||||||
|
strings.ToLower(ErrorLevel.String()),
|
||||||
|
strings.ToLower(WarnLevel.String()),
|
||||||
|
strings.ToLower(InfoLevel.String()),
|
||||||
|
strings.ToLower(DebugLevel.String()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse return a valid Level Type matching the given string parameter.
|
||||||
|
// If the given parameter don't represent a valid level, the InfoLevel will be return.
|
||||||
|
/*
|
||||||
|
level the string representation of a Level type
|
||||||
|
*/
|
||||||
|
func Parse(l string) Level {
|
||||||
|
switch {
|
||||||
|
case strings.EqualFold(PanicLevel.String(), l):
|
||||||
|
return PanicLevel
|
||||||
|
|
||||||
|
case strings.EqualFold(FatalLevel.String(), l):
|
||||||
|
return FatalLevel
|
||||||
|
|
||||||
|
case strings.EqualFold(ErrorLevel.String(), l):
|
||||||
|
return ErrorLevel
|
||||||
|
|
||||||
|
case strings.EqualFold(WarnLevel.String(), l):
|
||||||
|
return WarnLevel
|
||||||
|
|
||||||
|
case strings.EqualFold(InfoLevel.String(), l):
|
||||||
|
return InfoLevel
|
||||||
|
|
||||||
|
case strings.EqualFold(DebugLevel.String(), l):
|
||||||
|
return DebugLevel
|
||||||
|
}
|
||||||
|
|
||||||
|
return InfoLevel
|
||||||
|
}
|
||||||
81
logger/level/model.go
Normal file
81
logger/level/model.go
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
/***********************************************************************************************************************
|
||||||
|
*
|
||||||
|
* 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 level
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math"
|
||||||
|
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Uint8 Convert the current Level type to a uint8 value. E.g. FatalLevel becomes 1.
|
||||||
|
func (l Level) Uint8() uint8 {
|
||||||
|
return uint8(l)
|
||||||
|
}
|
||||||
|
|
||||||
|
// String Convert the current Level type to a string. E.g. PanicLevel becomes "Critical Error".
|
||||||
|
func (l Level) String() string {
|
||||||
|
//nolint exhaustive
|
||||||
|
switch l {
|
||||||
|
case DebugLevel:
|
||||||
|
return "Debug"
|
||||||
|
case InfoLevel:
|
||||||
|
return "Info"
|
||||||
|
case WarnLevel:
|
||||||
|
return "Warning"
|
||||||
|
case ErrorLevel:
|
||||||
|
return "Error"
|
||||||
|
case FatalLevel:
|
||||||
|
return "Fatal"
|
||||||
|
case PanicLevel:
|
||||||
|
return "Critical"
|
||||||
|
case NilLevel:
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
return "unknown"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l Level) Logrus() logrus.Level {
|
||||||
|
switch l {
|
||||||
|
case DebugLevel:
|
||||||
|
return logrus.DebugLevel
|
||||||
|
case InfoLevel:
|
||||||
|
return logrus.InfoLevel
|
||||||
|
case WarnLevel:
|
||||||
|
return logrus.WarnLevel
|
||||||
|
case ErrorLevel:
|
||||||
|
return logrus.ErrorLevel
|
||||||
|
case FatalLevel:
|
||||||
|
return logrus.FatalLevel
|
||||||
|
case PanicLevel:
|
||||||
|
return logrus.PanicLevel
|
||||||
|
default:
|
||||||
|
return math.MaxInt32
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -30,109 +30,70 @@ package logger
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
logent "github.com/nabbar/golib/logger/entry"
|
||||||
|
logfld "github.com/nabbar/golib/logger/fields"
|
||||||
|
loglvl "github.com/nabbar/golib/logger/level"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (o *logger) Debug(message string, data interface{}, args ...interface{}) {
|
func (o *logger) Debug(message string, data interface{}, args ...interface{}) {
|
||||||
o.newEntry(DebugLevel, fmt.Sprintf(message, args...), nil, nil, data).Log()
|
o.newEntry(loglvl.DebugLevel, fmt.Sprintf(message, args...), nil, nil, data).Log()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *logger) Info(message string, data interface{}, args ...interface{}) {
|
func (o *logger) Info(message string, data interface{}, args ...interface{}) {
|
||||||
o.newEntry(InfoLevel, fmt.Sprintf(message, args...), nil, nil, data).Log()
|
o.newEntry(loglvl.InfoLevel, fmt.Sprintf(message, args...), nil, nil, data).Log()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *logger) Warning(message string, data interface{}, args ...interface{}) {
|
func (o *logger) Warning(message string, data interface{}, args ...interface{}) {
|
||||||
o.newEntry(WarnLevel, fmt.Sprintf(message, args...), nil, nil, data).Log()
|
o.newEntry(loglvl.WarnLevel, fmt.Sprintf(message, args...), nil, nil, data).Log()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *logger) Error(message string, data interface{}, args ...interface{}) {
|
func (o *logger) Error(message string, data interface{}, args ...interface{}) {
|
||||||
o.newEntry(ErrorLevel, fmt.Sprintf(message, args...), nil, nil, data).Log()
|
o.newEntry(loglvl.ErrorLevel, fmt.Sprintf(message, args...), nil, nil, data).Log()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *logger) Fatal(message string, data interface{}, args ...interface{}) {
|
func (o *logger) Fatal(message string, data interface{}, args ...interface{}) {
|
||||||
o.newEntry(FatalLevel, fmt.Sprintf(message, args...), nil, nil, data).Log()
|
o.newEntry(loglvl.FatalLevel, fmt.Sprintf(message, args...), nil, nil, data).Log()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *logger) Panic(message string, data interface{}, args ...interface{}) {
|
func (o *logger) Panic(message string, data interface{}, args ...interface{}) {
|
||||||
o.newEntry(PanicLevel, fmt.Sprintf(message, args...), nil, nil, data).Log()
|
o.newEntry(loglvl.PanicLevel, fmt.Sprintf(message, args...), nil, nil, data).Log()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *logger) LogDetails(lvl Level, message string, data interface{}, err []error, fields Fields, args ...interface{}) {
|
func (o *logger) LogDetails(lvl loglvl.Level, message string, data interface{}, err []error, fields logfld.Fields, args ...interface{}) {
|
||||||
o.newEntry(lvl, fmt.Sprintf(message, args...), err, fields, data).Log()
|
o.newEntry(lvl, fmt.Sprintf(message, args...), err, fields, data).Log()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *logger) CheckError(lvlKO, lvlOK Level, message string, err ...error) bool {
|
func (o *logger) CheckError(lvlKO, lvlOK loglvl.Level, message string, err ...error) bool {
|
||||||
ent := o.newEntry(lvlKO, message, err, nil, nil)
|
ent := o.newEntry(lvlKO, message, err, nil, nil)
|
||||||
return ent.Check(lvlOK)
|
return ent.Check(lvlOK)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *logger) Entry(lvl Level, message string, args ...interface{}) *Entry {
|
func (o *logger) Entry(lvl loglvl.Level, message string, args ...interface{}) logent.Entry {
|
||||||
return o.newEntry(lvl, fmt.Sprintf(message, args...), nil, nil, nil)
|
return o.newEntry(lvl, fmt.Sprintf(message, args...), nil, nil, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *logger) Access(remoteAddr, remoteUser string, localtime time.Time, latency time.Duration, method, request, proto string, status int, size int64) *Entry {
|
func (o *logger) Access(remoteAddr, remoteUser string, localtime time.Time, latency time.Duration, method, request, proto string, status int, size int64) logent.Entry {
|
||||||
return o.newEntryClean(fmt.Sprintf("%s - %s [%s] [%s] \"%s %s %s\" %d %d", remoteAddr, remoteUser, localtime.Format(time.RFC1123Z), latency.String(), method, request, proto, status, size))
|
var msg = fmt.Sprintf("%s - %s [%s] [%s] \"%s %s %s\" %d %d", remoteAddr, remoteUser, localtime.Format(time.RFC1123Z), latency.String(), method, request, proto, status, size)
|
||||||
|
return o.newEntryClean(msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *logger) newEntry(lvl Level, message string, err []error, fields Fields, data interface{}) *Entry {
|
func (o *logger) newEntry(lvl loglvl.Level, message string, err []error, fields logfld.Fields, data interface{}) logent.Entry {
|
||||||
opt := o.GetOptions()
|
var (
|
||||||
cLv := o.GetLevel()
|
ent = logent.New(lvl)
|
||||||
|
frm = o.getCaller()
|
||||||
|
)
|
||||||
|
|
||||||
var ent = &Entry{
|
ent.ErrorSet(err)
|
||||||
clean: false,
|
ent.FieldSet(o.GetFields().FieldsClone(nil))
|
||||||
Time: time.Time{},
|
ent.DataSet(data)
|
||||||
Level: lvl,
|
ent.SetLogger(o.getLogrus)
|
||||||
Stack: 0,
|
ent.SetEntryContext(time.Now(), o.getStack(), frm.Function, frm.File, uint64(frm.Line), message)
|
||||||
Caller: "",
|
ent.FieldMerge(fields)
|
||||||
File: "",
|
|
||||||
Line: 0,
|
|
||||||
Error: err,
|
|
||||||
Fields: o.GetFields().FieldsClone(nil),
|
|
||||||
}
|
|
||||||
|
|
||||||
if cLv == NilLevel || lvl > cLv {
|
|
||||||
return ent
|
|
||||||
} else {
|
|
||||||
ent.log = o.getLogrus
|
|
||||||
ent.Message = message
|
|
||||||
ent.Data = data
|
|
||||||
}
|
|
||||||
|
|
||||||
ent.Fields.Merge(fields)
|
|
||||||
|
|
||||||
if !opt.DisableTimestamp {
|
|
||||||
ent.Time = time.Now()
|
|
||||||
}
|
|
||||||
|
|
||||||
if !opt.DisableStack {
|
|
||||||
ent.Stack = o.getStack()
|
|
||||||
}
|
|
||||||
|
|
||||||
if opt.EnableTrace {
|
|
||||||
frm := o.getCaller()
|
|
||||||
|
|
||||||
if frm.Function != "" {
|
|
||||||
ent.Caller = frm.Function
|
|
||||||
}
|
|
||||||
|
|
||||||
if frm.File != "" {
|
|
||||||
ent.File = o.filterPath(frm.File)
|
|
||||||
}
|
|
||||||
|
|
||||||
if frm.Line > 0 {
|
|
||||||
ent.Line = uint32(frm.Line)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ent
|
return ent
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *logger) newEntryClean(message string) *Entry {
|
func (o *logger) newEntryClean(message string) logent.Entry {
|
||||||
var ent = &Entry{
|
return o.newEntry(loglvl.InfoLevel, message, nil, nil, nil).SetMessageOnly(true)
|
||||||
log: o.getLogrus,
|
|
||||||
clean: true,
|
|
||||||
Message: message,
|
|
||||||
Fields: NewFields(o.x.GetContext),
|
|
||||||
}
|
|
||||||
|
|
||||||
return ent
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
/*
|
/***********************************************************************************************************************
|
||||||
|
*
|
||||||
* MIT License
|
* MIT License
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020 Nicolas JUHEL
|
* Copyright (c) 2021 Nicolas JUHEL
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -21,7 +22,8 @@
|
|||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*
|
*
|
||||||
*/
|
*
|
||||||
|
**********************************************************************************************************************/
|
||||||
|
|
||||||
package logger_test
|
package logger_test
|
||||||
|
|
||||||
|
|||||||
186
logger/manage.go
186
logger/manage.go
@@ -31,51 +31,111 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"io"
|
"io"
|
||||||
"sync"
|
"sync"
|
||||||
|
"sync/atomic"
|
||||||
|
"time"
|
||||||
|
|
||||||
iotclo "github.com/nabbar/golib/ioutils/mapCloser"
|
iotclo "github.com/nabbar/golib/ioutils/mapCloser"
|
||||||
|
logcfg "github.com/nabbar/golib/logger/config"
|
||||||
|
logfld "github.com/nabbar/golib/logger/fields"
|
||||||
|
logfil "github.com/nabbar/golib/logger/hookfile"
|
||||||
|
logerr "github.com/nabbar/golib/logger/hookstderr"
|
||||||
|
logout "github.com/nabbar/golib/logger/hookstdout"
|
||||||
|
logsys "github.com/nabbar/golib/logger/hooksyslog"
|
||||||
|
loglvl "github.com/nabbar/golib/logger/level"
|
||||||
|
logtps "github.com/nabbar/golib/logger/types"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func (o *logger) getCloser() iotclo.Closer {
|
||||||
|
i := o.c.Load()
|
||||||
|
if c, k := i.(iotclo.Closer); k && c != nil {
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
c := iotclo.New(o.x.GetContext)
|
||||||
|
o.c.Store(c)
|
||||||
|
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *logger) switchCloser(c iotclo.Closer) iotclo.Closer {
|
||||||
|
b := o.getCloser()
|
||||||
|
o.c.Store(c)
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *logger) newCloser() iotclo.Closer {
|
||||||
|
return iotclo.New(o.x.GetContext)
|
||||||
|
}
|
||||||
|
|
||||||
func (o *logger) Clone() Logger {
|
func (o *logger) Clone() Logger {
|
||||||
if o == nil {
|
if o == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
o.m.RLock()
|
l := &logger{
|
||||||
defer o.m.RUnlock()
|
|
||||||
|
|
||||||
return &logger{
|
|
||||||
x: o.x.Clone(nil),
|
|
||||||
m: sync.RWMutex{},
|
m: sync.RWMutex{},
|
||||||
|
x: o.x.Clone(nil),
|
||||||
f: o.f.FieldsClone(nil),
|
f: o.f.FieldsClone(nil),
|
||||||
c: o.c.Clone(),
|
c: new(atomic.Value),
|
||||||
|
}
|
||||||
|
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *logger) RegisterFuncUpdateLogger(fct func(log Logger)) {
|
||||||
|
o.x.Store(keyFctUpdLog, fct)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *logger) runFuncUpdateLogger() {
|
||||||
|
if i, l := o.x.Load(keyFctUpdLog); !l {
|
||||||
|
return
|
||||||
|
} else if f, k := i.(func(log Logger)); !k {
|
||||||
|
return
|
||||||
|
} else if f == nil {
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
f(o)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *logger) SetLevel(lvl Level) {
|
func (o *logger) RegisterFuncUpdateLevel(fct func(log Logger)) {
|
||||||
|
o.x.Store(keyFctUpdLvl, fct)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *logger) runFuncUpdateLevel() {
|
||||||
|
if i, l := o.x.Load(keyFctUpdLvl); !l {
|
||||||
|
return
|
||||||
|
} else if f, k := i.(func(log Logger)); !k {
|
||||||
|
return
|
||||||
|
} else if f == nil {
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
f(o)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *logger) SetLevel(lvl loglvl.Level) {
|
||||||
o.x.Store(keyLevel, lvl)
|
o.x.Store(keyLevel, lvl)
|
||||||
o.setLogrusLevel(o.GetLevel())
|
o.setLogrusLevel(o.GetLevel())
|
||||||
|
o.runFuncUpdateLevel()
|
||||||
if opt := o.GetOptions(); opt.change != nil {
|
|
||||||
opt.change(o)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *logger) GetLevel() Level {
|
func (o *logger) GetLevel() loglvl.Level {
|
||||||
if o == nil {
|
if o == nil {
|
||||||
return NilLevel
|
return loglvl.NilLevel
|
||||||
} else if o.x == nil {
|
} else if o.x == nil {
|
||||||
return NilLevel
|
return loglvl.NilLevel
|
||||||
} else if i, l := o.x.Load(keyLevel); !l {
|
} else if i, l := o.x.Load(keyLevel); !l {
|
||||||
return NilLevel
|
return loglvl.NilLevel
|
||||||
} else if v, k := i.(Level); !k {
|
} else if v, k := i.(loglvl.Level); !k {
|
||||||
return NilLevel
|
return loglvl.NilLevel
|
||||||
} else {
|
} else {
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *logger) SetFields(field Fields) {
|
func (o *logger) SetFields(field logfld.Fields) {
|
||||||
if o == nil {
|
if o == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -87,9 +147,9 @@ func (o *logger) SetFields(field Fields) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *logger) GetFields() Fields {
|
func (o *logger) GetFields() logfld.Fields {
|
||||||
if o == nil {
|
if o == nil {
|
||||||
return NewFields(context.Background)
|
return logfld.New(context.Background)
|
||||||
}
|
}
|
||||||
|
|
||||||
o.m.RLock()
|
o.m.RLock()
|
||||||
@@ -97,85 +157,97 @@ func (o *logger) GetFields() Fields {
|
|||||||
return o.f.FieldsClone(nil)
|
return o.f.FieldsClone(nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *logger) SetOptions(opt *Options) error {
|
func (o *logger) SetOptions(opt *logcfg.Options) error {
|
||||||
var (
|
var (
|
||||||
ctx, cnl = context.WithCancel(o.x.GetContext())
|
|
||||||
lvl = o.GetLevel()
|
lvl = o.GetLevel()
|
||||||
obj = logrus.New()
|
obj = logrus.New()
|
||||||
|
hkl = make([]logtps.Hook, 0)
|
||||||
)
|
)
|
||||||
|
|
||||||
defer cnl()
|
|
||||||
|
|
||||||
o.optionsMerge(opt)
|
o.optionsMerge(opt)
|
||||||
|
|
||||||
obj.SetLevel(lvl.Logrus())
|
obj.SetLevel(lvl.Logrus())
|
||||||
obj.SetFormatter(o.defaultFormatter(opt))
|
obj.SetFormatter(o.defaultFormatter(nil))
|
||||||
obj.SetOutput(io.Discard) // Send all logs to nowhere by default
|
obj.SetOutput(io.Discard) // Send all logs to nowhere by default
|
||||||
|
|
||||||
clo := iotclo.New(func() context.Context {
|
if opt.Stdout != nil && !opt.Stdout.DisableStandard {
|
||||||
return ctx
|
f := o.defaultFormatter(opt.Stdout)
|
||||||
})
|
l := []logrus.Level{
|
||||||
|
|
||||||
if !opt.DisableStandard {
|
|
||||||
obj.AddHook(NewHookStandard(*opt, StdOut, []logrus.Level{
|
|
||||||
logrus.InfoLevel,
|
logrus.InfoLevel,
|
||||||
logrus.DebugLevel,
|
logrus.DebugLevel,
|
||||||
logrus.TraceLevel,
|
logrus.TraceLevel,
|
||||||
}))
|
}
|
||||||
|
|
||||||
obj.AddHook(NewHookStandard(*opt, StdErr, []logrus.Level{
|
if h, e := logout.New(opt.Stdout, l, f); e != nil {
|
||||||
|
return e
|
||||||
|
} else {
|
||||||
|
hkl = append(hkl, h)
|
||||||
|
}
|
||||||
|
|
||||||
|
l = []logrus.Level{
|
||||||
logrus.PanicLevel,
|
logrus.PanicLevel,
|
||||||
logrus.FatalLevel,
|
logrus.FatalLevel,
|
||||||
logrus.ErrorLevel,
|
logrus.ErrorLevel,
|
||||||
logrus.WarnLevel,
|
logrus.WarnLevel,
|
||||||
}))
|
}
|
||||||
|
|
||||||
|
if h, e := logerr.New(opt.Stdout, l, f); e != nil {
|
||||||
|
return e
|
||||||
|
} else {
|
||||||
|
hkl = append(hkl, h)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(opt.LogFile) > 0 {
|
if len(opt.LogFile) > 0 {
|
||||||
for _, fopt := range opt.LogFile {
|
for _, f := range opt.LogFile {
|
||||||
if hook, err := NewHookFile(fopt, o.defaultFormatterNoColor()); err != nil {
|
if h, e := logfil.New(f, o.defaultFormatterNoColor()); e != nil {
|
||||||
return err
|
return e
|
||||||
} else {
|
} else {
|
||||||
clo.Add(hook)
|
hkl = append(hkl, h)
|
||||||
hook.RegisterHook(obj)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(opt.LogSyslog) > 0 {
|
if len(opt.LogSyslog) > 0 {
|
||||||
for _, lopt := range opt.LogSyslog {
|
for _, s := range opt.LogSyslog {
|
||||||
if hook, err := NewHookSyslog(lopt, o.defaultFormatterNoColor()); err != nil {
|
if h, e := logsys.New(s, o.defaultFormatterNoColor()); e != nil {
|
||||||
return err
|
return e
|
||||||
} else {
|
} else {
|
||||||
clo.Add(hook)
|
hkl = append(hkl, h)
|
||||||
hook.RegisterHook(obj)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var clo = o.newCloser()
|
||||||
|
|
||||||
|
for _, h := range hkl {
|
||||||
|
clo.Add(h)
|
||||||
|
h.RegisterHook(obj)
|
||||||
|
go h.Run(o.x.GetContext())
|
||||||
|
}
|
||||||
|
|
||||||
o.x.Store(keyOptions, opt)
|
o.x.Store(keyOptions, opt)
|
||||||
o.x.Store(keyLogrus, obj)
|
o.x.Store(keyLogrus, obj)
|
||||||
|
o.runFuncUpdateLogger()
|
||||||
|
|
||||||
_ = o.Close()
|
clo = o.switchCloser(clo)
|
||||||
o.c.Add(clo.Get()...)
|
go func(c iotclo.Closer) {
|
||||||
clo.Clean()
|
time.Sleep(3 * time.Second)
|
||||||
|
_ = c.Close()
|
||||||
if opt.init != nil {
|
}(clo)
|
||||||
opt.init(o)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *logger) GetOptions() *Options {
|
func (o *logger) GetOptions() *logcfg.Options {
|
||||||
if o == nil {
|
if o == nil {
|
||||||
return &Options{}
|
return &logcfg.Options{}
|
||||||
} else if o.x == nil {
|
} else if o.x == nil {
|
||||||
return &Options{}
|
return &logcfg.Options{}
|
||||||
} else if i, l := o.x.Load(keyOptions); !l {
|
} else if i, l := o.x.Load(keyOptions); !l {
|
||||||
return &Options{}
|
return &logcfg.Options{}
|
||||||
} else if v, k := i.(*Options); !k {
|
} else if v, k := i.(*logcfg.Options); !k {
|
||||||
return &Options{}
|
return &logcfg.Options{}
|
||||||
} else {
|
} else {
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,11 +36,14 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
libctx "github.com/nabbar/golib/context"
|
libctx "github.com/nabbar/golib/context"
|
||||||
liberr "github.com/nabbar/golib/errors"
|
liberr "github.com/nabbar/golib/errors"
|
||||||
iotclo "github.com/nabbar/golib/ioutils/mapCloser"
|
logcfg "github.com/nabbar/golib/logger/config"
|
||||||
|
logfld "github.com/nabbar/golib/logger/fields"
|
||||||
|
loglvl "github.com/nabbar/golib/logger/level"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -52,6 +55,8 @@ const (
|
|||||||
keyLogrus
|
keyLogrus
|
||||||
keyWriter
|
keyWriter
|
||||||
keyFilter
|
keyFilter
|
||||||
|
keyFctUpdLog
|
||||||
|
keyFctUpdLvl
|
||||||
|
|
||||||
_TraceFilterMod = "/pkg/mod/"
|
_TraceFilterMod = "/pkg/mod/"
|
||||||
_TraceFilterVendor = "/vendor/"
|
_TraceFilterVendor = "/vendor/"
|
||||||
@@ -62,8 +67,8 @@ var _selfPackage = path.Base(reflect.TypeOf(logger{}).PkgPath())
|
|||||||
type logger struct {
|
type logger struct {
|
||||||
m sync.RWMutex
|
m sync.RWMutex
|
||||||
x libctx.Config[uint8] // cf const key...
|
x libctx.Config[uint8] // cf const key...
|
||||||
f Fields // fields map
|
f logfld.Fields // fields map
|
||||||
c iotclo.Closer
|
c *atomic.Value // closer
|
||||||
}
|
}
|
||||||
|
|
||||||
func defaultFormatter() logrus.TextFormatter {
|
func defaultFormatter() logrus.TextFormatter {
|
||||||
@@ -86,7 +91,7 @@ func defaultFormatter() logrus.TextFormatter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *logger) defaultFormatter(opt *Options) logrus.Formatter {
|
func (o *logger) defaultFormatter(opt *logcfg.OptionsStd) logrus.Formatter {
|
||||||
f := defaultFormatter()
|
f := defaultFormatter()
|
||||||
|
|
||||||
if opt != nil && opt.DisableColor {
|
if opt != nil && opt.DisableColor {
|
||||||
@@ -128,69 +133,22 @@ func (o *logger) cancelCall() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *logger) optionsMerge(opt *Options) {
|
func (o *logger) optionsMerge(opt *logcfg.Options) {
|
||||||
if !opt.InheritDefault {
|
var oo logcfg.Options
|
||||||
|
|
||||||
|
if i, l := o.x.Load(keyOptions); !l {
|
||||||
return
|
return
|
||||||
}
|
} else if v, k := i.(*logcfg.Options); !k {
|
||||||
|
|
||||||
var no Options
|
|
||||||
|
|
||||||
if opt.opts != nil {
|
|
||||||
no = *opt.opts()
|
|
||||||
} else if i, l := o.x.Load(keyOptions); !l {
|
|
||||||
return
|
return
|
||||||
} else if v, k := i.(*Options); !k {
|
|
||||||
return
|
|
||||||
} else if v.opts != nil {
|
|
||||||
no = *v.opts()
|
|
||||||
} else {
|
} else {
|
||||||
no = *v
|
oo = *v
|
||||||
}
|
}
|
||||||
|
|
||||||
if opt.DisableStandard {
|
oo.Merge(opt)
|
||||||
no.DisableStandard = true
|
*opt = oo
|
||||||
}
|
}
|
||||||
|
|
||||||
if opt.DisableStack {
|
func (o *logger) setLogrusLevel(lvl loglvl.Level) {
|
||||||
no.DisableStack = true
|
|
||||||
}
|
|
||||||
|
|
||||||
if opt.DisableTimestamp {
|
|
||||||
no.DisableTimestamp = true
|
|
||||||
}
|
|
||||||
|
|
||||||
if opt.EnableTrace {
|
|
||||||
no.EnableTrace = true
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(opt.TraceFilter) > 0 {
|
|
||||||
no.TraceFilter = opt.TraceFilter
|
|
||||||
}
|
|
||||||
|
|
||||||
if opt.DisableColor {
|
|
||||||
no.DisableColor = true
|
|
||||||
}
|
|
||||||
|
|
||||||
if opt.EnableAccessLog {
|
|
||||||
no.EnableAccessLog = true
|
|
||||||
}
|
|
||||||
|
|
||||||
if opt.LogFileExtend {
|
|
||||||
no.LogFile = append(no.LogFile, opt.LogFile...)
|
|
||||||
} else {
|
|
||||||
no.LogFile = opt.LogFile
|
|
||||||
}
|
|
||||||
|
|
||||||
if opt.LogSyslogExtend {
|
|
||||||
no.LogSyslog = append(no.LogSyslog, opt.LogSyslog...)
|
|
||||||
} else {
|
|
||||||
no.LogSyslog = opt.LogSyslog
|
|
||||||
}
|
|
||||||
|
|
||||||
*opt = no
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o *logger) setLogrusLevel(lvl Level) {
|
|
||||||
if i, l := o.x.Load(keyLogrus); !l {
|
if i, l := o.x.Load(keyLogrus); !l {
|
||||||
return
|
return
|
||||||
} else if v, k := i.(*logrus.Logger); !k {
|
} else if v, k := i.(*logrus.Logger); !k {
|
||||||
|
|||||||
@@ -1,286 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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"
|
|
||||||
"os"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
libval "github.com/go-playground/validator/v10"
|
|
||||||
liberr "github.com/nabbar/golib/errors"
|
|
||||||
)
|
|
||||||
|
|
||||||
type FuncCustomConfig func(log Logger)
|
|
||||||
|
|
||||||
type NetworkType uint8
|
|
||||||
|
|
||||||
const (
|
|
||||||
NetworkEmpty NetworkType = iota
|
|
||||||
NetworkTCP
|
|
||||||
NetworkUDP
|
|
||||||
)
|
|
||||||
|
|
||||||
func (n NetworkType) String() string {
|
|
||||||
switch n {
|
|
||||||
case NetworkTCP:
|
|
||||||
return "tcp"
|
|
||||||
case NetworkUDP:
|
|
||||||
return "udp"
|
|
||||||
default:
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func MakeNetwork(net string) NetworkType {
|
|
||||||
switch strings.ToLower(net) {
|
|
||||||
case NetworkTCP.String():
|
|
||||||
return NetworkTCP
|
|
||||||
case NetworkUDP.String():
|
|
||||||
return NetworkUDP
|
|
||||||
default:
|
|
||||||
return NetworkEmpty
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type OptionsFile struct {
|
|
||||||
// LogLevel define the allowed level of log for this file.
|
|
||||||
LogLevel []string `json:"logLevel,omitempty" yaml:"logLevel,omitempty" toml:"logLevel,omitempty" mapstructure:"logLevel,omitempty"`
|
|
||||||
|
|
||||||
// Filepath define the file path for log to file.
|
|
||||||
Filepath string `json:"filepath,omitempty" yaml:"filepath,omitempty" toml:"filepath,omitempty" mapstructure:"filepath,omitempty"`
|
|
||||||
|
|
||||||
// Create define if the log file must exist or can create it.
|
|
||||||
Create bool `json:"create,omitempty" yaml:"create,omitempty" toml:"create,omitempty" mapstructure:"create,omitempty"`
|
|
||||||
|
|
||||||
// CreatePath define if the path of the log file must exist or can try to create it.
|
|
||||||
CreatePath bool `json:"createPath,omitempty" yaml:"createPath,omitempty" toml:"createPath,omitempty" mapstructure:"createPath,omitempty"`
|
|
||||||
|
|
||||||
// FileMode define mode to be used for the log file if the create it.
|
|
||||||
FileMode os.FileMode `json:"fileMode,omitempty" yaml:"fileMode,omitempty" toml:"fileMode,omitempty" mapstructure:"fileMode,omitempty"`
|
|
||||||
|
|
||||||
// PathMode define mode to be used for the path of the log file if create it.
|
|
||||||
PathMode os.FileMode `json:"pathMode,omitempty" yaml:"pathMode,omitempty" toml:"pathMode,omitempty" mapstructure:"pathMode,omitempty"`
|
|
||||||
|
|
||||||
// DisableStack allow to disable the goroutine id before each message.
|
|
||||||
DisableStack bool `json:"disableStack,omitempty" yaml:"disableStack,omitempty" toml:"disableStack,omitempty" mapstructure:"disableStack,omitempty"`
|
|
||||||
|
|
||||||
// DisableTimestamp allow to disable the timestamp before each message.
|
|
||||||
DisableTimestamp bool `json:"disableTimestamp,omitempty" yaml:"disableTimestamp,omitempty" toml:"disableTimestamp,omitempty" mapstructure:"disableTimestamp,omitempty"`
|
|
||||||
|
|
||||||
// EnableTrace allow to add the origin caller/file/line of each message.
|
|
||||||
EnableTrace bool `json:"enableTrace,omitempty" yaml:"enableTrace,omitempty" toml:"enableTrace,omitempty" mapstructure:"enableTrace,omitempty"`
|
|
||||||
|
|
||||||
// EnableAccessLog allow to add all message from api router for access log and error log.
|
|
||||||
EnableAccessLog bool `json:"enableAccessLog,omitempty" yaml:"enableAccessLog,omitempty" toml:"enableAccessLog,omitempty" mapstructure:"enableAccessLog,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type OptionsFiles []OptionsFile
|
|
||||||
|
|
||||||
type OptionsSyslog struct {
|
|
||||||
// LogLevel define the allowed level of log for this syslog.
|
|
||||||
LogLevel []string `json:"logLevel,omitempty" yaml:"logLevel,omitempty" toml:"logLevel,omitempty" mapstructure:"logLevel,omitempty"`
|
|
||||||
|
|
||||||
// Network define the network used to connect to this syslog (tcp, udp, or any other to a local connection).
|
|
||||||
Network string `json:"network,omitempty" yaml:"network,omitempty" toml:"network,omitempty" mapstructure:"network,omitempty"`
|
|
||||||
|
|
||||||
// Host define the remote syslog to use.
|
|
||||||
// If Host and Network are empty, local syslog will be used.
|
|
||||||
Host string `json:"host,omitempty" yaml:"host,omitempty" toml:"host,omitempty" mapstructure:"host,omitempty"`
|
|
||||||
/*
|
|
||||||
// Severity define the severity syslog to be used.
|
|
||||||
Severity string `json:"severity,omitempty" yaml:"severity,omitempty" toml:"severity,omitempty" mapstructure:"severity,omitempty"`
|
|
||||||
*/
|
|
||||||
// Facility define the facility syslog to be used.
|
|
||||||
Facility string `json:"facility,omitempty" yaml:"facility,omitempty" toml:"facility,omitempty" mapstructure:"facility,omitempty"`
|
|
||||||
|
|
||||||
// Tag define the syslog tag used in linux syslog system or name of logger for windows event logger.
|
|
||||||
// For window, this value must be unic for each syslog config
|
|
||||||
Tag string `json:"tag,omitempty" yaml:"tag,omitempty" toml:"tag,omitempty" mapstructure:"tag,omitempty"`
|
|
||||||
|
|
||||||
// DisableStack allow to disable the goroutine id before each message.
|
|
||||||
DisableStack bool `json:"disableStack,omitempty" yaml:"disableStack,omitempty" toml:"disableStack,omitempty" mapstructure:"disableStack,omitempty"`
|
|
||||||
|
|
||||||
// DisableTimestamp allow to disable the timestamp before each message.
|
|
||||||
DisableTimestamp bool `json:"disableTimestamp,omitempty" yaml:"disableTimestamp,omitempty" toml:"disableTimestamp,omitempty" mapstructure:"disableTimestamp,omitempty"`
|
|
||||||
|
|
||||||
// EnableTrace allow to add the origin caller/file/line of each message.
|
|
||||||
EnableTrace bool `json:"enableTrace,omitempty" yaml:"enableTrace,omitempty" toml:"enableTrace,omitempty" mapstructure:"enableTrace,omitempty"`
|
|
||||||
|
|
||||||
// EnableAccessLog allow to add all message from api router for access log and error log.
|
|
||||||
EnableAccessLog bool `json:"enableAccessLog,omitempty" yaml:"enableAccessLog,omitempty" toml:"enableAccessLog,omitempty" mapstructure:"enableAccessLog,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type OptionsSyslogs []OptionsSyslog
|
|
||||||
|
|
||||||
type Options struct {
|
|
||||||
// InheritDefault define if the current options will override a default options
|
|
||||||
InheritDefault bool `json:"inheritDefault" yaml:"inheritDefault" toml:"inheritDefault" mapstructure:"inheritDefault"`
|
|
||||||
|
|
||||||
// DisableStandard allow disabling to write log to standard output stdout/stderr.
|
|
||||||
DisableStandard bool `json:"disableStandard,omitempty" yaml:"disableStandard,omitempty" toml:"disableStandard,omitempty" mapstructure:"disableStandard,omitempty"`
|
|
||||||
|
|
||||||
// DisableStack allow to disable the goroutine id before each message.
|
|
||||||
DisableStack bool `json:"disableStack,omitempty" yaml:"disableStack,omitempty" toml:"disableStack,omitempty" mapstructure:"disableStack,omitempty"`
|
|
||||||
|
|
||||||
// DisableTimestamp allow to disable the timestamp before each message.
|
|
||||||
DisableTimestamp bool `json:"disableTimestamp,omitempty" yaml:"disableTimestamp,omitempty" toml:"disableTimestamp,omitempty" mapstructure:"disableTimestamp,omitempty"`
|
|
||||||
|
|
||||||
// EnableTrace allow to add the origin caller/file/line of each message.
|
|
||||||
EnableTrace bool `json:"enableTrace,omitempty" yaml:"enableTrace,omitempty" toml:"enableTrace,omitempty" mapstructure:"enableTrace,omitempty"`
|
|
||||||
|
|
||||||
// TraceFilter define the path to clean for trace.
|
|
||||||
TraceFilter string `json:"traceFilter,omitempty" yaml:"traceFilter,omitempty" toml:"traceFilter,omitempty" mapstructure:"traceFilter,omitempty"`
|
|
||||||
|
|
||||||
// DisableColor define if color could be use or not in messages format.
|
|
||||||
// If the running process is not a tty, no color will be used.
|
|
||||||
DisableColor bool `json:"disableColor,omitempty" yaml:"disableColor,omitempty" toml:"disableColor,omitempty" mapstructure:"disableColor,omitempty"`
|
|
||||||
|
|
||||||
// EnableAccessLog allow to add all message from api router for access log and error log.
|
|
||||||
EnableAccessLog bool `json:"enableAccessLog,omitempty" yaml:"enableAccessLog,omitempty" toml:"enableAccessLog,omitempty" mapstructure:"enableAccessLog,omitempty"`
|
|
||||||
|
|
||||||
// LogFileExtend define if the logFile given is in addition of default LogFile or a replacement.
|
|
||||||
LogFileExtend bool `json:"logFileExtend,omitempty" yaml:"logFileExtend,omitempty" toml:"logFileExtend,omitempty" mapstructure:"logFileExtend,omitempty"`
|
|
||||||
|
|
||||||
// LogFile define a list of log file configuration to allow log to files.
|
|
||||||
LogFile OptionsFiles `json:"logFile,omitempty" yaml:"logFile,omitempty" toml:"logFile,omitempty" mapstructure:"logFile,omitempty"`
|
|
||||||
|
|
||||||
// LogSyslogExtend define if the logFile given is in addition of default LogSyslog or a replacement.
|
|
||||||
LogSyslogExtend bool `json:"logSyslogExtend,omitempty" yaml:"logSyslogExtend,omitempty" toml:"logSyslogExtend,omitempty" mapstructure:"logSyslogExtend,omitempty"`
|
|
||||||
|
|
||||||
// LogSyslog define a list of syslog configuration to allow log to syslog.
|
|
||||||
LogSyslog OptionsSyslogs `json:"logSyslog,omitempty" yaml:"logSyslog,omitempty" toml:"logSyslog,omitempty" mapstructure:"logSyslog,omitempty"`
|
|
||||||
|
|
||||||
// custom function handler.
|
|
||||||
init FuncCustomConfig
|
|
||||||
change FuncCustomConfig
|
|
||||||
|
|
||||||
// default options
|
|
||||||
opts FuncOpt
|
|
||||||
}
|
|
||||||
|
|
||||||
// RegisterDefaultFunc allow to register a function called to retrieve default options for inheritDefault.
|
|
||||||
// If not set, the previous options will be used as default options.
|
|
||||||
// To clean function, just call RegisterDefaultFunc with nil as param.
|
|
||||||
func (o *Options) RegisterDefaultFunc(fct FuncOpt) {
|
|
||||||
o.opts = fct
|
|
||||||
}
|
|
||||||
|
|
||||||
// RegisterFuncUpdateLogger allow to register a function called when init or update of logger.
|
|
||||||
// To clean function, just call RegisterFuncUpdateLogger with nil as param.
|
|
||||||
func (o *Options) RegisterFuncUpdateLogger(fct FuncCustomConfig) {
|
|
||||||
o.init = fct
|
|
||||||
}
|
|
||||||
|
|
||||||
// RegisterFuncUpdateLevel allow to register a function called when init or update level
|
|
||||||
// To clean function, just call RegisterFuncUpdateLevel with nil as param.
|
|
||||||
func (o *Options) RegisterFuncUpdateLevel(fct FuncCustomConfig) {
|
|
||||||
o.change = fct
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate allow checking if the options' struct is valid with the awaiting model
|
|
||||||
func (o *Options) Validate() liberr.Error {
|
|
||||||
var e = ErrorValidatorError.Error(nil)
|
|
||||||
|
|
||||||
if err := libval.New().Struct(o); err != nil {
|
|
||||||
if er, ok := err.(*libval.InvalidValidationError); ok {
|
|
||||||
e.AddParent(er)
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, er := range err.(libval.ValidationErrors) {
|
|
||||||
//nolint #goerr113
|
|
||||||
e.AddParent(fmt.Errorf("config field '%s' is not validated by constraint '%s'", er.Namespace(), er.ActualTag()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if !e.HasParent() {
|
|
||||||
e = nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return e
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o *Options) Clone() Options {
|
|
||||||
return Options{
|
|
||||||
DisableStandard: o.DisableStandard,
|
|
||||||
DisableStack: o.DisableStack,
|
|
||||||
DisableTimestamp: o.DisableTimestamp,
|
|
||||||
EnableTrace: o.EnableTrace,
|
|
||||||
TraceFilter: o.TraceFilter,
|
|
||||||
DisableColor: o.DisableColor,
|
|
||||||
EnableAccessLog: o.EnableAccessLog,
|
|
||||||
LogFile: o.LogFile.Clone(),
|
|
||||||
LogSyslog: o.LogSyslog.Clone(),
|
|
||||||
init: o.init,
|
|
||||||
change: o.change,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o OptionsFile) Clone() OptionsFile {
|
|
||||||
return OptionsFile{
|
|
||||||
LogLevel: o.LogLevel,
|
|
||||||
Filepath: o.Filepath,
|
|
||||||
Create: o.Create,
|
|
||||||
CreatePath: o.CreatePath,
|
|
||||||
FileMode: o.FileMode,
|
|
||||||
PathMode: o.PathMode,
|
|
||||||
DisableStack: o.DisableStack,
|
|
||||||
DisableTimestamp: o.DisableTimestamp,
|
|
||||||
EnableTrace: o.EnableTrace,
|
|
||||||
EnableAccessLog: o.EnableAccessLog,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o OptionsFiles) Clone() OptionsFiles {
|
|
||||||
var c = make([]OptionsFile, 0)
|
|
||||||
for _, i := range o {
|
|
||||||
c = append(c, i.Clone())
|
|
||||||
}
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o OptionsSyslog) Clone() OptionsSyslog {
|
|
||||||
return OptionsSyslog{
|
|
||||||
LogLevel: o.LogLevel,
|
|
||||||
Network: o.Network,
|
|
||||||
Host: o.Host,
|
|
||||||
Facility: o.Facility,
|
|
||||||
Tag: o.Tag,
|
|
||||||
DisableStack: o.DisableStack,
|
|
||||||
DisableTimestamp: o.DisableTimestamp,
|
|
||||||
EnableTrace: o.EnableTrace,
|
|
||||||
EnableAccessLog: o.EnableAccessLog,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o OptionsSyslogs) Clone() OptionsSyslogs {
|
|
||||||
var c = make([]OptionsSyslog, 0)
|
|
||||||
for _, i := range o {
|
|
||||||
c = append(c, i.Clone())
|
|
||||||
}
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
67
logger/spf13.go
Normal file
67
logger/spf13.go
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
/***********************************************************************************************************************
|
||||||
|
*
|
||||||
|
* 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 (
|
||||||
|
"io"
|
||||||
|
|
||||||
|
loglvl "github.com/nabbar/golib/logger/level"
|
||||||
|
jww "github.com/spf13/jwalterweatherman"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (o *logger) SetSPF13Level(lvl loglvl.Level, log *jww.Notepad) {
|
||||||
|
if log == nil {
|
||||||
|
jww.SetStdoutOutput(io.Discard)
|
||||||
|
} else {
|
||||||
|
jww.SetStdoutOutput(o)
|
||||||
|
}
|
||||||
|
|
||||||
|
switch lvl {
|
||||||
|
case loglvl.NilLevel:
|
||||||
|
jww.SetLogOutput(io.Discard)
|
||||||
|
jww.SetLogThreshold(jww.LevelCritical)
|
||||||
|
case loglvl.DebugLevel:
|
||||||
|
jww.SetLogOutput(o)
|
||||||
|
jww.SetLogThreshold(jww.LevelTrace)
|
||||||
|
case loglvl.InfoLevel:
|
||||||
|
jww.SetLogOutput(o)
|
||||||
|
jww.SetLogThreshold(jww.LevelInfo)
|
||||||
|
case loglvl.WarnLevel:
|
||||||
|
jww.SetLogOutput(o)
|
||||||
|
jww.SetLogThreshold(jww.LevelWarn)
|
||||||
|
case loglvl.ErrorLevel:
|
||||||
|
jww.SetLogOutput(o)
|
||||||
|
jww.SetLogThreshold(jww.LevelError)
|
||||||
|
case loglvl.FatalLevel:
|
||||||
|
jww.SetLogOutput(o)
|
||||||
|
jww.SetLogThreshold(jww.LevelFatal)
|
||||||
|
case loglvl.PanicLevel:
|
||||||
|
jww.SetLogOutput(o)
|
||||||
|
jww.SetLogThreshold(jww.LevelCritical)
|
||||||
|
}
|
||||||
|
}
|
||||||
40
logger/types/fields.go
Normal file
40
logger/types/fields.go
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
/***********************************************************************************************************************
|
||||||
|
*
|
||||||
|
* 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 types
|
||||||
|
|
||||||
|
const (
|
||||||
|
FieldTime = "time"
|
||||||
|
FieldLevel = "level"
|
||||||
|
FieldStack = "stack"
|
||||||
|
FieldCaller = "caller"
|
||||||
|
FieldFile = "file"
|
||||||
|
FieldLine = "line"
|
||||||
|
FieldMessage = "message"
|
||||||
|
FieldError = "error"
|
||||||
|
FieldData = "data"
|
||||||
|
)
|
||||||
42
logger/types/hook.go
Normal file
42
logger/types/hook.go
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
/***********************************************************************************************************************
|
||||||
|
*
|
||||||
|
* 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 types
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"io"
|
||||||
|
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Hook interface {
|
||||||
|
logrus.Hook
|
||||||
|
io.WriteCloser
|
||||||
|
RegisterHook(log *logrus.Logger)
|
||||||
|
Run(ctx context.Context)
|
||||||
|
}
|
||||||
@@ -30,11 +30,10 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
libctx "github.com/nabbar/golib/context"
|
libctx "github.com/nabbar/golib/context"
|
||||||
|
|
||||||
"github.com/nabbar/golib/monitor/types"
|
|
||||||
|
|
||||||
liberr "github.com/nabbar/golib/errors"
|
liberr "github.com/nabbar/golib/errors"
|
||||||
liblog "github.com/nabbar/golib/logger"
|
liblog "github.com/nabbar/golib/logger"
|
||||||
|
logcfg "github.com/nabbar/golib/logger/config"
|
||||||
|
montps "github.com/nabbar/golib/monitor/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
type runCfg struct {
|
type runCfg struct {
|
||||||
@@ -101,7 +100,7 @@ func (o *mon) getLoggerDefault() liblog.Logger {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *mon) SetConfig(ctx libctx.FuncContext, cfg types.Config) liberr.Error {
|
func (o *mon) SetConfig(ctx libctx.FuncContext, cfg montps.Config) liberr.Error {
|
||||||
if ctx == nil {
|
if ctx == nil {
|
||||||
ctx = o.x.GetContext
|
ctx = o.x.GetContext
|
||||||
}
|
}
|
||||||
@@ -175,17 +174,12 @@ func (o *mon) SetConfig(ctx libctx.FuncContext, cfg types.Config) liberr.Error {
|
|||||||
|
|
||||||
f := n.GetFields()
|
f := n.GetFields()
|
||||||
n.SetFields(f.Add(LogFieldProcess, LogValueProcess).Add(LogFieldName, cfg.Name))
|
n.SetFields(f.Add(LogFieldProcess, LogValueProcess).Add(LogFieldName, cfg.Name))
|
||||||
n.SetLevel(liblog.GetCurrentLevel())
|
|
||||||
|
|
||||||
if l := o.getLog(); l != nil {
|
|
||||||
_ = l.Close()
|
|
||||||
}
|
|
||||||
|
|
||||||
o.x.Store(keyLogger, n)
|
o.x.Store(keyLogger, n)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *mon) GetConfig() types.Config {
|
func (o *mon) GetConfig() montps.Config {
|
||||||
cfg := o.getCfg()
|
cfg := o.getCfg()
|
||||||
if cfg == nil {
|
if cfg == nil {
|
||||||
cfg = &runCfg{}
|
cfg = &runCfg{}
|
||||||
@@ -193,10 +187,10 @@ func (o *mon) GetConfig() types.Config {
|
|||||||
|
|
||||||
opt := o.getLogger().GetOptions()
|
opt := o.getLogger().GetOptions()
|
||||||
if opt == nil {
|
if opt == nil {
|
||||||
opt = &liblog.Options{}
|
opt = &logcfg.Options{}
|
||||||
}
|
}
|
||||||
|
|
||||||
return types.Config{
|
return montps.Config{
|
||||||
Name: o.getName(),
|
Name: o.getName(),
|
||||||
CheckTimeout: cfg.checkTimeout,
|
CheckTimeout: cfg.checkTimeout,
|
||||||
IntervalCheck: cfg.intervalCheck,
|
IntervalCheck: cfg.intervalCheck,
|
||||||
@@ -244,16 +238,16 @@ func (o *mon) getLogger() liblog.Logger {
|
|||||||
i := o.getLog()
|
i := o.getLog()
|
||||||
|
|
||||||
if i == nil {
|
if i == nil {
|
||||||
return liblog.GetDefault()
|
return liblog.New(o.x.GetContext)
|
||||||
} else {
|
} else {
|
||||||
return i
|
return i
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *mon) getFct() types.HealthCheck {
|
func (o *mon) getFct() montps.HealthCheck {
|
||||||
if i, l := o.x.Load(keyHealthCheck); !l {
|
if i, l := o.x.Load(keyHealthCheck); !l {
|
||||||
return nil
|
return nil
|
||||||
} else if v, k := i.(types.HealthCheck); !k {
|
} else if v, k := i.(montps.HealthCheck); !k {
|
||||||
return nil
|
return nil
|
||||||
} else {
|
} else {
|
||||||
return v
|
return v
|
||||||
|
|||||||
@@ -30,8 +30,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
liblog "github.com/nabbar/golib/logger"
|
loglvl "github.com/nabbar/golib/logger/level"
|
||||||
|
|
||||||
montps "github.com/nabbar/golib/monitor/types"
|
montps "github.com/nabbar/golib/monitor/types"
|
||||||
libprm "github.com/nabbar/golib/prometheus"
|
libprm "github.com/nabbar/golib/prometheus"
|
||||||
libmet "github.com/nabbar/golib/prometheus/metrics"
|
libmet "github.com/nabbar/golib/prometheus/metrics"
|
||||||
@@ -115,7 +114,7 @@ func (o *pool) collectMetricLatency(ctx context.Context, m libmet.Metric) {
|
|||||||
|
|
||||||
o.MonitorWalk(func(name string, val montps.Monitor) bool {
|
o.MonitorWalk(func(name string, val montps.Monitor) bool {
|
||||||
if e := m.Observe([]string{name}, val.CollectLatency().Seconds()); e != nil {
|
if e := m.Observe([]string{name}, val.CollectLatency().Seconds()); e != nil {
|
||||||
ent := log.Entry(liblog.ErrorLevel, "failed to collect metrics", nil)
|
ent := log.Entry(loglvl.ErrorLevel, "failed to collect metrics", nil)
|
||||||
ent.FieldAdd("monitor", name)
|
ent.FieldAdd("monitor", name)
|
||||||
ent.FieldAdd("metric", val.Name())
|
ent.FieldAdd("metric", val.Name())
|
||||||
ent.ErrorAdd(true, e)
|
ent.ErrorAdd(true, e)
|
||||||
@@ -151,7 +150,7 @@ func (o *pool) collectMetricUptime(ctx context.Context, m libmet.Metric) {
|
|||||||
|
|
||||||
o.MonitorWalk(func(name string, val montps.Monitor) bool {
|
o.MonitorWalk(func(name string, val montps.Monitor) bool {
|
||||||
if e := m.SetGaugeValue([]string{name}, val.CollectUpTime().Seconds()); e != nil {
|
if e := m.SetGaugeValue([]string{name}, val.CollectUpTime().Seconds()); e != nil {
|
||||||
ent := log.Entry(liblog.ErrorLevel, "failed to collect metrics", nil)
|
ent := log.Entry(loglvl.ErrorLevel, "failed to collect metrics", nil)
|
||||||
ent.FieldAdd("monitor", name)
|
ent.FieldAdd("monitor", name)
|
||||||
ent.FieldAdd("metric", val.Name())
|
ent.FieldAdd("metric", val.Name())
|
||||||
ent.ErrorAdd(true, e)
|
ent.ErrorAdd(true, e)
|
||||||
@@ -187,7 +186,7 @@ func (o *pool) collectMetricDowntime(ctx context.Context, m libmet.Metric) {
|
|||||||
|
|
||||||
o.MonitorWalk(func(name string, val montps.Monitor) bool {
|
o.MonitorWalk(func(name string, val montps.Monitor) bool {
|
||||||
if e := m.SetGaugeValue([]string{name}, val.CollectDownTime().Seconds()); e != nil {
|
if e := m.SetGaugeValue([]string{name}, val.CollectDownTime().Seconds()); e != nil {
|
||||||
ent := log.Entry(liblog.ErrorLevel, "failed to collect metrics", nil)
|
ent := log.Entry(loglvl.ErrorLevel, "failed to collect metrics", nil)
|
||||||
ent.FieldAdd("monitor", name)
|
ent.FieldAdd("monitor", name)
|
||||||
ent.FieldAdd("metric", val.Name())
|
ent.FieldAdd("metric", val.Name())
|
||||||
ent.ErrorAdd(true, e)
|
ent.ErrorAdd(true, e)
|
||||||
@@ -223,7 +222,7 @@ func (o *pool) collectMetricRiseTime(ctx context.Context, m libmet.Metric) {
|
|||||||
|
|
||||||
o.MonitorWalk(func(name string, val montps.Monitor) bool {
|
o.MonitorWalk(func(name string, val montps.Monitor) bool {
|
||||||
if e := m.SetGaugeValue([]string{name}, val.CollectRiseTime().Seconds()); e != nil {
|
if e := m.SetGaugeValue([]string{name}, val.CollectRiseTime().Seconds()); e != nil {
|
||||||
ent := log.Entry(liblog.ErrorLevel, "failed to collect metrics", nil)
|
ent := log.Entry(loglvl.ErrorLevel, "failed to collect metrics", nil)
|
||||||
ent.FieldAdd("monitor", name)
|
ent.FieldAdd("monitor", name)
|
||||||
ent.FieldAdd("metric", val.Name())
|
ent.FieldAdd("metric", val.Name())
|
||||||
ent.ErrorAdd(true, e)
|
ent.ErrorAdd(true, e)
|
||||||
@@ -259,7 +258,7 @@ func (o *pool) collectMetricFallTime(ctx context.Context, m libmet.Metric) {
|
|||||||
|
|
||||||
o.MonitorWalk(func(name string, val montps.Monitor) bool {
|
o.MonitorWalk(func(name string, val montps.Monitor) bool {
|
||||||
if e := m.SetGaugeValue([]string{name}, val.CollectFallTime().Seconds()); e != nil {
|
if e := m.SetGaugeValue([]string{name}, val.CollectFallTime().Seconds()); e != nil {
|
||||||
ent := log.Entry(liblog.ErrorLevel, "failed to collect metrics", nil)
|
ent := log.Entry(loglvl.ErrorLevel, "failed to collect metrics", nil)
|
||||||
ent.FieldAdd("monitor", name)
|
ent.FieldAdd("monitor", name)
|
||||||
ent.FieldAdd("metric", val.Name())
|
ent.FieldAdd("metric", val.Name())
|
||||||
ent.ErrorAdd(true, e)
|
ent.ErrorAdd(true, e)
|
||||||
@@ -299,7 +298,7 @@ func (o *pool) collectMetricStatus(ctx context.Context, m libmet.Metric) {
|
|||||||
)
|
)
|
||||||
|
|
||||||
if e := m.SetGaugeValue([]string{name}, s.Float()); e != nil {
|
if e := m.SetGaugeValue([]string{name}, s.Float()); e != nil {
|
||||||
ent := log.Entry(liblog.ErrorLevel, "failed to collect metrics", nil)
|
ent := log.Entry(loglvl.ErrorLevel, "failed to collect metrics", nil)
|
||||||
ent.FieldAdd("monitor", name)
|
ent.FieldAdd("monitor", name)
|
||||||
ent.FieldAdd("metric", val.Name())
|
ent.FieldAdd("metric", val.Name())
|
||||||
ent.ErrorAdd(true, e)
|
ent.ErrorAdd(true, e)
|
||||||
@@ -345,7 +344,7 @@ func (o *pool) collectMetricRising(ctx context.Context, m libmet.Metric) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if e := m.SetGaugeValue([]string{name}, s); e != nil {
|
if e := m.SetGaugeValue([]string{name}, s); e != nil {
|
||||||
ent := log.Entry(liblog.ErrorLevel, "failed to collect metrics", nil)
|
ent := log.Entry(loglvl.ErrorLevel, "failed to collect metrics", nil)
|
||||||
ent.FieldAdd("monitor", name)
|
ent.FieldAdd("monitor", name)
|
||||||
ent.FieldAdd("metric", val.Name())
|
ent.FieldAdd("metric", val.Name())
|
||||||
ent.ErrorAdd(true, e)
|
ent.ErrorAdd(true, e)
|
||||||
@@ -392,7 +391,7 @@ func (o *pool) collectMetricFalling(ctx context.Context, m libmet.Metric) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if e := m.SetGaugeValue([]string{name}, s); e != nil {
|
if e := m.SetGaugeValue([]string{name}, s); e != nil {
|
||||||
ent := log.Entry(liblog.ErrorLevel, "failed to collect metrics", nil)
|
ent := log.Entry(loglvl.ErrorLevel, "failed to collect metrics", nil)
|
||||||
ent.FieldAdd("monitor", name)
|
ent.FieldAdd("monitor", name)
|
||||||
ent.FieldAdd("metric", val.Name())
|
ent.FieldAdd("metric", val.Name())
|
||||||
ent.ErrorAdd(true, e)
|
ent.ErrorAdd(true, e)
|
||||||
@@ -462,7 +461,7 @@ func (o *pool) collectMetricSLis(ctx context.Context, m libmet.Metric) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if e := m.SetGaugeValue([]string{name}, cur); e != nil {
|
if e := m.SetGaugeValue([]string{name}, cur); e != nil {
|
||||||
ent := log.Entry(liblog.ErrorLevel, "failed to collect metrics", nil)
|
ent := log.Entry(loglvl.ErrorLevel, "failed to collect metrics", nil)
|
||||||
ent.FieldAdd("monitor", name)
|
ent.FieldAdd("monitor", name)
|
||||||
ent.FieldAdd("metric", val.Name())
|
ent.FieldAdd("metric", val.Name())
|
||||||
ent.ErrorAdd(true, e)
|
ent.ErrorAdd(true, e)
|
||||||
@@ -489,7 +488,7 @@ func (o *pool) collectMetricSLis(ctx context.Context, m libmet.Metric) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if e := m.SetGaugeValue([]string{monitorMeans}, mns); e != nil {
|
if e := m.SetGaugeValue([]string{monitorMeans}, mns); e != nil {
|
||||||
ent := log.Entry(liblog.ErrorLevel, "failed to collect metrics", nil)
|
ent := log.Entry(loglvl.ErrorLevel, "failed to collect metrics", nil)
|
||||||
ent.FieldAdd("monitor", monitorMeans)
|
ent.FieldAdd("monitor", monitorMeans)
|
||||||
ent.FieldAdd("metric", metricSLis)
|
ent.FieldAdd("metric", metricSLis)
|
||||||
ent.ErrorAdd(true, e)
|
ent.ErrorAdd(true, e)
|
||||||
@@ -497,7 +496,7 @@ func (o *pool) collectMetricSLis(ctx context.Context, m libmet.Metric) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if e := m.SetGaugeValue([]string{monitorMin}, min); e != nil {
|
if e := m.SetGaugeValue([]string{monitorMin}, min); e != nil {
|
||||||
ent := log.Entry(liblog.ErrorLevel, "failed to collect metrics", nil)
|
ent := log.Entry(loglvl.ErrorLevel, "failed to collect metrics", nil)
|
||||||
ent.FieldAdd("monitor", monitorMin)
|
ent.FieldAdd("monitor", monitorMin)
|
||||||
ent.FieldAdd("metric", metricSLis)
|
ent.FieldAdd("metric", metricSLis)
|
||||||
ent.ErrorAdd(true, e)
|
ent.ErrorAdd(true, e)
|
||||||
@@ -505,7 +504,7 @@ func (o *pool) collectMetricSLis(ctx context.Context, m libmet.Metric) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if e := m.SetGaugeValue([]string{monitorMax}, max); e != nil {
|
if e := m.SetGaugeValue([]string{monitorMax}, max); e != nil {
|
||||||
ent := log.Entry(liblog.ErrorLevel, "failed to collect metrics", nil)
|
ent := log.Entry(loglvl.ErrorLevel, "failed to collect metrics", nil)
|
||||||
ent.FieldAdd("monitor", monitorMax)
|
ent.FieldAdd("monitor", monitorMax)
|
||||||
ent.FieldAdd("metric", metricSLis)
|
ent.FieldAdd("metric", metricSLis)
|
||||||
ent.ErrorAdd(true, e)
|
ent.ErrorAdd(true, e)
|
||||||
|
|||||||
@@ -31,9 +31,8 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
liblog "github.com/nabbar/golib/logger"
|
|
||||||
|
|
||||||
libctx "github.com/nabbar/golib/context"
|
libctx "github.com/nabbar/golib/context"
|
||||||
|
liblog "github.com/nabbar/golib/logger"
|
||||||
libprm "github.com/nabbar/golib/prometheus"
|
libprm "github.com/nabbar/golib/prometheus"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -44,17 +43,31 @@ type pool struct {
|
|||||||
p libctx.Config[string]
|
p libctx.Config[string]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (o *pool) setDefaultLog() {
|
||||||
|
o.m.Lock()
|
||||||
|
defer o.m.Unlock()
|
||||||
|
|
||||||
|
lg := liblog.New(o.p.GetContext)
|
||||||
|
o.fl = func() liblog.Logger {
|
||||||
|
return lg
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (o *pool) getLog() liblog.Logger {
|
func (o *pool) getLog() liblog.Logger {
|
||||||
o.m.RLock()
|
o.m.RLock()
|
||||||
defer o.m.RUnlock()
|
defer o.m.RUnlock()
|
||||||
|
|
||||||
if o.fl == nil {
|
if o.fl != nil {
|
||||||
return liblog.GetDefault()
|
if l := o.fl(); l != nil {
|
||||||
} else if l := o.fl(); l != nil {
|
|
||||||
return l
|
return l
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return liblog.GetDefault()
|
o.m.RUnlock()
|
||||||
|
o.setDefaultLog()
|
||||||
|
o.m.RLock()
|
||||||
|
|
||||||
|
return o.fl()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *pool) InitMetrics(prm libprm.FuncGetPrometheus, log liblog.FuncLog) error {
|
func (o *pool) InitMetrics(prm libprm.FuncGetPrometheus, log liblog.FuncLog) error {
|
||||||
|
|||||||
@@ -32,13 +32,10 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
cptlog "github.com/nabbar/golib/logger/config"
|
|
||||||
|
|
||||||
cfgtps "github.com/nabbar/golib/config/const"
|
|
||||||
|
|
||||||
libval "github.com/go-playground/validator/v10"
|
libval "github.com/go-playground/validator/v10"
|
||||||
|
cfgtps "github.com/nabbar/golib/config/const"
|
||||||
liberr "github.com/nabbar/golib/errors"
|
liberr "github.com/nabbar/golib/errors"
|
||||||
liblog "github.com/nabbar/golib/logger"
|
logcfg "github.com/nabbar/golib/logger/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _defaultConfig = []byte(`{
|
var _defaultConfig = []byte(`{
|
||||||
@@ -51,7 +48,7 @@ var _defaultConfig = []byte(`{
|
|||||||
"fall-count-warn": "",
|
"fall-count-warn": "",
|
||||||
"rise-count-ko": "",
|
"rise-count-ko": "",
|
||||||
"rise-count-warn": "",
|
"rise-count-warn": "",
|
||||||
"logger": ` + string(cptlog.DefaultConfig(cfgtps.JSONIndent+cfgtps.JSONIndent)) + `
|
"logger": ` + string(logcfg.DefaultConfig(cfgtps.JSONIndent+cfgtps.JSONIndent)) + `
|
||||||
}`)
|
}`)
|
||||||
|
|
||||||
func SetDefaultConfig(cfg []byte) {
|
func SetDefaultConfig(cfg []byte) {
|
||||||
@@ -96,7 +93,7 @@ type Config struct {
|
|||||||
RiseCountWarn uint8 `json:"rise-count-warn" yaml:"rise-count-warn" toml:"rise-count-warn" mapstructure:"rise-count-warn"`
|
RiseCountWarn uint8 `json:"rise-count-warn" yaml:"rise-count-warn" toml:"rise-count-warn" mapstructure:"rise-count-warn"`
|
||||||
|
|
||||||
// Logger define the logger options for current monitor log
|
// Logger define the logger options for current monitor log
|
||||||
Logger liblog.Options `json:"logger" yaml:"logger" toml:"logger" mapstructure:"logger"`
|
Logger logcfg.Options `json:"logger" yaml:"logger" toml:"logger" mapstructure:"logger"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o Config) Validate() liberr.Error {
|
func (o Config) Validate() liberr.Error {
|
||||||
|
|||||||
@@ -36,13 +36,13 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
moncfg "github.com/nabbar/golib/monitor/types"
|
|
||||||
|
|
||||||
libval "github.com/go-playground/validator/v10"
|
libval "github.com/go-playground/validator/v10"
|
||||||
libtls "github.com/nabbar/golib/certificates"
|
libtls "github.com/nabbar/golib/certificates"
|
||||||
liberr "github.com/nabbar/golib/errors"
|
liberr "github.com/nabbar/golib/errors"
|
||||||
libiot "github.com/nabbar/golib/ioutils"
|
libiot "github.com/nabbar/golib/ioutils"
|
||||||
liblog "github.com/nabbar/golib/logger"
|
liblog "github.com/nabbar/golib/logger"
|
||||||
|
loglvl "github.com/nabbar/golib/logger/level"
|
||||||
|
moncfg "github.com/nabbar/golib/monitor/types"
|
||||||
natjwt "github.com/nats-io/jwt/v2"
|
natjwt "github.com/nats-io/jwt/v2"
|
||||||
natsrv "github.com/nats-io/nats-server/v2/server"
|
natsrv "github.com/nats-io/nats-server/v2/server"
|
||||||
)
|
)
|
||||||
@@ -128,7 +128,7 @@ func (c Config) LogConfigJson() liberr.Error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c Config) NatsOption(defaultTls libtls.TLSConfig) (*natsrv.Options, liberr.Error) {
|
func (c Config) NatsOption(defaultTls libtls.TLSConfig, log liblog.Logger) (*natsrv.Options, liberr.Error) {
|
||||||
cfg := &natsrv.Options{
|
cfg := &natsrv.Options{
|
||||||
CheckConfig: false,
|
CheckConfig: false,
|
||||||
}
|
}
|
||||||
@@ -137,7 +137,7 @@ func (c Config) NatsOption(defaultTls libtls.TLSConfig) (*natsrv.Options, liberr
|
|||||||
return nil, e
|
return nil, e
|
||||||
}
|
}
|
||||||
|
|
||||||
if e := c.Logs.makeOpt(cfg); e != nil {
|
if e := c.Logs.makeOpt(log, cfg); e != nil {
|
||||||
return nil, e
|
return nil, e
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -472,7 +472,7 @@ func (c ConfigPermissionResponse) makeOpt() *natsrv.ResponsePermission {
|
|||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c ConfigLogger) makeOpt(cfg *natsrv.Options) liberr.Error {
|
func (c ConfigLogger) makeOpt(log liblog.Logger, cfg *natsrv.Options) liberr.Error {
|
||||||
if cfg == nil {
|
if cfg == nil {
|
||||||
return ErrorParamsInvalid.Error(nil)
|
return ErrorParamsInvalid.Error(nil)
|
||||||
}
|
}
|
||||||
@@ -521,19 +521,14 @@ func (c ConfigLogger) makeOpt(cfg *natsrv.Options) liberr.Error {
|
|||||||
cfg.ReconnectErrorReports = c.ReconnectErrorReports
|
cfg.ReconnectErrorReports = c.ReconnectErrorReports
|
||||||
}
|
}
|
||||||
|
|
||||||
if liblog.IsTimeStamp() {
|
|
||||||
cfg.Logtime = true
|
cfg.Logtime = true
|
||||||
}
|
|
||||||
|
|
||||||
if liblog.IsFileTrace() {
|
|
||||||
cfg.Trace = true
|
cfg.Trace = true
|
||||||
}
|
|
||||||
|
|
||||||
switch liblog.GetCurrentLevel() {
|
switch log.GetLevel() {
|
||||||
case liblog.DebugLevel:
|
case loglvl.DebugLevel:
|
||||||
cfg.Debug = true
|
cfg.Debug = true
|
||||||
cfg.NoLog = false
|
cfg.NoLog = false
|
||||||
case liblog.NilLevel:
|
case loglvl.NilLevel:
|
||||||
cfg.Debug = false
|
cfg.Debug = false
|
||||||
cfg.NoLog = true
|
cfg.NoLog = true
|
||||||
default:
|
default:
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user