mirror of
https://github.com/minio/minio.git
synced 2025-04-06 12:50:34 -04:00
Make logger webhook config dynamic (#14289)
It should not be required to restart the server after setting the logger webhook config.
This commit is contained in:
parent
b29224f62f
commit
28f188e3ef
@ -574,18 +574,6 @@ func lookupConfigs(s config.Config, objAPI ObjectLayer) {
|
|||||||
logger.LogIf(ctx, fmt.Errorf("Unable to initialize logger/audit targets: %w", err))
|
logger.LogIf(ctx, fmt.Errorf("Unable to initialize logger/audit targets: %w", err))
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, l := range loggerCfg.HTTP {
|
|
||||||
if l.Enabled {
|
|
||||||
l.LogOnce = logger.LogOnceIf
|
|
||||||
l.UserAgent = loggerUserAgent
|
|
||||||
l.Transport = NewGatewayHTTPTransportWithClientCerts(l.ClientCert, l.ClientKey)
|
|
||||||
// Enable http logging
|
|
||||||
if err = logger.AddTarget(http.New(l)); err != nil {
|
|
||||||
logger.LogIf(ctx, fmt.Errorf("Unable to initialize server logger HTTP target: %w", err))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, l := range loggerCfg.AuditWebhook {
|
for _, l := range loggerCfg.AuditWebhook {
|
||||||
if l.Enabled {
|
if l.Enabled {
|
||||||
l.LogOnce = logger.LogOnceIf
|
l.LogOnce = logger.LogOnceIf
|
||||||
@ -663,6 +651,25 @@ func applyDynamicConfig(ctx context.Context, objAPI ObjectLayer, s config.Config
|
|||||||
return fmt.Errorf("Unable to apply scanner config: %w", err)
|
return fmt.Errorf("Unable to apply scanner config: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Logger webhook
|
||||||
|
loggerCfg, err := logger.LookupConfig(s)
|
||||||
|
if err != nil {
|
||||||
|
logger.LogIf(ctx, fmt.Errorf("Unable to load logger webhook config: %w", err))
|
||||||
|
}
|
||||||
|
userAgent := getUserAgent(getMinioMode())
|
||||||
|
for n, l := range loggerCfg.HTTP {
|
||||||
|
if l.Enabled {
|
||||||
|
l.LogOnce = logger.LogOnceIf
|
||||||
|
l.UserAgent = userAgent
|
||||||
|
l.Transport = NewGatewayHTTPTransportWithClientCerts(l.ClientCert, l.ClientKey)
|
||||||
|
loggerCfg.HTTP[n] = l
|
||||||
|
}
|
||||||
|
}
|
||||||
|
err = logger.UpdateTargets(loggerCfg)
|
||||||
|
if err != nil {
|
||||||
|
logger.LogIf(ctx, fmt.Errorf("Unable to update logger webhook config: %w", err))
|
||||||
|
}
|
||||||
|
|
||||||
// Apply configurations.
|
// Apply configurations.
|
||||||
// We should not fail after this.
|
// We should not fail after this.
|
||||||
var setDriveCounts []int
|
var setDriveCounts []int
|
||||||
|
@ -150,6 +150,10 @@ func (sys *HTTPConsoleLoggerSys) Content() (logs []log.Entry) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Cancel - cancels the target
|
||||||
|
func (sys *HTTPConsoleLoggerSys) Cancel() {
|
||||||
|
}
|
||||||
|
|
||||||
// Send log message 'e' to console and publish to console
|
// Send log message 'e' to console and publish to console
|
||||||
// log pubsub system
|
// log pubsub system
|
||||||
func (sys *HTTPConsoleLoggerSys) Send(e interface{}, logKind string) error {
|
func (sys *HTTPConsoleLoggerSys) Send(e interface{}, logKind string) error {
|
||||||
|
@ -55,6 +55,9 @@ func (t *testingLogger) Init() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *testingLogger) Cancel() {
|
||||||
|
}
|
||||||
|
|
||||||
func (t *testingLogger) Send(entry interface{}, errKind string) error {
|
func (t *testingLogger) Send(entry interface{}, errKind string) error {
|
||||||
t.mu.Lock()
|
t.mu.Lock()
|
||||||
defer t.mu.Unlock()
|
defer t.mu.Unlock()
|
||||||
|
@ -166,6 +166,7 @@ var SubSystemsDynamic = set.CreateStringSet(
|
|||||||
ScannerSubSys,
|
ScannerSubSys,
|
||||||
HealSubSys,
|
HealSubSys,
|
||||||
SubnetSubSys,
|
SubnetSubSys,
|
||||||
|
LoggerWebhookSubSys,
|
||||||
)
|
)
|
||||||
|
|
||||||
// SubSystemsSingleTargets - subsystems which only support single target.
|
// SubSystemsSingleTargets - subsystems which only support single target.
|
||||||
|
@ -25,6 +25,8 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
xhttp "github.com/minio/minio/internal/http"
|
xhttp "github.com/minio/minio/internal/http"
|
||||||
@ -55,6 +57,9 @@ type Config struct {
|
|||||||
// buffer is full, new logs are just ignored and an error
|
// buffer is full, new logs are just ignored and an error
|
||||||
// is returned to the caller.
|
// is returned to the caller.
|
||||||
type Target struct {
|
type Target struct {
|
||||||
|
status int32
|
||||||
|
wg sync.WaitGroup
|
||||||
|
|
||||||
// Channel of log entries
|
// Channel of log entries
|
||||||
logCh chan interface{}
|
logCh chan interface{}
|
||||||
|
|
||||||
@ -109,6 +114,7 @@ func (h *Target) Init() error {
|
|||||||
h.config.Endpoint, resp.Status)
|
h.config.Endpoint, resp.Status)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
h.status = 1
|
||||||
go h.startHTTPLogger()
|
go h.startHTTPLogger()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -120,14 +126,13 @@ func acceptedResponseStatusCode(code int) bool {
|
|||||||
return acceptedStatusCodeMap[code]
|
return acceptedStatusCodeMap[code]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *Target) startHTTPLogger() {
|
func (h *Target) logEntry(entry interface{}) {
|
||||||
// Create a routine which sends json logs received
|
h.wg.Add(1)
|
||||||
// from an internal channel.
|
defer h.wg.Done()
|
||||||
go func() {
|
|
||||||
for entry := range h.logCh {
|
|
||||||
logJSON, err := json.Marshal(&entry)
|
logJSON, err := json.Marshal(&entry)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), webhookCallTimeout)
|
ctx, cancel := context.WithTimeout(context.Background(), webhookCallTimeout)
|
||||||
@ -136,7 +141,7 @@ func (h *Target) startHTTPLogger() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
h.config.LogOnce(ctx, fmt.Errorf("%s returned '%w', please check your endpoint configuration", h.config.Endpoint, err), h.config.Endpoint)
|
h.config.LogOnce(ctx, fmt.Errorf("%s returned '%w', please check your endpoint configuration", h.config.Endpoint, err), h.config.Endpoint)
|
||||||
cancel()
|
cancel()
|
||||||
continue
|
return
|
||||||
}
|
}
|
||||||
req.Header.Set(xhttp.ContentType, "application/json")
|
req.Header.Set(xhttp.ContentType, "application/json")
|
||||||
|
|
||||||
@ -153,7 +158,7 @@ func (h *Target) startHTTPLogger() {
|
|||||||
cancel()
|
cancel()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.config.LogOnce(ctx, fmt.Errorf("%s returned '%w', please check your endpoint configuration", h.config.Endpoint, err), h.config.Endpoint)
|
h.config.LogOnce(ctx, fmt.Errorf("%s returned '%w', please check your endpoint configuration", h.config.Endpoint, err), h.config.Endpoint)
|
||||||
continue
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Drain any response.
|
// Drain any response.
|
||||||
@ -168,6 +173,14 @@ func (h *Target) startHTTPLogger() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h *Target) startHTTPLogger() {
|
||||||
|
// Create a routine which sends json logs received
|
||||||
|
// from an internal channel.
|
||||||
|
go func() {
|
||||||
|
for entry := range h.logCh {
|
||||||
|
h.logEntry(entry)
|
||||||
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -184,6 +197,11 @@ func New(config Config) *Target {
|
|||||||
|
|
||||||
// Send log message 'e' to http target.
|
// Send log message 'e' to http target.
|
||||||
func (h *Target) Send(entry interface{}, errKind string) error {
|
func (h *Target) Send(entry interface{}, errKind string) error {
|
||||||
|
if atomic.LoadInt32(&h.status) == 0 {
|
||||||
|
// Channel was closed or used before init.
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case h.logCh <- entry:
|
case h.logCh <- entry:
|
||||||
default:
|
default:
|
||||||
@ -194,3 +212,11 @@ func (h *Target) Send(entry interface{}, errKind string) error {
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Cancel - cancels the target
|
||||||
|
func (h *Target) Cancel() {
|
||||||
|
if atomic.CompareAndSwapInt32(&h.status, 1, 0) {
|
||||||
|
close(h.logCh)
|
||||||
|
}
|
||||||
|
h.wg.Wait()
|
||||||
|
}
|
||||||
|
@ -197,6 +197,10 @@ func (h *Target) Init() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Cancel - cancels the target
|
||||||
|
func (h *Target) Cancel() {
|
||||||
|
}
|
||||||
|
|
||||||
// New initializes a new logger target which
|
// New initializes a new logger target which
|
||||||
// sends log over http to the specified endpoint
|
// sends log over http to the specified endpoint
|
||||||
func New(config Config) *Target {
|
func New(config Config) *Target {
|
||||||
|
@ -20,6 +20,8 @@ package logger
|
|||||||
import (
|
import (
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
|
||||||
|
"github.com/minio/minio/internal/logger/target/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Target is the entity that we will receive
|
// Target is the entity that we will receive
|
||||||
@ -29,6 +31,7 @@ type Target interface {
|
|||||||
String() string
|
String() string
|
||||||
Endpoint() string
|
Endpoint() string
|
||||||
Init() error
|
Init() error
|
||||||
|
Cancel()
|
||||||
Send(entry interface{}, errKind string) error
|
Send(entry interface{}, errKind string) error
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,3 +111,37 @@ func AddTarget(t Target) error {
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func cancelAllTargets() {
|
||||||
|
for _, tgt := range targets {
|
||||||
|
tgt.Cancel()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func initTargets(cfg Config) (tgts []Target, err error) {
|
||||||
|
for _, l := range cfg.HTTP {
|
||||||
|
if l.Enabled {
|
||||||
|
t := http.New(l)
|
||||||
|
if err = t.Init(); err != nil {
|
||||||
|
return tgts, err
|
||||||
|
}
|
||||||
|
tgts = append(tgts, t)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return tgts, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateTargets swaps targets with newly loaded ones from the cfg
|
||||||
|
func UpdateTargets(cfg Config) error {
|
||||||
|
updated, err := initTargets(cfg)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
swapMu.Lock()
|
||||||
|
atomic.StoreInt32(&nTargets, int32(len(updated)))
|
||||||
|
cancelAllTargets() // cancel running targets
|
||||||
|
targets = updated
|
||||||
|
swapMu.Unlock()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user