Skip to content

Commit 5618606

Browse files
authored
Merge pull request #203 from arangodb/feature/improved-log-ids
Log improvements
2 parents cf338bd + da49ab0 commit 5618606

File tree

3 files changed

+139
-5
lines changed

3 files changed

+139
-5
lines changed
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
//
2+
// DISCLAIMER
3+
//
4+
// Copyright 2018 ArangoDB GmbH, Cologne, Germany
5+
//
6+
// Licensed under the Apache License, Version 2.0 (the "License");
7+
// you may not use this file except in compliance with the License.
8+
// You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing, software
13+
// distributed under the License is distributed on an "AS IS" BASIS,
14+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
// See the License for the specific language governing permissions and
16+
// limitations under the License.
17+
//
18+
// Copyright holder is ArangoDB GmbH, Cologne, Germany
19+
//
20+
// Author Ewout Prangsma
21+
//
22+
23+
//
24+
// Note: This code is added to the standard glog package.
25+
// It has to be here because it needs package level
26+
// access to some members.
27+
// Do not remove this when updating the vendored glog package!
28+
//
29+
30+
package glog
31+
32+
import "strings"
33+
34+
type LogLevel int
35+
36+
const (
37+
// Make sure these constants end up having the same indexes as the severity constants
38+
LogLevelInfo LogLevel = iota
39+
LogLevelWarning
40+
LogLevelError
41+
LogLevelFatal
42+
)
43+
44+
// redirectWriter wraps a callback that is called when data is written to it.
45+
type redirectWriter struct {
46+
cb func(level LogLevel, message string)
47+
level LogLevel
48+
}
49+
50+
func (w *redirectWriter) Flush() error {
51+
return nil
52+
}
53+
54+
func (w *redirectWriter) Sync() error {
55+
return nil
56+
}
57+
58+
func (w *redirectWriter) Write(p []byte) (n int, err error) {
59+
msg := string(p)
60+
if msg[len(msg)-1] == '\n' {
61+
msg = msg[:len(msg)-1]
62+
}
63+
if idx := strings.IndexByte(msg, ']'); idx > 0 {
64+
msg = strings.TrimSpace(msg[idx+1:])
65+
}
66+
w.cb(w.level, msg)
67+
return len(p), nil
68+
}
69+
70+
// RedirectOutput redirects output of the given logging to the given callback.
71+
func (l *loggingT) RedirectOutput(cb func(level LogLevel, message string)) {
72+
l.mu.Lock()
73+
defer l.mu.Unlock()
74+
75+
l.toStderr = false
76+
l.alsoToStderr = false
77+
for i := range logging.file {
78+
logging.file[i] = &redirectWriter{
79+
cb: cb,
80+
level: LogLevel(i),
81+
}
82+
}
83+
return
84+
}
85+
86+
// RedirectOutput redirects output of thestandard logging to the given callback.
87+
func RedirectOutput(cb func(level LogLevel, message string)) {
88+
logging.RedirectOutput(cb)
89+
}

