mirror of
https://github.com/arangodb/kube-arangodb.git
synced 2024-12-14 11:57:37 +00:00
Capture glog output and redirect to standard logging service
This commit is contained in:
parent
a9247586f7
commit
b3abeafcc4
3 changed files with 139 additions and 5 deletions
89
deps/github.com/golang/glog/glog_redirect.go
vendored
Normal file
89
deps/github.com/golang/glog/glog_redirect.go
vendored
Normal file
|
@ -0,0 +1,89 @@
|
|||
//
|
||||
// DISCLAIMER
|
||||
//
|
||||
// Copyright 2018 ArangoDB GmbH, Cologne, Germany
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
//
|
||||
// Author Ewout Prangsma
|
||||
//
|
||||
|
||||
//
|
||||
// Note: This code is added to the standard glog package.
|
||||
// It has to be here because it needs package level
|
||||
// access to some members.
|
||||
// Do not remove this when updating the vendored glog package!
|
||||
//
|
||||
|
||||
package glog
|
||||
|
||||
import "strings"
|
||||
|
||||
type LogLevel int
|
||||
|
||||
const (
|
||||
// Make sure these constants end up having the same indexes as the severity constants
|
||||
LogLevelInfo LogLevel = iota
|
||||
LogLevelWarning
|
||||
LogLevelError
|
||||
LogLevelFatal
|
||||
)
|
||||
|
||||
// redirectWriter wraps a callback that is called when data is written to it.
|
||||
type redirectWriter struct {
|
||||
cb func(level LogLevel, message string)
|
||||
level LogLevel
|
||||
}
|
||||
|
||||
func (w *redirectWriter) Flush() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (w *redirectWriter) Sync() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (w *redirectWriter) Write(p []byte) (n int, err error) {
|
||||
msg := string(p)
|
||||
if msg[len(msg)-1] == '\n' {
|
||||
msg = msg[:len(msg)-1]
|
||||
}
|
||||
if idx := strings.IndexByte(msg, ']'); idx > 0 {
|
||||
msg = strings.TrimSpace(msg[idx+1:])
|
||||
}
|
||||
w.cb(w.level, msg)
|
||||
return len(p), nil
|
||||
}
|
||||
|
||||
// RedirectOutput redirects output of the given logging to the given callback.
|
||||
func (l *loggingT) RedirectOutput(cb func(level LogLevel, message string)) {
|
||||
l.mu.Lock()
|
||||
defer l.mu.Unlock()
|
||||
|
||||
l.toStderr = false
|
||||
l.alsoToStderr = false
|
||||
for i := range logging.file {
|
||||
logging.file[i] = &redirectWriter{
|
||||
cb: cb,
|
||||
level: LogLevel(i),
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// RedirectOutput redirects output of thestandard logging to the given callback.
|
||||
func RedirectOutput(cb func(level LogLevel, message string)) {
|
||||
logging.RedirectOutput(cb)
|
||||
}
|
24
main.go
24
main.go
|
@ -29,6 +29,7 @@ import (
|
|||
"net/http"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
@ -116,12 +117,25 @@ func cmdUsage(cmd *cobra.Command, args []string) {
|
|||
|
||||
// Run the operator
|
||||
func cmdMainRun(cmd *cobra.Command, args []string) {
|
||||
// Get environment
|
||||
namespace := os.Getenv(constants.EnvOperatorPodNamespace)
|
||||
name := os.Getenv(constants.EnvOperatorPodName)
|
||||
ip := os.Getenv(constants.EnvOperatorPodIP)
|
||||
|
||||
// Prepare log service
|
||||
goflag.CommandLine.Parse([]string{"-logtostderr"})
|
||||
var err error
|
||||
logService, err = logging.NewService(logLevel)
|
||||
if err != nil {
|
||||
cliLog.Fatal().Err(err).Msg("Failed to initialize log service")
|
||||
}
|
||||
logService.ConfigureRootLogger(func(log zerolog.Logger) zerolog.Logger {
|
||||
podNameParts := strings.Split(name, "-")
|
||||
operatorID := podNameParts[len(podNameParts)-1]
|
||||
cliLog = cliLog.With().Str("operator-id", operatorID).Logger()
|
||||
return log.With().Str("operator-id", operatorID).Logger()
|
||||
})
|
||||
logService.CaptureGLog(logService.MustGetLogger("glog"))
|
||||
|
||||
// Check operating mode
|
||||
if !operatorOptions.enableDeployment && !operatorOptions.enableDeploymentReplication && !operatorOptions.enableStorage {
|
||||
|
@ -129,18 +143,18 @@ func cmdMainRun(cmd *cobra.Command, args []string) {
|
|||
}
|
||||
|
||||
// Log version
|
||||
cliLog.Info().Msgf("Starting arangodb-operator, version %s build %s", projectVersion, projectBuild)
|
||||
cliLog.Info().
|
||||
Str("pod-name", name).
|
||||
Str("pod-namespace", namespace).
|
||||
Msgf("Starting arangodb-operator, version %s build %s", projectVersion, projectBuild)
|
||||
|
||||
// Get environment
|
||||
namespace := os.Getenv(constants.EnvOperatorPodNamespace)
|
||||
// Check environment
|
||||
if len(namespace) == 0 {
|
||||
cliLog.Fatal().Msgf("%s environment variable missing", constants.EnvOperatorPodNamespace)
|
||||
}
|
||||
name := os.Getenv(constants.EnvOperatorPodName)
|
||||
if len(name) == 0 {
|
||||
cliLog.Fatal().Msgf("%s environment variable missing", constants.EnvOperatorPodName)
|
||||
}
|
||||
ip := os.Getenv(constants.EnvOperatorPodIP)
|
||||
if len(ip) == 0 {
|
||||
cliLog.Fatal().Msgf("%s environment variable missing", constants.EnvOperatorPodIP)
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ import (
|
|||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"github.com/rs/zerolog"
|
||||
)
|
||||
|
||||
|
@ -47,6 +48,10 @@ type Service interface {
|
|||
MustGetLogger(name string) zerolog.Logger
|
||||
// MustSetLevel sets the log level for the component with given name to given level.
|
||||
MustSetLevel(name, level string)
|
||||
// ConfigureRootLogger calls the given callback to modify the root logger.
|
||||
ConfigureRootLogger(cb func(rootLog zerolog.Logger) zerolog.Logger)
|
||||
// CaptureGLog configures glog to write to the given logger
|
||||
CaptureGLog(log zerolog.Logger)
|
||||
}
|
||||
|
||||
// loggingService implements Service
|
||||
|
@ -83,6 +88,32 @@ func NewService(defaultLevel string) (Service, error) {
|
|||
return s, nil
|
||||
}
|
||||
|
||||
// ConfigureRootLogger calls the given callback to modify the root logger.
|
||||
func (s *loggingService) ConfigureRootLogger(cb func(rootLog zerolog.Logger) zerolog.Logger) {
|
||||
s.mutex.Lock()
|
||||
defer s.mutex.Unlock()
|
||||
|
||||
s.rootLog = cb(s.rootLog)
|
||||
}
|
||||
|
||||
// CaptureGLog configures glog to write to the given logger
|
||||
func (s *loggingService) CaptureGLog(log zerolog.Logger) {
|
||||
glog.RedirectOutput(func(level glog.LogLevel, msg string) {
|
||||
var e *zerolog.Event
|
||||
switch level {
|
||||
case glog.LogLevelWarning:
|
||||
e = log.WithLevel(zerolog.WarnLevel)
|
||||
case glog.LogLevelError:
|
||||
e = log.WithLevel(zerolog.ErrorLevel)
|
||||
case glog.LogLevelFatal:
|
||||
e = log.WithLevel(zerolog.FatalLevel)
|
||||
default:
|
||||
e = log.WithLevel(zerolog.InfoLevel)
|
||||
}
|
||||
e.Msg(msg)
|
||||
})
|
||||
}
|
||||
|
||||
// MustGetLogger creates a logger with given name
|
||||
func (s *loggingService) MustGetLogger(name string) zerolog.Logger {
|
||||
s.mutex.Lock()
|
||||
|
|
Loading…
Reference in a new issue