Skip to content

Commit 9fd42c6

Browse files
authored
Make whitespace trimming in log messages optional (#506)
The Log Cache Syslog server trims leading and trailing whitespace in the messages. The log messages should be not changed. This change: - adds config parameter to define if the whitespace in the log messages should be trimmed or not - trims or leaves the log message untouched based on the config parameter The default behavior is to trim the log messages, so that it is compatible with the behavior up until now.
1 parent 79a9ee5 commit 9fd42c6

File tree

6 files changed

+87
-16
lines changed

6 files changed

+87
-16
lines changed

jobs/log-cache-syslog-server/spec

+3
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ properties:
3535
syslog_idle_timeout:
3636
description: "Timeout for the Syslog Server connection"
3737
default: "2m"
38+
syslog_trim_message_whitespace:
39+
description: "Defines if the leading and trailing whitespace in the Syslog log messages should be trimmed"
40+
default: true
3841

3942
syslog_client_ca_cert:
4043
description: The CA certificate for key/cert verification.

jobs/log-cache-syslog-server/templates/bpm.yml.erb

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ processes:
1616
env:
1717
SYSLOG_PORT: "<%= p('syslog_port') %>"
1818
SYSLOG_IDLE_TIMEOUT: "<%= p('syslog_idle_timeout') %>"
19+
SYSLOG_TRIM_MESSAGE_WHITESPACE: "<%= p('syslog_trim_message_whitespace') %>"
1920

2021
SYSLOG_TLS_CERT_PATH: "<%= "#{certDir}/syslog.crt" %>"
2122
SYSLOG_TLS_KEY_PATH: "<%= "#{certDir}/syslog.key" %>"

src/cmd/syslog-server/config.go

+5-3
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,9 @@ type Config struct {
1818
SyslogTLSCertPath string `env:"SYSLOG_TLS_CERT_PATH, report"`
1919
SyslogTLSKeyPath string `env:"SYSLOG_TLS_KEY_PATH, report"`
2020

21-
SyslogIdleTimeout time.Duration `env:"SYSLOG_IDLE_TIMEOUT, report"`
22-
SyslogMaxMessageLength int `env:"SYSLOG_MAX_MESSAGE_LENGTH, report"`
21+
SyslogIdleTimeout time.Duration `env:"SYSLOG_IDLE_TIMEOUT, report"`
22+
SyslogMaxMessageLength int `env:"SYSLOG_MAX_MESSAGE_LENGTH, report"`
23+
SyslogTrimMessageWhitespace bool `env:"SYSLOG_TRIM_MESSAGE_WHITESPACE, report"`
2324

2425
SyslogClientTrustedCAFile string `env:"SYSLOG_CLIENT_TRUSTED_CA_FILE, report"`
2526

@@ -36,7 +37,8 @@ func LoadConfig() (*Config, error) {
3637
MetricsServer: config.MetricsServer{
3738
Port: 6061,
3839
},
39-
SyslogMaxMessageLength: 65 * 1024, // Diego should never send logs bigger than 64Kib
40+
SyslogMaxMessageLength: 65 * 1024, // Diego should never send logs bigger than 64Kib
41+
SyslogTrimMessageWhitespace: true,
4042
}
4143

4244
if err := envstruct.Load(&c); err != nil {

src/cmd/syslog-server/main.go

+1
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ func main() {
7575
syslog.WithServerPort(cfg.SyslogPort),
7676
syslog.WithIdleTimeout(cfg.SyslogIdleTimeout),
7777
syslog.WithServerMaxMessageLength(cfg.SyslogMaxMessageLength),
78+
syslog.WithServerTrimMessageWhitespace(cfg.SyslogTrimMessageWhitespace),
7879
}
7980
if cfg.SyslogTLSCertPath != "" || cfg.SyslogTLSKeyPath != "" {
8081
serverOptions = append(serverOptions, syslog.WithServerTLS(cfg.SyslogTLSCertPath, cfg.SyslogTLSKeyPath))

src/internal/syslog/server.go

+27-13
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,15 @@ import (
2525

2626
type Server struct {
2727
sync.Mutex
28-
port int
29-
l net.Listener
30-
envelopes chan *loggregator_v2.Envelope
31-
syslogClientCA string
32-
syslogCert string
33-
syslogKey string
34-
idleTimeout time.Duration
35-
maxMessageLength int
28+
port int
29+
l net.Listener
30+
envelopes chan *loggregator_v2.Envelope
31+
syslogClientCA string
32+
syslogCert string
33+
syslogKey string
34+
idleTimeout time.Duration
35+
maxMessageLength int
36+
trimMessageWhitespace bool
3637

3738
ingress metrics.Counter
3839
invalidIngress metrics.Counter
@@ -52,10 +53,11 @@ func NewServer(
5253
opts ...ServerOption,
5354
) *Server {
5455
s := &Server{
55-
loggr: loggr,
56-
envelopes: make(chan *loggregator_v2.Envelope, 100),
57-
idleTimeout: 2 * time.Minute,
58-
maxMessageLength: 65 * 1024, // Diego should never send logs bigger than 64Kib
56+
loggr: loggr,
57+
envelopes: make(chan *loggregator_v2.Envelope, 100),
58+
idleTimeout: 2 * time.Minute,
59+
maxMessageLength: 65 * 1024, // Diego should never send logs bigger than 64Kib
60+
trimMessageWhitespace: true,
5961
}
6062

6163
for _, o := range opts {
@@ -86,6 +88,12 @@ func WithServerMaxMessageLength(l int) ServerOption {
8688
}
8789
}
8890

91+
func WithServerTrimMessageWhitespace(t bool) ServerOption {
92+
return func(s *Server) {
93+
s.trimMessageWhitespace = t
94+
}
95+
}
96+
8997
func WithServerTLS(cert, key string) ServerOption {
9098
return func(s *Server) {
9199
s.syslogCert = cert
@@ -238,9 +246,15 @@ func (s *Server) convertToEnvelope(msg *rfc5424.SyslogMessage) (*loggregator_v2.
238246
}
239247

240248
func (s *Server) convertMessage(env *loggregator_v2.Envelope, msg *rfc5424.SyslogMessage) *loggregator_v2.Envelope {
249+
var payload string
250+
if s.trimMessageWhitespace {
251+
payload = strings.TrimSpace(*msg.Message)
252+
} else {
253+
payload = strings.TrimSuffix(*msg.Message, "\n")
254+
}
241255
env.Message = &loggregator_v2.Envelope_Log{
242256
Log: &loggregator_v2.Log{
243-
Payload: []byte(strings.TrimSpace(*msg.Message)),
257+
Payload: []byte(payload),
244258
Type: s.typeFromPriority(int(*msg.Priority)),
245259
},
246260
}

src/internal/syslog/server_test.go

+50
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ func newTlsServerTestSetup(opts ...syslog.ServerOption) (*syslog.Server, *testhe
3131
syslog.WithSyslogClientCA(testing.LogCacheTestCerts.CA()),
3232
syslog.WithServerPort(0),
3333
syslog.WithIdleTimeout(100 * time.Millisecond),
34+
syslog.WithServerTrimMessageWhitespace(true),
3435
}
3536
options = append(options, opts...)
3637

@@ -151,6 +152,55 @@ var _ = Describe("Syslog", func() {
151152
))
152153
})
153154

155+
It("trims whitespace in log messages when configured to do so", func() {
156+
tests := []struct {
157+
trimWhitespace bool
158+
expectedMsg string
159+
}{
160+
{expectedMsg: "just a test with with whitespace"},
161+
{trimWhitespace: true, expectedMsg: "just a test with with whitespace"},
162+
{trimWhitespace: false, expectedMsg: " just a test with with whitespace "},
163+
}
164+
165+
for i, tc := range tests {
166+
var server *syslog.Server
167+
if i == 0 {
168+
server, _, _ = newTlsServerTestSetup()
169+
} else {
170+
server, _, _ = newTlsServerTestSetup(syslog.WithServerTrimMessageWhitespace(tc.trimWhitespace))
171+
}
172+
defer server.Stop()
173+
174+
tlsConfig := buildClientTLSConfig(tls.VersionTLS12, tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384)
175+
conn, err := tlsClientConnection(server.Addr(), tlsConfig)
176+
Expect(err).ToNot(HaveOccurred())
177+
178+
const messageWithWhitespace = `174 <14>1 1970-01-01T00:00:00.012345+00:00 test-hostname test-app-id [APP/2] - [tags@47450 key="value" source_type="actual-source-type"] just a test with with whitespace ` + "\n"
179+
_, err = fmt.Fprint(conn, messageWithWhitespace)
180+
Expect(err).ToNot(HaveOccurred())
181+
182+
br := loggregator_v2.EgressBatchRequest{}
183+
ctx := context.Background()
184+
Expect(server.Stream(ctx, &br)()).Should(ContainElement(
185+
&loggregator_v2.Envelope{
186+
Tags: map[string]string{
187+
"source_type": "actual-source-type",
188+
"key": "value",
189+
},
190+
InstanceId: "2",
191+
Timestamp: 12345000,
192+
SourceId: "test-app-id",
193+
Message: &loggregator_v2.Envelope_Log{
194+
Log: &loggregator_v2.Log{
195+
Payload: []byte(tc.expectedMsg),
196+
Type: loggregator_v2.Log_OUT,
197+
},
198+
},
199+
},
200+
))
201+
}
202+
})
203+
154204
It("max syslog length is configurable", func() {
155205
server, spyMetrics, _ := newTlsServerTestSetup(syslog.WithServerMaxMessageLength(128))
156206
defer server.Stop()

0 commit comments

Comments
 (0)