main.go

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import (
2929
"net/http"
3030
"os"
3131
"strconv"
32+
"strings"
3233
"time"
3334

3435
"github.com/pkg/errors"
@@ -118,31 +119,44 @@ func cmdUsage(cmd *cobra.Command, args []string) {
118119

119120
// Run the operator
120121
func cmdMainRun(cmd *cobra.Command, args []string) {
122+
// Get environment
123+
namespace := os.Getenv(constants.EnvOperatorPodNamespace)
124+
name := os.Getenv(constants.EnvOperatorPodName)
125+
ip := os.Getenv(constants.EnvOperatorPodIP)
126+
127+
// Prepare log service
121128
goflag.CommandLine.Parse([]string{"-logtostderr"})
122129
var err error
123130
logService, err = logging.NewService(logLevel)
124131
if err != nil {
125132
cliLog.Fatal().Err(err).Msg("Failed to initialize log service")
126133
}
134+
logService.ConfigureRootLogger(func(log zerolog.Logger) zerolog.Logger {
135+
podNameParts := strings.Split(name, "-")
136+
operatorID := podNameParts[len(podNameParts)-1]
137+
cliLog = cliLog.With().Str("operator-id", operatorID).Logger()
138+
return log.With().Str("operator-id", operatorID).Logger()
139+
})
140+
logService.CaptureGLog(logService.MustGetLogger("glog"))
127141

128142
// Check operating mode
129143
if !operatorOptions.enableDeployment && !operatorOptions.enableDeploymentReplication && !operatorOptions.enableStorage {
130144
cliLog.Fatal().Err(err).Msg("Turn on --operator.deployment, --operator.deployment-replication, --operator.storage or any combination of these")
131145
}
132146

133147
// Log version
134-
cliLog.Info().Msgf("Starting arangodb-operator, version %s build %s", projectVersion, projectBuild)
148+
cliLog.Info().
149+
Str("pod-name", name).
150+
Str("pod-namespace", namespace).
151+
Msgf("Starting arangodb-operator, version %s build %s", projectVersion, projectBuild)
135152

136-
// Get environment
137-
namespace := os.Getenv(constants.EnvOperatorPodNamespace)
153+
// Check environment
138154
if len(namespace) == 0 {
139155
cliLog.Fatal().Msgf("%s environment variable missing", constants.EnvOperatorPodNamespace)
140156
}
141-
name := os.Getenv(constants.EnvOperatorPodName)
142157
if len(name) == 0 {
143158
cliLog.Fatal().Msgf("%s environment variable missing", constants.EnvOperatorPodName)
144159
}
145-
ip := os.Getenv(constants.EnvOperatorPodIP)
146160
if len(ip) == 0 {
147161
cliLog.Fatal().Msgf("%s environment variable missing", constants.EnvOperatorPodIP)
148162
}

pkg/logging/logger.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import (
2828
"strings"
2929
"sync"
3030

31+
"github.com/golang/glog"
3132
"github.com/rs/zerolog"
3233
)
3334

@@ -47,6 +48,10 @@ type Service interface {
4748
MustGetLogger(name string) zerolog.Logger
4849
// MustSetLevel sets the log level for the component with given name to given level.
4950
MustSetLevel(name, level string)
51+
// ConfigureRootLogger calls the given callback to modify the root logger.
52+
ConfigureRootLogger(cb func(rootLog zerolog.Logger) zerolog.Logger)
53+
// CaptureGLog configures glog to write to the given logger
54+
CaptureGLog(log zerolog.Logger)
5055
}
5156

5257
// loggingService implements Service
@@ -83,6 +88,32 @@ func NewService(defaultLevel string) (Service, error) {
8388
return s, nil
8489
}
8590

91+
// ConfigureRootLogger calls the given callback to modify the root logger.
92+
func (s *loggingService) ConfigureRootLogger(cb func(rootLog zerolog.Logger) zerolog.Logger) {
93+
s.mutex.Lock()
94+
defer s.mutex.Unlock()
95+
96+
s.rootLog = cb(s.rootLog)
97+
}
98+
99+
// CaptureGLog configures glog to write to the given logger
100+
func (s *loggingService) CaptureGLog(log zerolog.Logger) {
101+
glog.RedirectOutput(func(level glog.LogLevel, msg string) {
102+
var e *zerolog.Event
103+
switch level {
104+
case glog.LogLevelWarning:
105+
e = log.WithLevel(zerolog.WarnLevel)
106+
case glog.LogLevelError:
107+
e = log.WithLevel(zerolog.ErrorLevel)
108+
case glog.LogLevelFatal:
109+
e = log.WithLevel(zerolog.FatalLevel)
110+
default:
111+
e = log.WithLevel(zerolog.InfoLevel)
112+
}
113+
e.Msg(msg)
114+
})
115+
}
116+
86117
// MustGetLogger creates a logger with given name
87118
func (s *loggingService) MustGetLogger(name string) zerolog.Logger {
88119
s.mutex.Lock()

0 commit comments

Comments
 (0)