Skip to content

Commit 3d53a0a

Browse files
authored
Add support to suppress tls logging (#157)
- Allow a way to suppress the logging messages related to tls handshake error logged in https://cs.opensource.google/go/go/+/master:src/net/http/server.go;l=1933?q=%22TLS%20handshake%20error%20from%20%22&ss=go%2Fgo. - Remove unused anomaly logger method
1 parent ae85f65 commit 3d53a0a

File tree

6 files changed

+111
-28
lines changed

6 files changed

+111
-28
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,10 @@ Configure and use Prometheus or a StatsD-interface supporting data store for met
165165

166166
![Basic Dashboard](./doc/grafana-dashboard.png)
167167

168+
## Logging
169+
170+
To suppress [tls handshake error logging](https://cs.opensource.google/go/go/+/master:src/net/http/server.go;l=1933?q=%22TLS%20handshake%20error%20from%20%22&ss=go%2Fgo), set environment variable `SUPPRESS_TLS_HANDSHAKE_ERROR_LOGGING` to `true`. See [docker compose](./docker-compose.yml) for example.
171+
168172
## Protos
169173
Data is encapsulated into protobuf messages of different types. Protos can be recompiled via:
170174

config/config_initializer.go

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package config
33
import (
44
"encoding/json"
55
"flag"
6+
"log"
67
"os"
78

89
"github.com/sirupsen/logrus/hooks/test"
@@ -15,7 +16,11 @@ import (
1516
// LoadApplicationConfiguration loads the configuration from args and config files
1617
func LoadApplicationConfiguration() (config *Config, logger *logrus.Logger, err error) {
1718

18-
logger = logrus.NewBasicLogrusLogger("fleet-telemetry")
19+
logger, err = logrus.NewBasicLogrusLogger("fleet-telemetry")
20+
if err != nil {
21+
return nil, nil, err
22+
}
23+
log.SetOutput(logger)
1924

2025
configFilePath := loadConfigFlags()
2126

@@ -38,9 +43,15 @@ func loadApplicationConfig(configFilePath string) (*Config, error) {
3843

3944
config := &Config{}
4045
err = json.NewDecoder(configFile).Decode(&config)
46+
if err != nil {
47+
return nil, err
48+
}
4149

4250
log, _ := test.NewNullLogger()
43-
logger := logrus.NewLogrusLogger("null_logger", map[string]interface{}{}, log.WithField("context", "metrics"))
51+
logger, err := logrus.NewLogrusLogger("null_logger", map[string]interface{}{}, log.WithField("context", "metrics"))
52+
if err != nil {
53+
return nil, err
54+
}
4455
config.MetricCollector = metrics.NewCollector(config.Monitoring, logger)
4556

4657
config.AckChan = make(chan *telemetry.Record)

docker-compose.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ services:
2323
AWS_ACCESS_KEY_ID: ABC123
2424
AWS_SECRET_ACCESS_KEY: EFG456
2525
PUBSUB_EMULATOR_HOST: pubsub:8085
26+
SUPPRESS_TLS_HANDSHAKE_ERROR_LOGGING: true
2627
depends_on:
2728
kinesis:
2829
condition: service_healthy

logger/logger.go

Lines changed: 55 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ package logrus
22

33
import (
44
"os"
5+
"strconv"
6+
"strings"
57

68
"github.com/mattn/go-colorable"
79
"github.com/sirupsen/logrus"
@@ -19,6 +21,10 @@ const (
1921
FATAL
2022
)
2123

24+
const (
25+
tlsFilter = "http: TLS handshake error from"
26+
)
27+
2228
// AllLogType is a map of LogType to string names
2329
var AllLogType = map[LogType]string{
2430
DEBUG: "debug",
@@ -34,29 +40,43 @@ type LogInfo map[string]interface{}
3440
// Logger a logrus implementer of the JSON logger interface
3541
type Logger struct {
3642
logger *logrus.Entry
43+
44+
suppressionFilter string
3745
}
3846

3947
// NewLogrusLogger return a LogrusLogger
40-
func NewLogrusLogger(context string, info LogInfo, logger *logrus.Entry) *Logger {
48+
func NewLogrusLogger(context string, info LogInfo, logger *logrus.Entry) (*Logger, error) {
4149
if logger == nil {
4250
logger = logrus.WithField("context", context)
4351
}
44-
4552
l := &Logger{logger: logger}
4653
l.logger = l.getEntry(info)
47-
return l
54+
value, ok := os.LookupEnv("SUPPRESS_TLS_HANDSHAKE_ERROR_LOGGING")
55+
if ok {
56+
b, err := strconv.ParseBool(value)
57+
if err != nil {
58+
return nil, err
59+
}
60+
if b {
61+
l.suppressionFilter = tlsFilter
62+
}
63+
}
64+
return l, nil
4865
}
4966

5067
// NewBasicLogrusLogger creates a logrus logger with a context but no other options
51-
func NewBasicLogrusLogger(context string) *Logger {
68+
func NewBasicLogrusLogger(context string) (*Logger, error) {
5269
return NewLogrusLogger(context, nil, nil)
5370
}
5471

5572
// NewColorLogrusLogger creates a logrus logger with a context and colorized output support
56-
func NewColorLogrusLogger(context string) *Logger {
57-
logger := NewLogrusLogger(context, nil, nil)
73+
func NewColorLogrusLogger(context string) (*Logger, error) {
74+
logger, err := NewLogrusLogger(context, nil, nil)
75+
if err != nil {
76+
return nil, err
77+
}
5878
logger.SetColorFormatter(true)
59-
return logger
79+
return logger, nil
6080
}
6181

6282
// Set minimum log level for messages
@@ -69,8 +89,18 @@ func SetLogLevel(name string) {
6989
logrus.SetLevel(level)
7090
}
7191

92+
func (l *Logger) shouldSuppress(message string) bool {
93+
if l.suppressionFilter == "" {
94+
return false
95+
}
96+
return strings.Contains(message, l.suppressionFilter)
97+
}
98+
7299
// Log logs a message on a particular log level
73100
func (l *Logger) Log(logType LogType, message string, info LogInfo) {
101+
if l.shouldSuppress(message) {
102+
return
103+
}
74104
entry := l.getEntry(info)
75105

76106
switch logType {
@@ -87,13 +117,22 @@ func (l *Logger) Log(logType LogType, message string, info LogInfo) {
87117
}
88118
}
89119

120+
// Write implements the Write method of the io.Writer interface
121+
func (l *Logger) Write(p []byte) (n int, err error) {
122+
l.ActivityLog(string(p), nil)
123+
return len(p), nil
124+
}
125+
90126
// Print allows Printing on the logger
91127
func (l *Logger) Print(v ...interface{}) {
92128
l.logger.Print(v...)
93129
}
94130

95131
// Printf allows Printf'ing on the logger
96132
func (l *Logger) Printf(format string, v ...interface{}) {
133+
if l.shouldSuppress(format) {
134+
return
135+
}
97136
l.logger.Printf(format, v...)
98137
}
99138

@@ -104,33 +143,30 @@ func (l *Logger) Println(v ...interface{}) {
104143

105144
// Fatalf allows Fatalf'ing on the logger
106145
func (l *Logger) Fatalf(format string, v ...interface{}) {
146+
if l.shouldSuppress(format) {
147+
return
148+
}
107149
l.logger.Fatalf(format, v...)
108150
}
109151

110152
// ActivityLog is used for web activity logs
111153
func (l *Logger) ActivityLog(message string, info LogInfo) {
154+
if l.shouldSuppress(message) {
155+
return
156+
}
112157
entry := l.getEntry(info)
113158
entry.WithField("activity", true).Info(message)
114159
}
115160

116-
// AnomalyLog is used to tag a log line as an anomaly
117-
func (l *Logger) AnomalyLog(message string, info LogInfo) {
118-
entry := l.getEntry(info)
119-
entry.WithField("anomaly", true).Error(message)
120-
}
121-
122161
// ErrorLog log an error message
123162
func (l *Logger) ErrorLog(message string, err error, info LogInfo) {
163+
if l.shouldSuppress(message) {
164+
return
165+
}
124166
entry := l.getEntry(info)
125167
entry.WithError(err).Error(message)
126168
}
127169

128-
// AnomalyLogError log an error that is an anomaly
129-
func (l *Logger) AnomalyLogError(message string, err error, info LogInfo) {
130-
entry := l.getEntry(info)
131-
entry.WithError(err).WithField("anomaly", true).Error(message)
132-
}
133-
134170
// SetJSONFormatter sets logger to emit JSON or false => TextFormatter
135171
func (l *Logger) SetJSONFormatter(json bool) {
136172
if json {

logger/logger_logrus_test.go

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package logrus
22

33
import (
44
"errors"
5+
"os"
56

67
githubLogrus "github.com/sirupsen/logrus"
78

@@ -10,29 +11,58 @@ import (
1011
)
1112

1213
var _ = Describe("logger tests", func() {
14+
15+
BeforeEach(func() {
16+
os.Clearenv()
17+
})
18+
1319
It("works", func() {
1420
data := map[string]interface{}{"simple": "value", "complex": `has "quotes" and spaces`, "boolean": true}
1521

1622
logger, hook := NoOpLogger()
1723

1824
logger.Log(INFO, "http", data)
19-
Expect(len(hook.Entries)).To(Equal(1))
25+
Expect(hook.Entries).To(HaveLen(1))
2026
Expect(hook.LastEntry().Level).To(Equal(githubLogrus.InfoLevel))
2127
Expect(hook.LastEntry().Message).To(Equal("http"))
2228

2329
logger.ActivityLog("sample_activity_log", data)
24-
Expect(len(hook.Entries)).To(Equal(2))
30+
Expect(hook.Entries).To(HaveLen(2))
2531
Expect(hook.LastEntry().Level).To(Equal(githubLogrus.InfoLevel))
2632
Expect(hook.LastEntry().Message).To(Equal("sample_activity_log"))
2733

28-
logger.AnomalyLog("sample_anomaly_log", data)
29-
Expect(len(hook.Entries)).To(Equal(3))
34+
logger.ErrorLog("sample_anomaly_log", nil, data)
35+
Expect(hook.Entries).To(HaveLen(3))
3036
Expect(hook.LastEntry().Level).To(Equal(githubLogrus.ErrorLevel))
3137
Expect(hook.LastEntry().Message).To(Equal("sample_anomaly_log"))
3238

33-
logger.AnomalyLogError("sample_anomaly_log_2", errors.New("error message"), nil)
34-
Expect(len(hook.Entries)).To(Equal(4))
39+
logger.ErrorLog("sample_anomaly_log_2", errors.New("error message"), nil)
40+
Expect(hook.Entries).To(HaveLen(4))
3541
Expect(hook.LastEntry().Level).To(Equal(githubLogrus.ErrorLevel))
3642
Expect(hook.LastEntry().Message).To(Equal("sample_anomaly_log_2"))
43+
44+
logger.Log(ERROR, "http: TLS handshake error from 0.0.0.0:1: EOF", nil)
45+
Expect(hook.Entries).To(HaveLen(5))
46+
Expect(hook.LastEntry().Level).To(Equal(githubLogrus.ErrorLevel))
47+
Expect(hook.LastEntry().Message).To(Equal("http: TLS handshake error from 0.0.0.0:1: EOF"))
3748
})
49+
50+
Context("Tls handshake error", func() {
51+
DescribeTable("suppresses",
52+
func(envValue string) {
53+
os.Setenv("SUPPRESS_TLS_HANDSHAKE_ERROR_LOGGING", envValue)
54+
logger, hook := NoOpLogger()
55+
logger.Log(ERROR, "http: TLS handshake error from 0.0.0.0:1: EOF", nil)
56+
Expect(hook.Entries).To(BeEmpty())
57+
logger.Log(ERROR, "Random error", nil)
58+
Expect(hook.Entries).To(HaveLen(1))
59+
Expect(hook.LastEntry().Message).To(Equal("Random error"))
60+
61+
},
62+
Entry("for env variable true", "true"),
63+
Entry("for env variable TRUE", "TRUE"),
64+
Entry("for env variable 1", "1"),
65+
)
66+
})
67+
3868
})

logger/no_op_logger.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,6 @@ import (
66

77
func NoOpLogger() (*Logger, *test.Hook) {
88
log, hook := test.NewNullLogger()
9-
return NewLogrusLogger("null_logger", map[string]interface{}{}, log.WithField("context", "test")), hook
9+
logger, _ := NewLogrusLogger("null_logger", map[string]interface{}{}, log.WithField("context", "test"))
10+
return logger, hook
1011
}

0 commit comments

Comments
 (0)