Commit c9759ae3 authored by Kubernetes Submit Queue's avatar Kubernetes Submit Queue Committed by GitHub

Merge pull request #52289 from crassirostris/sd-logging-trim-long-lines

Automatic merge from submit-queue (batch tested with PRs 52316, 52289, 52375) [fluentd-gcp addon] Trim too long log entries due to Stackdriver limitations Stackdriver doesn't support log entries bigger than 100KB, so by default fluentd plugin just drops such entries. To avoid that and increase the visibility of this problem it's suggested to trim long lines instead. /cc @igorpeshansky ```release-note [fluentd-gcp addon] Fluentd will trim lines exceeding 100KB instead of dropping them. ```
parents a789fc77 d8525f8b
...@@ -345,6 +345,18 @@ data: ...@@ -345,6 +345,18 @@ data:
</metric> </metric>
</filter> </filter>
# TODO(instrumentation): Reconsider this workaround later.
# Trim the entries which exceed slightly less than 100KB, to avoid
# dropping them. It is a necessity, because Stackdriver only supports
# entries that are up to 100KB in size.
<filter kubernetes.**>
@type record_transformer
enable_ruby true
<record>
log ${record['log'].length > 100000 ? "[Trimmed]#{record['log'][0..100000]}..." : record['log']}
</record>
</filter>
# We use 2 output stanzas - one to handle the container logs and one to handle # We use 2 output stanzas - one to handle the container logs and one to handle
# the node daemon logs, the latter of which explicitly sends its logs to the # the node daemon logs, the latter of which explicitly sends its logs to the
# compute.googleapis.com service rather than container.googleapis.com to keep # compute.googleapis.com service rather than container.googleapis.com to keep
...@@ -396,7 +408,7 @@ data: ...@@ -396,7 +408,7 @@ data:
num_threads 2 num_threads 2
</match> </match>
metadata: metadata:
name: fluentd-gcp-config-v1.1.2 name: fluentd-gcp-config-v1.2.0
namespace: kube-system namespace: kube-system
labels: labels:
addonmanager.kubernetes.io/mode: Reconcile addonmanager.kubernetes.io/mode: Reconcile
...@@ -117,7 +117,7 @@ spec: ...@@ -117,7 +117,7 @@ spec:
path: /usr/lib64 path: /usr/lib64
- name: config-volume - name: config-volume
configMap: configMap:
name: fluentd-gcp-config-v1.1.2 name: fluentd-gcp-config-v1.2.0
- name: ssl-certs - name: ssl-certs
hostPath: hostPath:
path: /etc/ssl/certs path: /etc/ssl/certs
...@@ -18,6 +18,7 @@ package stackdriver ...@@ -18,6 +18,7 @@ package stackdriver
import ( import (
"fmt" "fmt"
"strings"
"time" "time"
"k8s.io/apimachinery/pkg/util/wait" "k8s.io/apimachinery/pkg/util/wait"
...@@ -107,6 +108,39 @@ var _ = instrumentation.SIGDescribe("Cluster level logging implemented by Stackd ...@@ -107,6 +108,39 @@ var _ = instrumentation.SIGDescribe("Cluster level logging implemented by Stackd
err = utils.WaitForLogs(c, ingestionInterval, ingestionTimeout) err = utils.WaitForLogs(c, ingestionInterval, ingestionTimeout)
framework.ExpectNoError(err) framework.ExpectNoError(err)
}) })
ginkgo.By("Checking that too long lines are trimmed", func() {
originalLength := 100001
cmd := []string{
"/bin/sh",
"-c",
fmt.Sprintf("while :; do printf '%%*s' %d | tr ' ' 'A'; echo; sleep 1; done", originalLength),
}
trimPrefix := "[Trimmed]"
pod, err := utils.StartAndReturnSelf(utils.NewExecLoggingPod("synthlogger-4", cmd), f)
framework.ExpectNoError(err, "Failed to start a pod")
ginkgo.By("Waiting for logs to ingest")
c := utils.NewLogChecker(p, func(_ string, logEntries []utils.LogEntry) (bool, error) {
if len(logEntries) == 0 {
return false, nil
}
log := logEntries[0]
if log.JSONPayload != nil {
return false, fmt.Errorf("got json log entry %v, wanted plain text", log.JSONPayload)
}
if len(log.TextPayload) == originalLength {
return false, fmt.Errorf("got non-trimmed entry of length %d", len(log.TextPayload))
}
if !strings.HasPrefix(log.TextPayload, trimPrefix) {
return false, fmt.Errorf("got message without prefix '%s': %s", trimPrefix, log.TextPayload)
}
return true, nil
}, utils.JustTimeout, pod.Name())
err = utils.WaitForLogs(c, ingestionInterval, ingestionTimeout)
framework.ExpectNoError(err)
})
}) })
}) })
......
...@@ -134,27 +134,38 @@ func (p *loadLoggingPod) ExpectedLineCount() int { ...@@ -134,27 +134,38 @@ func (p *loadLoggingPod) ExpectedLineCount() int {
return p.expectedLinesCount return p.expectedLinesCount
} }
var _ LoggingPod = &repeatingLoggingPod{} // NewRepeatingLoggingPod returns a logging pod that each second prints
// line value to its stdout.
func NewRepeatingLoggingPod(podName string, line string) LoggingPod {
cmd := []string{
"/bin/sh",
"-c",
fmt.Sprintf("while :; do echo '%s'; sleep 1; done", line),
}
return NewExecLoggingPod(podName, cmd)
}
var _ LoggingPod = &execLoggingPod{}
type repeatingLoggingPod struct { type execLoggingPod struct {
name string name string
line string cmd []string
} }
// NewRepeatingLoggingPod returns a logging pod that each second prints // NewExecLoggingPod returns a logging pod that produces logs through
// line value to its stdout. // executing a command, passed in cmd.
func NewRepeatingLoggingPod(podName string, line string) LoggingPod { func NewExecLoggingPod(podName string, cmd []string) LoggingPod {
return &repeatingLoggingPod{ return &execLoggingPod{
name: podName, name: podName,
line: line, cmd: cmd,
} }
} }
func (p *repeatingLoggingPod) Name() string { func (p *execLoggingPod) Name() string {
return p.name return p.name
} }
func (p *repeatingLoggingPod) Start(f *framework.Framework) error { func (p *execLoggingPod) Start(f *framework.Framework) error {
framework.Logf("Starting repeating logging pod %s", p.name) framework.Logf("Starting repeating logging pod %s", p.name)
f.PodClient().Create(&api_v1.Pod{ f.PodClient().Create(&api_v1.Pod{
ObjectMeta: meta_v1.ObjectMeta{ ObjectMeta: meta_v1.ObjectMeta{
...@@ -163,13 +174,9 @@ func (p *repeatingLoggingPod) Start(f *framework.Framework) error { ...@@ -163,13 +174,9 @@ func (p *repeatingLoggingPod) Start(f *framework.Framework) error {
Spec: api_v1.PodSpec{ Spec: api_v1.PodSpec{
Containers: []api_v1.Container{ Containers: []api_v1.Container{
{ {
Name: loggingContainerName, Name: loggingContainerName,
Image: "busybox", Image: "busybox",
Command: []string{ Command: p.cmd,
"/bin/sh",
"-c",
fmt.Sprintf("while :; do echo '%s'; sleep 1; done", p.line),
},
Resources: api_v1.ResourceRequirements{ Resources: api_v1.ResourceRequirements{
Requests: api_v1.ResourceList{ Requests: api_v1.ResourceList{
api_v1.ResourceCPU: *resource.NewMilliQuantity( api_v1.ResourceCPU: *resource.NewMilliQuantity(
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment