This is an automated email from the ASF dual-hosted git repository.

orpiske pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-k.git


The following commit(s) were added to refs/heads/main by this push:
     new 475fc8d  Configure kubernetes to use structured log
475fc8d is described below

commit 475fc8d58a79e602724442f96bcc72f819380505
Author: Otavio Rodolfo Piske <[email protected]>
AuthorDate: Thu May 13 13:57:05 2021 +0200

    Configure kubernetes to use structured log
    
    Also include an integration test to ensure no unstructured logs leak
    from other parts of the code
---
 e2e/common/operator_metrics_test.go | 20 +++++++++----
 e2e/common/structured_logs_test.go  | 58 +++++++++++++++++++++++++++++++++++++
 e2e/support/test_support.go         | 12 ++++++--
 e2e/support/util/structured_log.go  | 26 +++++++++++++++--
 pkg/cmd/operator/operator.go        |  3 ++
 5 files changed, 110 insertions(+), 9 deletions(-)

diff --git a/e2e/common/operator_metrics_test.go 
b/e2e/common/operator_metrics_test.go
index fa10779..ebe6dc2 100644
--- a/e2e/common/operator_metrics_test.go
+++ b/e2e/common/operator_metrics_test.go
@@ -56,7 +56,7 @@ func TestMetrics(t *testing.T) {
                pod := OperatorPod(ns)()
                Expect(pod).NotTo(BeNil())
 
-               logs := StructuredLogs(ns, pod.Name, corev1.PodLogOptions{})
+               logs := StructuredLogs(ns, pod.Name, corev1.PodLogOptions{}, 
false)
                Expect(logs).NotTo(BeEmpty())
 
                response, err := TestClient().CoreV1().RESTClient().Get().
@@ -81,14 +81,19 @@ func TestMetrics(t *testing.T) {
                                AddStep(MatchFields(IgnoreExtras, Fields{
                                        "LoggerName":  
Equal("camel-k.controller.build"),
                                        "Message":     Equal("Build state 
transition"),
-                                       "Phase":       
Equal(string(v1.BuildPhasePending)),
+                                       "Phase":       MatchFields(IgnoreExtras,
+                                               Fields{
+                                                       "Name": 
Equal(string(v1.BuildPhasePending)),
+                                               }),
                                        "RequestName": Equal(build.Name),
                                }), LogEntryNoop).
                                AddStep(MatchFields(IgnoreExtras, Fields{
                                        "LoggerName":  
Equal("camel-k.controller.build"),
                                        "Message":     Equal("Reconciling 
Build"),
                                        "RequestName": Equal(build.Name),
-                               }), func(l *LogEntry) { ts1 = l.Timestamp.Time 
}).
+                               }), func(l *LogEntry) {
+                                       ts1 = l.Timestamp.Time
+                               }).
                                AddStep(MatchFields(IgnoreExtras, Fields{
                                        "LoggerName": Equal("camel-k.builder"),
                                        "Message":    HavePrefix("resolved base 
image:"),
@@ -97,7 +102,9 @@ func TestMetrics(t *testing.T) {
                                        "LoggerName":  
Equal("camel-k.controller.build"),
                                        "Message":     Equal("Reconciling 
Build"),
                                        "RequestName": Equal(build.Name),
-                               }), func(l *LogEntry) { ts2 = l.Timestamp.Time 
}).
+                               }), func(l *LogEntry) {
+                                       ts2 = l.Timestamp.Time
+                               }).
                                Walk()
                        Expect(err).To(BeNil())
                        Expect(ts1).NotTo(BeZero())
@@ -337,7 +344,10 @@ func TestMetrics(t *testing.T) {
                                AddStep(MatchFields(IgnoreExtras, Fields{
                                        "LoggerName":  
Equal("camel-k.controller.build"),
                                        "Message":     Equal("Build state 
transition"),
-                                       "Phase":       
Equal(string(v1.BuildPhasePending)),
+                                       "Phase":       MatchFields(IgnoreExtras,
+                                               Fields{
+                                                       "Name": 
Equal(string(v1.BuildPhasePending)),
+                                       }),
                                        "RequestName": Equal(build.Name),
                                }), func(l *LogEntry) { ts2 = l.Timestamp.Time 
}).
                                Walk()
diff --git a/e2e/common/structured_logs_test.go 
b/e2e/common/structured_logs_test.go
new file mode 100644
index 0000000..e80a820
--- /dev/null
+++ b/e2e/common/structured_logs_test.go
@@ -0,0 +1,58 @@
+// +build integration
+
+// To enable compilation of this file in Goland, go to "Settings -> Go -> 
Vendoring & Build Tags -> Custom Tags" and add "integration"
+
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You 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.
+*/
+
+package common
+
+import (
+       . "github.com/onsi/gomega"
+       "testing"
+
+       corev1 "k8s.io/api/core/v1"
+
+       . "github.com/apache/camel-k/e2e/support"
+       v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
+)
+
+func TestStructuredLogs(t *testing.T) {
+       WithNewTestNamespace(t, func(ns string) {
+               name := "java"
+               Expect(Kamel("install", "-n", ns).Execute()).To(Succeed())
+               Expect(Kamel("run", "-n", ns, "files/Java.java",
+                       "-t", "logging.format=json").Execute()).To(Succeed())
+               Eventually(IntegrationPodPhase(ns, name), 
TestTimeoutMedium).Should(Equal(corev1.PodRunning))
+               Eventually(IntegrationCondition(ns, name, 
v1.IntegrationConditionReady), 
TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+
+               pod := OperatorPod(ns)()
+               Expect(pod).NotTo(BeNil())
+
+               logs := StructuredLogs(ns, pod.Name, corev1.PodLogOptions{}, 
false)
+               Expect(logs).NotTo(BeEmpty())
+
+               it := Integration(ns, name)()
+               Expect(it).NotTo(BeNil())
+               build := Build(ns, it.Status.IntegrationKit.Name)()
+               Expect(build).NotTo(BeNil())
+
+               // Clean up
+               Expect(Kamel("delete", "--all", "-n", 
ns).Execute()).To(Succeed())
+       })
+}
+
diff --git a/e2e/support/test_support.go b/e2e/support/test_support.go
index cdc0998..ad57ef6 100644
--- a/e2e/support/test_support.go
+++ b/e2e/support/test_support.go
@@ -266,7 +266,7 @@ func Logs(ns, podName string, options corev1.PodLogOptions) 
func() string {
        }
 }
 
-func StructuredLogs(ns, podName string, options corev1.PodLogOptions) 
[]util.LogEntry {
+func StructuredLogs(ns, podName string, options corev1.PodLogOptions, 
ignoreParseErrors bool) []util.LogEntry {
        byteReader, err := TestClient().CoreV1().Pods(ns).GetLogs(podName, 
&options).Stream(TestContext)
        if err != nil {
                log.Error(err, "Error while reading container logs")
@@ -285,8 +285,16 @@ func StructuredLogs(ns, podName string, options 
corev1.PodLogOptions) []util.Log
                t := scanner.Text()
                err := json.Unmarshal([]byte(t), &entry)
                if err != nil {
-                       continue
+                       if ignoreParseErrors {
+                               continue
+                       } else {
+                               log.Errorf(err, "Unable to parse structured 
content: %s", t)
+                               return nil
+                       }
                }
+
+               log.Debug("Parsed: %s with phase '%s'\n", entry.Message, 
entry.Phase.Name)
+
                entries = append(entries, entry)
        }
 
diff --git a/e2e/support/util/structured_log.go 
b/e2e/support/util/structured_log.go
index ca26628..7b621dc 100644
--- a/e2e/support/util/structured_log.go
+++ b/e2e/support/util/structured_log.go
@@ -20,6 +20,7 @@ limitations under the License.
 package util
 
 import (
+       "encoding/json"
        "math"
        "strconv"
        "time"
@@ -43,6 +44,27 @@ func (t *Time) UnmarshalJSON(s []byte) (err error) {
        return nil
 }
 
+type Phase struct {
+       Name string
+}
+
+func (p *Phase) UnmarshalJSON(b []byte) error {
+       if b[0] != '"' {
+               var tmp int
+
+               json.Unmarshal(b, &tmp)
+               p.Name = strconv.Itoa(tmp)
+
+               return nil
+       }
+
+       if err := json.Unmarshal(b, &p.Name); err != nil {
+               return err
+       }
+
+       return nil
+}
+
 type LogEntry struct {
        // Zap
        Level      zapcore.Level `json:"level,omitempty"`
@@ -57,7 +79,7 @@ type LogEntry struct {
        // Camel K
        Namespace string `json:"ns,omitempty"`
        Name      string `json:"name,omitempty"`
-       Phase     string `json:"phase,omitempty"`
+       Phase     Phase `json:"phase,omitempty"`
        PhaseFrom string `json:"phase-from,omitempty"`
        PhaseTo   string `json:"phase-to,omitempty"`
-}
+}
\ No newline at end of file
diff --git a/pkg/cmd/operator/operator.go b/pkg/cmd/operator/operator.go
index 31b4da6..c64f503 100644
--- a/pkg/cmd/operator/operator.go
+++ b/pkg/cmd/operator/operator.go
@@ -21,6 +21,7 @@ import (
        "context"
        "flag"
        "fmt"
+       "k8s.io/klog/v2"
        "math/rand"
        "os"
        "runtime"
@@ -77,6 +78,8 @@ func Run(healthPort, monitoringPort int32) {
                o.Development = false
        }))
 
+       klog.SetLogger(log)
+
        printVersion()
 
        watchNamespace, err := getWatchNamespace()

Reply via email to