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:
parent
7420e13b5c
commit
9235014796
5 changed files with 165 additions and 0 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
21
pkg/debug_package/generators/kubernetes/pod_logs.go
Normal file
21
pkg/debug_package/generators/kubernetes/pod_logs.go
Normal 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
|
|
@ -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
|
||||
}
|
||||
|
|
56
pkg/util/errors/errors_array.go
Normal file
56
pkg/util/errors/errors_array.go
Normal 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
|
||||
}
|
Loading…
Reference in a new issue