mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-25 04:33:26 +00:00
Merge pull request #89819 from pohly/enhance-podlogs-master
tests: enhance podlogs
This commit is contained in:
commit
7c53c1eb91
@ -76,7 +76,11 @@ func CopyAllLogs(ctx context.Context, cs clientset.Interface, ns string, to LogO
|
|||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
var m sync.Mutex
|
var m sync.Mutex
|
||||||
logging := map[string]bool{}
|
// Key is pod/container name, true if currently logging it.
|
||||||
|
active := map[string]bool{}
|
||||||
|
// Key is pod/container/container-id, true if we have ever started to capture its output.
|
||||||
|
started := map[string]bool{}
|
||||||
|
|
||||||
check := func() {
|
check := func() {
|
||||||
m.Lock()
|
m.Lock()
|
||||||
defer m.Unlock()
|
defer m.Unlock()
|
||||||
@ -91,10 +95,17 @@ func CopyAllLogs(ctx context.Context, cs clientset.Interface, ns string, to LogO
|
|||||||
|
|
||||||
for _, pod := range pods.Items {
|
for _, pod := range pods.Items {
|
||||||
for i, c := range pod.Spec.Containers {
|
for i, c := range pod.Spec.Containers {
|
||||||
|
// sanity check, array should have entry for each container
|
||||||
|
if len(pod.Status.ContainerStatuses) <= i {
|
||||||
|
continue
|
||||||
|
}
|
||||||
name := pod.ObjectMeta.Name + "/" + c.Name
|
name := pod.ObjectMeta.Name + "/" + c.Name
|
||||||
if logging[name] ||
|
id := name + "/" + pod.Status.ContainerStatuses[i].ContainerID
|
||||||
// sanity check, array should have entry for each container
|
if active[name] ||
|
||||||
len(pod.Status.ContainerStatuses) <= i ||
|
// If we have worked on a container before and it has now terminated, then
|
||||||
|
// there cannot be any new output and we can ignore it.
|
||||||
|
(pod.Status.ContainerStatuses[i].State.Terminated != nil &&
|
||||||
|
started[id]) ||
|
||||||
// Don't attempt to get logs for a container unless it is running or has terminated.
|
// Don't attempt to get logs for a container unless it is running or has terminated.
|
||||||
// Trying to get a log would just end up with an error that we would have to suppress.
|
// Trying to get a log would just end up with an error that we would have to suppress.
|
||||||
(pod.Status.ContainerStatuses[i].State.Running == nil &&
|
(pod.Status.ContainerStatuses[i].State.Running == nil &&
|
||||||
@ -117,7 +128,7 @@ func CopyAllLogs(ctx context.Context, cs clientset.Interface, ns string, to LogO
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Determine where we write. If this fails, we intentionally return without clearing
|
// Determine where we write. If this fails, we intentionally return without clearing
|
||||||
// the logging[name] flag, which prevents trying over and over again to
|
// the active[name] flag, which prevents trying over and over again to
|
||||||
// create the output file.
|
// create the output file.
|
||||||
var out io.Writer
|
var out io.Writer
|
||||||
var closer io.Closer
|
var closer io.Closer
|
||||||
@ -155,14 +166,22 @@ func CopyAllLogs(ctx context.Context, cs clientset.Interface, ns string, to LogO
|
|||||||
if closer != nil {
|
if closer != nil {
|
||||||
defer closer.Close()
|
defer closer.Close()
|
||||||
}
|
}
|
||||||
|
first := true
|
||||||
defer func() {
|
defer func() {
|
||||||
m.Lock()
|
m.Lock()
|
||||||
logging[name] = false
|
// If we never printed anything, then also skip the final message.
|
||||||
|
if !first {
|
||||||
|
if prefix != "" {
|
||||||
|
fmt.Fprintf(out, "%s==== end of pod log ====\n", prefix)
|
||||||
|
} else {
|
||||||
|
fmt.Fprintf(out, "==== end of pod log for container %s ====\n", name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
active[name] = false
|
||||||
m.Unlock()
|
m.Unlock()
|
||||||
readCloser.Close()
|
readCloser.Close()
|
||||||
}()
|
}()
|
||||||
scanner := bufio.NewScanner(readCloser)
|
scanner := bufio.NewScanner(readCloser)
|
||||||
first := true
|
|
||||||
for scanner.Scan() {
|
for scanner.Scan() {
|
||||||
line := scanner.Text()
|
line := scanner.Text()
|
||||||
// Filter out the expected "end of stream" error message,
|
// Filter out the expected "end of stream" error message,
|
||||||
@ -170,21 +189,25 @@ func CopyAllLogs(ctx context.Context, cs clientset.Interface, ns string, to LogO
|
|||||||
// Same for attempts to read logs from a container that
|
// Same for attempts to read logs from a container that
|
||||||
// isn't ready (yet?!).
|
// isn't ready (yet?!).
|
||||||
if !strings.HasPrefix(line, "rpc error: code = Unknown desc = Error: No such container:") &&
|
if !strings.HasPrefix(line, "rpc error: code = Unknown desc = Error: No such container:") &&
|
||||||
|
!strings.HasPrefix(line, "unable to retrieve container logs for ") &&
|
||||||
!strings.HasPrefix(line, "Unable to retrieve container logs for ") {
|
!strings.HasPrefix(line, "Unable to retrieve container logs for ") {
|
||||||
if first {
|
if first {
|
||||||
if to.LogWriter == nil {
|
// Because the same log might be written to multiple times
|
||||||
// Because the same log might be written to multiple times
|
// in different test instances, log an extra line to separate them.
|
||||||
// in different test instances, log an extra line to separate them.
|
// Also provides some useful extra information.
|
||||||
// Also provides some useful extra information.
|
if prefix == "" {
|
||||||
fmt.Fprintf(out, "==== start of log for container %s ====\n", name)
|
fmt.Fprintf(out, "==== start of pod log for container %s ====\n", name)
|
||||||
|
} else {
|
||||||
|
fmt.Fprintf(out, "%s==== start of pod log ====\n", prefix)
|
||||||
}
|
}
|
||||||
first = false
|
first = false
|
||||||
}
|
}
|
||||||
fmt.Fprintf(out, "%s%s\n", prefix, scanner.Text())
|
fmt.Fprintf(out, "%s%s\n", prefix, line)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
logging[name] = true
|
active[name] = true
|
||||||
|
started[id] = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user