mirror of
https://github.com/nabbar/golib.git
synced 2025-11-02 11:54:00 +08:00
Package Status :
- optimize output writer block for Get function - add query string params online to print all result as one line plain text format Package logger : - refactor closer function to specific interface - refactor syslog linux to log message by severity instead of same severity for all message Other : - Bump dependencies
This commit is contained in:
24
go.mod
24
go.mod
@@ -29,11 +29,11 @@ require (
|
||||
github.com/nats-io/jwt/v2 v2.3.0
|
||||
github.com/nats-io/nats-server/v2 v2.9.6
|
||||
github.com/nats-io/nats.go v1.19.1
|
||||
github.com/onsi/ginkgo/v2 v2.4.0
|
||||
github.com/onsi/gomega v1.24.0
|
||||
github.com/onsi/ginkgo/v2 v2.5.0
|
||||
github.com/onsi/gomega v1.24.1
|
||||
github.com/pelletier/go-toml v1.9.5
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/prometheus/client_golang v1.13.1
|
||||
github.com/prometheus/client_golang v1.14.0
|
||||
github.com/shirou/gopsutil v3.21.11+incompatible
|
||||
github.com/sirupsen/logrus v1.9.0
|
||||
github.com/spf13/cobra v1.6.1
|
||||
@@ -44,12 +44,12 @@ require (
|
||||
github.com/xhit/go-simple-mail v2.2.2+incompatible
|
||||
github.com/xujiajun/nutsdb v0.11.0
|
||||
github.com/xujiajun/utils v0.0.0-20220904132955-5f7c5b914235
|
||||
golang.org/x/exp v0.0.0-20221106115401-f9659909a136
|
||||
golang.org/x/net v0.1.0
|
||||
golang.org/x/oauth2 v0.1.0
|
||||
golang.org/x/exp v0.0.0-20221109205753-fc8884afc316
|
||||
golang.org/x/net v0.2.0
|
||||
golang.org/x/oauth2 v0.2.0
|
||||
golang.org/x/sync v0.1.0
|
||||
golang.org/x/sys v0.1.0
|
||||
golang.org/x/term v0.1.0
|
||||
golang.org/x/sys v0.2.0
|
||||
golang.org/x/term v0.2.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
gorm.io/driver/clickhouse v0.5.0
|
||||
gorm.io/driver/mysql v1.4.3
|
||||
@@ -190,11 +190,11 @@ require (
|
||||
github.com/yusufpapurcu/wmi v1.2.2 // indirect
|
||||
go.opentelemetry.io/otel v1.11.1 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.11.1 // indirect
|
||||
golang.org/x/crypto v0.1.0 // indirect
|
||||
golang.org/x/mod v0.6.0 // indirect
|
||||
golang.org/x/crypto v0.2.0 // indirect
|
||||
golang.org/x/mod v0.7.0 // indirect
|
||||
golang.org/x/text v0.4.0 // indirect
|
||||
golang.org/x/time v0.1.0 // indirect
|
||||
golang.org/x/tools v0.2.0 // indirect
|
||||
golang.org/x/time v0.2.0 // indirect
|
||||
golang.org/x/tools v0.3.0 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/protobuf v1.28.1 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
|
||||
116
logger/closer.go
Normal file
116
logger/closer.go
Normal file
@@ -0,0 +1,116 @@
|
||||
/***********************************************************************************************************************
|
||||
*
|
||||
* 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"
|
||||
)
|
||||
|
||||
type _Closer interface {
|
||||
Add(clo io.Closer)
|
||||
Get() []io.Closer
|
||||
Len() int
|
||||
Clean()
|
||||
Clone() _Closer
|
||||
Close() error
|
||||
}
|
||||
|
||||
func _NewCloser() _Closer {
|
||||
return &closer{
|
||||
m: sync.Mutex{},
|
||||
c: make([]io.Closer, 0),
|
||||
}
|
||||
}
|
||||
|
||||
type closer struct {
|
||||
m sync.Mutex
|
||||
c []io.Closer
|
||||
}
|
||||
|
||||
func (c *closer) Add(clo io.Closer) {
|
||||
lst := append(c.Get(), clo)
|
||||
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
c.c = lst
|
||||
}
|
||||
|
||||
func (c *closer) Get() []io.Closer {
|
||||
res := make([]io.Closer, 0)
|
||||
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
if len(c.c) > 0 {
|
||||
for _, i := range c.c {
|
||||
if i == nil {
|
||||
continue
|
||||
}
|
||||
res = append(res, i)
|
||||
}
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
func (c *closer) Len() int {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
return len(c.c)
|
||||
}
|
||||
|
||||
func (c *closer) Clean() {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
c.c = make([]io.Closer, 0)
|
||||
}
|
||||
|
||||
func (c *closer) Clone() _Closer {
|
||||
o := _NewCloser()
|
||||
for _, i := range c.Get() {
|
||||
o.Add(i)
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
func (c *closer) Close() error {
|
||||
var e = make([]string, 0)
|
||||
|
||||
for _, i := range c.Get() {
|
||||
if err := i.Close(); err != nil {
|
||||
e = append(e, err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
return fmt.Errorf("%s", strings.Join(e, ", "))
|
||||
}
|
||||
@@ -31,6 +31,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
@@ -55,13 +56,24 @@ type syslogWrapper interface {
|
||||
type FuncFormatter func() logrus.Formatter
|
||||
|
||||
type _HookSyslog struct {
|
||||
m sync.Mutex
|
||||
w syslogWrapper
|
||||
f logrus.Formatter
|
||||
l []logrus.Level
|
||||
s bool
|
||||
d bool
|
||||
t bool
|
||||
a bool
|
||||
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) {
|
||||
@@ -79,19 +91,64 @@ func NewHookSyslog(opt OptionsSyslog, format logrus.Formatter) (HookSyslog, erro
|
||||
LVLs = logrus.AllLevels
|
||||
}
|
||||
|
||||
if sys, err = newSyslog(MakeNetwork(opt.Network), opt.Host, opt.Tag, MakeSeverity(opt.Severity), MakeFacility(opt.Facility)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &_HookSyslog{
|
||||
obj := &_HookSyslog{
|
||||
m: sync.Mutex{},
|
||||
w: sys,
|
||||
f: format,
|
||||
l: LVLs,
|
||||
s: opt.DisableStack,
|
||||
d: opt.DisableTimestamp,
|
||||
t: opt.EnableTrace,
|
||||
a: opt.EnableAccessLog,
|
||||
}, nil
|
||||
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) {
|
||||
@@ -106,15 +163,15 @@ func (o *_HookSyslog) Fire(entry *logrus.Entry) error {
|
||||
ent := entry.Dup()
|
||||
ent.Level = entry.Level
|
||||
|
||||
if o.s {
|
||||
if !o.isStack() {
|
||||
ent.Data = o.filterKey(ent.Data, FieldStack)
|
||||
}
|
||||
|
||||
if o.d {
|
||||
if !o.isTimeStamp() {
|
||||
ent.Data = o.filterKey(ent.Data, FieldTime)
|
||||
}
|
||||
|
||||
if !o.t {
|
||||
if !o.isTrace() {
|
||||
ent.Data = o.filterKey(ent.Data, FieldCaller)
|
||||
ent.Data = o.filterKey(ent.Data, FieldFile)
|
||||
ent.Data = o.filterKey(ent.Data, FieldLine)
|
||||
@@ -125,7 +182,7 @@ func (o *_HookSyslog) Fire(entry *logrus.Entry) error {
|
||||
e error
|
||||
)
|
||||
|
||||
if o.a {
|
||||
if o.isAccessLog() {
|
||||
if len(entry.Message) > 0 {
|
||||
if !strings.HasSuffix(entry.Message, "\n") {
|
||||
entry.Message += "\n"
|
||||
@@ -142,38 +199,59 @@ func (o *_HookSyslog) Fire(entry *logrus.Entry) error {
|
||||
}
|
||||
}
|
||||
|
||||
switch ent.Level {
|
||||
case logrus.PanicLevel:
|
||||
_, e = o.w.Panic(p)
|
||||
case logrus.FatalLevel:
|
||||
_, e = o.w.Fatal(p)
|
||||
case logrus.ErrorLevel:
|
||||
_, e = o.w.Error(p)
|
||||
case logrus.WarnLevel:
|
||||
_, e = o.w.Warning(p)
|
||||
case logrus.InfoLevel:
|
||||
_, e = o.w.Info(p)
|
||||
case logrus.DebugLevel:
|
||||
_, e = o.w.Debug(p)
|
||||
default:
|
||||
return nil
|
||||
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 {
|
||||
return 0, fmt.Errorf("logrus.hooksyslog: connection not setup")
|
||||
var e error
|
||||
if o.w, e = o.openCreate(); e != nil {
|
||||
return 0, fmt.Errorf("logrus.hooksyslog: %v", e)
|
||||
}
|
||||
}
|
||||
|
||||
return o.w.Write(p)
|
||||
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 {
|
||||
err := o.w.Close()
|
||||
o.m.Lock()
|
||||
defer o.m.Unlock()
|
||||
|
||||
var e error
|
||||
|
||||
if o.w != nil {
|
||||
e = o.w.Close()
|
||||
}
|
||||
|
||||
o.w = nil
|
||||
return err
|
||||
return e
|
||||
}
|
||||
|
||||
func (o *_HookSyslog) filterKey(f logrus.Fields, key string) logrus.Fields {
|
||||
@@ -187,16 +265,4 @@ func (o *_HookSyslog) filterKey(f logrus.Fields, key string) logrus.Fields {
|
||||
delete(f, key)
|
||||
return f
|
||||
}
|
||||
/*
|
||||
var res = make(map[string]interface{}, 0)
|
||||
|
||||
for k, v := range f {
|
||||
if k == key {
|
||||
continue
|
||||
}
|
||||
res[k] = v
|
||||
}
|
||||
|
||||
return res
|
||||
*/
|
||||
}
|
||||
|
||||
@@ -137,6 +137,6 @@ func New(ctx context.Context) Logger {
|
||||
s: new(atomic.Value),
|
||||
f: new(atomic.Value),
|
||||
w: new(atomic.Value),
|
||||
c: new(atomic.Value),
|
||||
c: _NewCloser(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,20 +30,14 @@ package logger
|
||||
import "sync/atomic"
|
||||
|
||||
func (l *logger) Close() error {
|
||||
lst := l.closeGet()
|
||||
|
||||
l.m.Lock()
|
||||
defer func() {
|
||||
l.m.Unlock()
|
||||
l.closeClean()
|
||||
l.cancelCall()
|
||||
}()
|
||||
|
||||
for _, c := range lst {
|
||||
if c != nil {
|
||||
_ = c.Close()
|
||||
}
|
||||
}
|
||||
_ = l.c.Close()
|
||||
l.c = _NewCloser()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -30,7 +30,6 @@ package logger
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"path"
|
||||
"reflect"
|
||||
@@ -60,7 +59,7 @@ type logger struct {
|
||||
s *atomic.Value //logrus logger
|
||||
f *atomic.Value //defaults fields
|
||||
w *atomic.Value //io writer level
|
||||
c *atomic.Value
|
||||
c _Closer // closer
|
||||
}
|
||||
|
||||
func defaultFormatter() logrus.TextFormatter {
|
||||
@@ -106,57 +105,6 @@ func (l *logger) defaultFormatterNoColor() logrus.Formatter {
|
||||
return &f
|
||||
}
|
||||
|
||||
func (l *logger) closeAdd(clo io.Closer) {
|
||||
lst := append(l.closeGet(), clo)
|
||||
|
||||
l.m.Lock()
|
||||
defer l.m.Unlock()
|
||||
|
||||
if l.c == nil {
|
||||
l.c = new(atomic.Value)
|
||||
}
|
||||
|
||||
l.c.Store(lst)
|
||||
}
|
||||
|
||||
func (l *logger) closeClean() {
|
||||
if l == nil {
|
||||
return
|
||||
}
|
||||
|
||||
l.m.Lock()
|
||||
defer l.m.Unlock()
|
||||
|
||||
if l.c == nil {
|
||||
l.c = new(atomic.Value)
|
||||
}
|
||||
|
||||
l.c.Store(make([]io.Closer, 0))
|
||||
}
|
||||
|
||||
func (l *logger) closeGet() []io.Closer {
|
||||
res := make([]io.Closer, 0)
|
||||
|
||||
if l == nil {
|
||||
return res
|
||||
}
|
||||
|
||||
l.m.Lock()
|
||||
defer l.m.Unlock()
|
||||
|
||||
if l.c == nil {
|
||||
l.c = new(atomic.Value)
|
||||
}
|
||||
|
||||
if i := l.c.Load(); i == nil {
|
||||
return res
|
||||
} else if o, ok := i.([]io.Closer); ok {
|
||||
return o
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
func (l *logger) Clone() (Logger, error) {
|
||||
c := &logger{
|
||||
x: l.contextGet(),
|
||||
@@ -167,7 +115,7 @@ func (l *logger) Clone() (Logger, error) {
|
||||
s: new(atomic.Value),
|
||||
f: new(atomic.Value),
|
||||
w: new(atomic.Value),
|
||||
c: new(atomic.Value),
|
||||
c: _NewCloser(),
|
||||
}
|
||||
|
||||
c.setLoggerMutex(l.GetLevel())
|
||||
@@ -308,13 +256,8 @@ func (l *logger) GetFields() Fields {
|
||||
}
|
||||
|
||||
func (l *logger) setOptionsMutex(opt *Options) error {
|
||||
l.setOptions(opt)
|
||||
|
||||
opt = l.GetOptions()
|
||||
lvl := l.GetLevel()
|
||||
|
||||
_ = l.Close()
|
||||
|
||||
go func() {
|
||||
var ctx = l.contextNew()
|
||||
|
||||
@@ -333,6 +276,7 @@ func (l *logger) setOptionsMutex(opt *Options) error {
|
||||
obj.SetLevel(lvl.Logrus())
|
||||
obj.SetFormatter(l.defaultFormatter(opt))
|
||||
obj.SetOutput(ioutil.Discard) // Send all logs to nowhere by default
|
||||
clo := _NewCloser()
|
||||
|
||||
if !opt.DisableStandard {
|
||||
obj.AddHook(NewHookStandard(*opt, StdOut, []logrus.Level{
|
||||
@@ -354,7 +298,7 @@ func (l *logger) setOptionsMutex(opt *Options) error {
|
||||
if hook, err := NewHookFile(fopt, l.defaultFormatterNoColor()); err != nil {
|
||||
return err
|
||||
} else {
|
||||
l.closeAdd(hook)
|
||||
clo.Add(hook)
|
||||
hook.RegisterHook(obj)
|
||||
}
|
||||
}
|
||||
@@ -365,12 +309,20 @@ func (l *logger) setOptionsMutex(opt *Options) error {
|
||||
if hook, err := NewHookSyslog(lopt, l.defaultFormatterNoColor()); err != nil {
|
||||
return err
|
||||
} else {
|
||||
l.closeAdd(hook)
|
||||
clo.Add(hook)
|
||||
hook.RegisterHook(obj)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
l.setOptions(opt)
|
||||
|
||||
l.m.Lock()
|
||||
defer l.m.Unlock()
|
||||
|
||||
_ = l.c.Close()
|
||||
l.c = clo
|
||||
|
||||
l.s = new(atomic.Value)
|
||||
l.s.Store(obj)
|
||||
|
||||
|
||||
@@ -109,10 +109,10 @@ type OptionsSyslog struct {
|
||||
// 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"`
|
||||
|
||||
/*
|
||||
// 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"`
|
||||
|
||||
|
||||
@@ -111,55 +111,86 @@ type _Syslog struct {
|
||||
w *syslog.Writer
|
||||
}
|
||||
|
||||
func newSyslog(net NetworkType, host, tag string, severity SyslogSeverity, facility SyslogFacility) (syslogWrapper, error) {
|
||||
func newSyslog(net NetworkType, host, tag string, fac SyslogFacility) (syslogWrapper, error) {
|
||||
var (
|
||||
sys *syslog.Writer
|
||||
err error
|
||||
)
|
||||
|
||||
if sys, err = syslog.Dial(net.String(), host, makePriority(severity, facility), tag); err != nil {
|
||||
var obj = &_Syslog{
|
||||
w: nil,
|
||||
}
|
||||
|
||||
if obj.w, err = obj.openSyslogSev(net, host, tag, makePriority(SyslogSeverityInfo, fac)); err != nil {
|
||||
_ = obj.Close()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &_Syslog{
|
||||
w: sys,
|
||||
}, nil
|
||||
return obj, nil
|
||||
}
|
||||
|
||||
func (o *_Syslog) openSyslogSev(net NetworkType, host, tag string, prio syslog.Priority) (*syslog.Writer, error) {
|
||||
return syslog.Dial(net.String(), host, prio, tag)
|
||||
}
|
||||
|
||||
func (o *_Syslog) Write(p []byte) (n int, err error) {
|
||||
return o.WriteSev(SyslogSeverityInfo, p)
|
||||
}
|
||||
|
||||
func (o *_Syslog) WriteSev(sev SyslogSeverity, p []byte) (n int, err error) {
|
||||
if o.w == nil {
|
||||
return 0, fmt.Errorf("logrus.hooksyslog: connection not setup")
|
||||
}
|
||||
|
||||
switch sev {
|
||||
case SyslogSeverityEmerg:
|
||||
return len(p), o.w.Emerg(string(p))
|
||||
case SyslogSeverityAlert:
|
||||
return len(p), o.w.Alert(string(p))
|
||||
case SyslogSeverityCrit:
|
||||
return len(p), o.w.Crit(string(p))
|
||||
case SyslogSeverityErr:
|
||||
return len(p), o.w.Err(string(p))
|
||||
case SyslogSeverityWarning:
|
||||
return len(p), o.w.Warning(string(p))
|
||||
case SyslogSeverityNotice:
|
||||
return len(p), o.w.Notice(string(p))
|
||||
case SyslogSeverityInfo:
|
||||
return len(p), o.w.Info(string(p))
|
||||
case SyslogSeverityDebug:
|
||||
return len(p), o.w.Debug(string(p))
|
||||
}
|
||||
|
||||
return o.w.Write(p)
|
||||
}
|
||||
|
||||
func (o *_Syslog) Close() error {
|
||||
err := o.w.Close()
|
||||
o.w = nil
|
||||
return err
|
||||
if o.w == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return o.w.Close()
|
||||
}
|
||||
|
||||
func (o *_Syslog) Panic(p []byte) (n int, err error) {
|
||||
return o.Write(p)
|
||||
return o.WriteSev(SyslogSeverityAlert, p)
|
||||
}
|
||||
|
||||
func (o *_Syslog) Fatal(p []byte) (n int, err error) {
|
||||
return o.Write(p)
|
||||
return o.WriteSev(SyslogSeverityCrit, p)
|
||||
}
|
||||
|
||||
func (o *_Syslog) Error(p []byte) (n int, err error) {
|
||||
return o.Write(p)
|
||||
return o.WriteSev(SyslogSeverityErr, p)
|
||||
}
|
||||
|
||||
func (o *_Syslog) Warning(p []byte) (n int, err error) {
|
||||
return o.Write(p)
|
||||
return o.WriteSev(SyslogSeverityWarning, p)
|
||||
}
|
||||
|
||||
func (o *_Syslog) Info(p []byte) (n int, err error) {
|
||||
return o.Write(p)
|
||||
return o.WriteSev(SyslogSeverityInfo, p)
|
||||
}
|
||||
|
||||
func (o *_Syslog) Debug(p []byte) (n int, err error) {
|
||||
return o.Write(p)
|
||||
return o.WriteSev(SyslogSeverityDebug, p)
|
||||
}
|
||||
|
||||
@@ -125,7 +125,7 @@ type _WinLog struct {
|
||||
w *eventlog.Log
|
||||
}
|
||||
|
||||
func newSyslog(net NetworkType, host, tag string, severity SyslogSeverity, facility SyslogFacility) (syslogWrapper, error) {
|
||||
func newSyslog(net NetworkType, host, tag string, facility SyslogFacility) (syslogWrapper, error) {
|
||||
var (
|
||||
sys *eventlog.Log
|
||||
err error
|
||||
|
||||
@@ -2,6 +2,11 @@
|
||||
This package help to manage status router in a API to respond a standard response for status of API and his component.
|
||||
This package requires `golib/router` + go Gin Tonic API Framework.
|
||||
|
||||
This package also include 2 option of call that can be passed into query string :
|
||||
- `short` : if use, the response will only include the main status and no one component, but all health are still check
|
||||
- `online` : if use, the response will be into a list of text line composed as `status: name (release - build) - message`, instead of a JSON output
|
||||
This 2 options call be use together.
|
||||
|
||||
## Example of implementation
|
||||
We will work on an example of file/folder tree like this :
|
||||
```bash
|
||||
|
||||
@@ -26,12 +26,16 @@
|
||||
package status
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"path"
|
||||
"strings"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
|
||||
"github.com/gin-gonic/gin/render"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
liberr "github.com/nabbar/golib/errors"
|
||||
liblog "github.com/nabbar/golib/logger"
|
||||
@@ -57,7 +61,10 @@ type rtrStatus struct {
|
||||
c map[string]*atomic.Value
|
||||
}
|
||||
|
||||
const keyShortOutput = "short"
|
||||
const (
|
||||
keyShortOutput = "short"
|
||||
keyOneLineOutput = "oneline"
|
||||
)
|
||||
|
||||
func (r *rtrStatus) HttpStatusCode(codeOk, codeKO, codeWarning int) {
|
||||
r.cOk = codeOk
|
||||
@@ -204,17 +211,30 @@ func (r *rtrStatus) Get(x *gin.Context) {
|
||||
}
|
||||
|
||||
if x.Request.URL.Query().Has(keyShortOutput) {
|
||||
rsp.Components = nil
|
||||
rsp.Components = make([]CptResponse, 0)
|
||||
}
|
||||
|
||||
x.Header("Connection", "Close")
|
||||
|
||||
if code == r.cKO {
|
||||
x.AbortWithStatusJSON(code, rsp)
|
||||
x.Abort()
|
||||
}
|
||||
|
||||
if x.Request.URL.Query().Has(keyOneLineOutput) {
|
||||
var buf = bytes.NewBuffer(make([]byte, 0))
|
||||
buf.WriteString(fmt.Sprintf("%s: %s (%s - %s) : %s\n", rsp.Status, rsp.Name, rsp.Release, rsp.HashBuild, rsp.Message))
|
||||
|
||||
for _, c := range rsp.Components {
|
||||
buf.WriteString(fmt.Sprintf("%s: %s (%s - %s) : %s\n", c.Status, c.Name, c.Release, c.HashBuild, c.Message))
|
||||
}
|
||||
|
||||
x.Render(code, render.Data{
|
||||
ContentType: gin.MIMEPlain,
|
||||
Data: buf.Bytes(),
|
||||
})
|
||||
} else {
|
||||
x.JSON(code, rsp)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (r *rtrStatus) ComponentKeys() []string {
|
||||
|
||||
Reference in New Issue
Block a user