1
0
Fork 0
mirror of https://github.com/arangodb/kube-arangodb.git synced 2024-12-14 11:57:37 +00:00

[DebugPackage] Collect logs from pods (#1175)

This commit is contained in:
Adam Janikowski 2022-11-07 18:46:57 +01:00 committed by GitHub
parent 7420e13b5c
commit 9235014796
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 165 additions and 0 deletions

View file

@ -16,6 +16,7 @@
- (Debug) Allow to send package to stdout
- (Improvement) ArangoDB image validation (=>3.10) for ARM64 architecture
- (Improvement) Use inspector for ArangoMember
- (DebugPackage) Collect logs from pods
## [1.2.20](https://github.com/arangodb/kube-arangodb/tree/1.2.20) (2022-10-25)
- (Feature) Add action progress

View file

@ -26,6 +26,7 @@ func Register(cmd *cobra.Command) {
f := cmd.Flags()
f.StringVar(&input.Namespace, "namespace", "default", "Kubernetes namespace")
f.BoolVar(&input.HideSensitiveData, "hide-sensitive-data", true, "Hide sensitive data")
f.BoolVar(&input.PodLogs, "pod-logs", true, "Collect pod logs")
}
var input Input
@ -37,4 +38,5 @@ func GetInput() Input {
type Input struct {
Namespace string
HideSensitiveData bool
PodLogs bool
}

View file

@ -0,0 +1,21 @@
//
// DISCLAIMER
//
// Copyright 2016-2022 ArangoDB GmbH, Cologne, Germany
//
// Licensed 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.
//
// Copyright holder is ArangoDB GmbH, Cologne, Germany
//
package kubernetes

View file

@ -22,6 +22,8 @@ package kubernetes
import (
"context"
"fmt"
"io/ioutil"
"github.com/rs/zerolog"
core "k8s.io/api/core/v1"
@ -65,6 +67,12 @@ func pods(logger zerolog.Logger, files chan<- shared.File) error {
}
}
podsList := make([]*core.Pod, 0, len(pods))
for _, p := range pods {
podsList = append(podsList, p)
}
files <- shared.NewJSONFile("kubernetes/pods.json", func() (interface{}, error) {
q := make([]*core.Pod, 0, len(pods))
@ -75,5 +83,82 @@ func pods(logger zerolog.Logger, files chan<- shared.File) error {
return q, nil
})
if cli.GetInput().PodLogs {
if err := podsLogs(k, files, podsList...); err != nil {
logger.Err(err).Msgf("Error while collecting pod logs")
}
}
return nil
}
func podsLogs(client kclient.Client, files chan<- shared.File, pods ...*core.Pod) error {
errs := make([]error, len(pods))
for id := range pods {
errs[id] = podLogs(client, files, pods[id])
}
return errors.Errors(errs...)
}
func podLogs(client kclient.Client, files chan<- shared.File, pod *core.Pod) error {
errs := make([]error, 0, len(pod.Status.ContainerStatuses)+len(pod.Status.InitContainerStatuses)+len(pod.Status.EphemeralContainerStatuses))
if s := pod.Status.ContainerStatuses; len(s) > 0 {
for id := range s {
if s[id].State.Waiting != nil {
continue
}
errs = append(errs, errors.Wrapf(podContainerLogs(client, files, pod, s[id].Name), "Unable to read %s Container logs", s[id].Name))
}
}
if s := pod.Status.EphemeralContainerStatuses; len(s) > 0 {
for id := range s {
if s[id].State.Waiting != nil {
continue
}
errs = append(errs, errors.Wrapf(podContainerLogs(client, files, pod, s[id].Name), "Unable to read %s EphemeralContainer logs", s[id].Name))
}
}
if s := pod.Status.InitContainerStatuses; len(s) > 0 {
for id := range s {
if s[id].State.Waiting != nil {
continue
}
errs = append(errs, errors.Wrapf(podContainerLogs(client, files, pod, s[id].Name), "Unable to read %s InitContainer logs", s[id].Name))
}
}
return errors.Errors(errs...)
}
func podContainerLogs(client kclient.Client, files chan<- shared.File, pod *core.Pod, container string) error {
res := client.Kubernetes().CoreV1().Pods(pod.GetNamespace()).GetLogs(pod.GetName(), &core.PodLogOptions{
Container: container,
Timestamps: true,
})
q, err := res.Stream(context.Background())
if err != nil {
return err
}
defer q.Close()
d, err := ioutil.ReadAll(q)
if err != nil {
return err
}
files <- shared.NewFile(fmt.Sprintf("kubernetes/pods/%s/logs/container/%s", pod.GetName(), container), func() ([]byte, error) {
return d, nil
})
return nil
}

View file

@ -0,0 +1,56 @@
//
// DISCLAIMER
//
// Copyright 2016-2022 ArangoDB GmbH, Cologne, Germany
//
// Licensed 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.
//
// Copyright holder is ArangoDB GmbH, Cologne, Germany
//
package errors
import (
"fmt"
"strings"
)
type Array []error
func (a Array) Error() string {
q := make([]string, len(a))
for id := range a {
q[id] = a.Error()
}
return fmt.Sprintf("Received %d errors: %s", len(q), strings.Join(q, ", "))
}
func Errors(errs ...error) error {
f := make(Array, 0, len(errs))
for _, err := range errs {
if err == nil {
continue
}
f = append(f, err)
}
if len(f) == 0 {
return nil
}
return f
}