This is an automated email from the ASF dual-hosted git repository.
tsato 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 8f66a6fbd feat(cli): Add tail flag to the log command
8f66a6fbd is described below
commit 8f66a6fbd6e5de0cc81d6a4710955537d67e382e
Author: Nicolas Filotto <[email protected]>
AuthorDate: Tue Aug 30 17:24:10 2022 +0200
feat(cli): Add tail flag to the log command
---
e2e/namespace/install/cli/log_test.go | 11 +++++++++--
pkg/cmd/debug.go | 2 +-
pkg/cmd/log.go | 9 ++++++++-
pkg/cmd/run.go | 2 +-
pkg/util/kubernetes/log/annotation_scraper.go | 6 ++++--
pkg/util/kubernetes/log/pod_scraper.go | 5 ++++-
pkg/util/kubernetes/log/util.go | 8 ++++----
7 files changed, 31 insertions(+), 12 deletions(-)
diff --git a/e2e/namespace/install/cli/log_test.go
b/e2e/namespace/install/cli/log_test.go
index 5b696ac68..967128ca9 100644
--- a/e2e/namespace/install/cli/log_test.go
+++ b/e2e/namespace/install/cli/log_test.go
@@ -42,12 +42,19 @@ func TestKamelCLILog(t *testing.T) {
Expect(KamelRunWithID(operatorID, ns,
"../files/yaml.yaml").Execute()).To(Succeed())
Eventually(IntegrationPodPhase(ns, "yaml"),
TestTimeoutLong).Should(Equal(corev1.PodRunning))
// first line of the integration logs
- logs := strings.Split(IntegrationLogs(ns, "yaml")(),
"\n")[0]
+ firstLine := strings.Split(IntegrationLogs(ns,
"yaml")(), "\n")[0]
podName := IntegrationPod(ns, "yaml")().Name
logsCLI := GetOutputStringAsync(Kamel("log", "yaml",
"-n", ns))
Eventually(logsCLI).Should(ContainSubstring("Monitoring
pod " + podName))
- Eventually(logsCLI).Should(ContainSubstring(logs))
+ Eventually(logsCLI).Should(ContainSubstring(firstLine))
+
+ logs := strings.Split(IntegrationLogs(ns, "yaml")(),
"\n")
+ lastLine := logs[len(logs)-1]
+
+ logsCLI = GetOutputStringAsync(Kamel("log", "yaml",
"-n", ns, "--tail", "5"))
+ Eventually(logsCLI).Should(ContainSubstring("Monitoring
pod " + podName))
+ Eventually(logsCLI).Should(ContainSubstring(lastLine))
})
})
}
diff --git a/pkg/cmd/debug.go b/pkg/cmd/debug.go
index 2913bacae..7d5a1de8f 100644
--- a/pkg/cmd/debug.go
+++ b/pkg/cmd/debug.go
@@ -123,7 +123,7 @@ func (o *debugCmdOptions) run(cmd *cobra.Command, args
[]string) error {
selector :=
fmt.Sprintf("camel.apache.org/debug=true,camel.apache.org/integration=%s", name)
go func() {
- err = k8slog.PrintUsingSelector(o.Context, cmd, cmdClient,
o.Namespace, "integration", selector, cmd.OutOrStdout())
+ err = k8slog.PrintUsingSelector(o.Context, cmd, cmdClient,
o.Namespace, "integration", selector, nil, cmd.OutOrStdout())
if err != nil {
fmt.Fprintln(cmd.ErrOrStderr(), err.Error())
}
diff --git a/pkg/cmd/log.go b/pkg/cmd/log.go
index 9a9efcbf9..6faa19b35 100644
--- a/pkg/cmd/log.go
+++ b/pkg/cmd/log.go
@@ -46,6 +46,8 @@ func newCmdLog(rootCmdOptions *RootCmdOptions)
(*cobra.Command, *logCmdOptions)
RunE: options.run,
}
+ cmd.Flags().Int64("tail", -1, "The number of lines from the end of the
logs to show. Defaults to -1 to show all the lines.")
+
// completion support
configureKnownCompletions(&cmd)
@@ -54,6 +56,7 @@ func newCmdLog(rootCmdOptions *RootCmdOptions)
(*cobra.Command, *logCmdOptions)
type logCmdOptions struct {
*RootCmdOptions
+ Tail int64 `mapstructure:"tail"`
}
func (o *logCmdOptions) validate(_ *cobra.Command, args []string) error {
@@ -129,7 +132,11 @@ func (o *logCmdOptions) run(cmd *cobra.Command, args
[]string) error {
// Found the running integration so step over to
scraping its pod log
//
fmt.Fprintln(cmd.OutOrStdout(), "Integration
'"+integrationID+"' is now running. Showing log ...")
- if err := k8slog.Print(o.Context, cmd, c, &integration,
cmd.OutOrStdout()); err != nil {
+ var tailLines *int64
+ if o.Tail > 0 {
+ tailLines = &o.Tail
+ }
+ if err := k8slog.Print(o.Context, cmd, c, &integration,
tailLines, cmd.OutOrStdout()); err != nil {
return false, err
}
diff --git a/pkg/cmd/run.go b/pkg/cmd/run.go
index b1e23aa6e..ac4174ff4 100644
--- a/pkg/cmd/run.go
+++ b/pkg/cmd/run.go
@@ -378,7 +378,7 @@ func (o *runCmdOptions) run(cmd *cobra.Command, args
[]string) error {
}
}
if o.Logs || o.Dev {
- err = k8slog.Print(o.Context, cmd, c, integration,
cmd.OutOrStdout())
+ err = k8slog.Print(o.Context, cmd, c, integration, nil,
cmd.OutOrStdout())
if err != nil {
return err
}
diff --git a/pkg/util/kubernetes/log/annotation_scraper.go
b/pkg/util/kubernetes/log/annotation_scraper.go
index c3cde929d..4c687ad60 100644
--- a/pkg/util/kubernetes/log/annotation_scraper.go
+++ b/pkg/util/kubernetes/log/annotation_scraper.go
@@ -44,16 +44,18 @@ type SelectorScraper struct {
podScrapers sync.Map
counter uint64
L klog.Logger
+ tailLines *int64
}
// NewSelectorScraper creates a new SelectorScraper.
-func NewSelectorScraper(client kubernetes.Interface, namespace string,
defaultContainerName string, labelSelector string) *SelectorScraper {
+func NewSelectorScraper(client kubernetes.Interface, namespace string,
defaultContainerName string, labelSelector string, tailLines *int64)
*SelectorScraper {
return &SelectorScraper{
client: client,
namespace: namespace,
defaultContainerName: defaultContainerName,
labelSelector: labelSelector,
L:
klog.WithName("scraper").WithName("label").WithValues("selector",
labelSelector),
+ tailLines: tailLines,
}
}
@@ -130,7 +132,7 @@ func (s *SelectorScraper) synchronize(ctx context.Context,
out *bufio.Writer) er
}
func (s *SelectorScraper) addPodScraper(ctx context.Context, podName string,
out *bufio.Writer) {
- podScraper := NewPodScraper(s.client, s.namespace, podName,
s.defaultContainerName)
+ podScraper := NewPodScraper(s.client, s.namespace, podName,
s.defaultContainerName, s.tailLines)
podCtx, podCancel := context.WithCancel(ctx)
id := atomic.AddUint64(&s.counter, 1)
prefix := "[" + strconv.FormatUint(id, 10) + "] "
diff --git a/pkg/util/kubernetes/log/pod_scraper.go
b/pkg/util/kubernetes/log/pod_scraper.go
index 494e0501f..a9fb24a89 100644
--- a/pkg/util/kubernetes/log/pod_scraper.go
+++ b/pkg/util/kubernetes/log/pod_scraper.go
@@ -48,16 +48,18 @@ type PodScraper struct {
defaultContainerName string
client kubernetes.Interface
L klog.Logger
+ tailLines *int64
}
// NewPodScraper creates a new pod scraper.
-func NewPodScraper(c kubernetes.Interface, namespace string, podName string,
defaultContainerName string) *PodScraper {
+func NewPodScraper(c kubernetes.Interface, namespace string, podName string,
defaultContainerName string, tailLines *int64) *PodScraper {
return &PodScraper{
namespace: namespace,
podName: podName,
defaultContainerName: defaultContainerName,
client: c,
L:
klog.WithName("scraper").WithName("pod").WithValues("name", podName),
+ tailLines: tailLines,
}
}
@@ -83,6 +85,7 @@ func (s *PodScraper) doScrape(ctx context.Context, out
*bufio.Writer, clientClos
}
logOptions := corev1.PodLogOptions{
Follow: true,
+ TailLines: s.tailLines,
Container: containerName,
}
byteReader, err :=
s.client.CoreV1().Pods(s.namespace).GetLogs(s.podName, &logOptions).Stream(ctx)
diff --git a/pkg/util/kubernetes/log/util.go b/pkg/util/kubernetes/log/util.go
index 26bd2c158..8dbc08530 100644
--- a/pkg/util/kubernetes/log/util.go
+++ b/pkg/util/kubernetes/log/util.go
@@ -30,13 +30,13 @@ import (
)
// Print prints integrations logs to the stdout.
-func Print(ctx context.Context, cmd *cobra.Command, client
kubernetes.Interface, integration *v1.Integration, out io.Writer) error {
- return PrintUsingSelector(ctx, cmd, client, integration.Namespace,
integration.Name, v1.IntegrationLabel+"="+integration.Name, out)
+func Print(ctx context.Context, cmd *cobra.Command, client
kubernetes.Interface, integration *v1.Integration, tailLines *int64, out
io.Writer) error {
+ return PrintUsingSelector(ctx, cmd, client, integration.Namespace,
integration.Name, v1.IntegrationLabel+"="+integration.Name, tailLines, out)
}
// PrintUsingSelector prints pod logs using a selector.
-func PrintUsingSelector(ctx context.Context, cmd *cobra.Command, client
kubernetes.Interface, namespace, defaultContainerName, selector string, out
io.Writer) error {
- scraper := NewSelectorScraper(client, namespace, defaultContainerName,
selector)
+func PrintUsingSelector(ctx context.Context, cmd *cobra.Command, client
kubernetes.Interface, namespace, defaultContainerName, selector string,
tailLines *int64, out io.Writer) error {
+ scraper := NewSelectorScraper(client, namespace, defaultContainerName,
selector, tailLines)
reader := scraper.Start(ctx)
if _, err := io.Copy(out, ioutil.NopCloser(reader)); err != nil {