Change:
What happened: Running on a pod with two containers, of which one has restarted but the other hasn't results in a undesired behavior. I get an inconsistent outcome, sometimes just a report of , other times I get the other containers logs followed by the error. What you expected to happen: I expect to get to see the full response of all containers, even though one container without any --previous logs throwed an error. How to reproduce it (as minimally and precisely as possible): The output can look like this... Anything else we need to know?: The flag by itself ("If watching / following pod logs, allow for any errors that occur to be non-fatal") doesn't influence this, but a workaround is to use to be able to see the full output. Kubernetes version (use ): Cloud provider or hardware configuration: GKE OS (e.g: ): Ubuntu 20.04 Kernel (e.g. ): 5.4.0-58-generic
This issue is currently awaiting triage. If a SIG or subproject determines this is a relevant issue, they will accept it by applying the label and provide further guidance. The label can be by org members by writing in a comment. <detailsInstructions for interacting with me using PR comments are available . If you have questions or suggestions related to my behavior, please file an issue against the repository. </details
/sig cli
do you have an example yaml file to create these containers?
yikes I feared I'd be asked this question :) Well, I provided a minimal example in the original post.
Thank you very much. I'll take a look.
Hmm... I can replicate this issue with the example you provided. Very explanatory instructions! I'll investigate tomorrow.
I used the example to reproduce this issue. Created pod through above. The state of pod is Running. I guess the reason is that none of the containers in pod have Terminated state.Only when one of containers is Terminated. The param --previous will return the result normally.
looking at these lines... ...I discovered that adding the option significantly increases the frequency that the "bash" container's logs are printed (the numbers are how many times was printed out of 100 runs):
Can i work on this issue?
/assign
Go ahead I'd love for you too. Hopefully my notes help!

Discussion:
for objRef, request := range requests { out := o.addPrefixIfNeeded(objRef, o.Out) if err := o.ConsumeRequestFn(request, out); err != nil { <del> return err </del> <ins> if !o.IgnoreLogErrors { return err } fmt.Fprintf(o.Out, "error: %vn", err) </ins> } }

}, expectedErr: "Error from the ConsumeRequestFn", }, <ins> { name: "get logs from multiple requests and ignores the error if the container fails", opts: func(streams genericclioptions.IOStreams) *LogsOptions { mock := &logTestMock{ logsForObjectRequests: map[corev1.ObjectReference]restclient.ResponseWrapper{ { Kind:      "Pod", Name:      "some-pod-error-container", FieldPath: "spec.containers{some-container}", }: &responseWrapperMock{err: errors.New("error-container")}, { Kind:      "Pod", Name:      "some-pod-1", FieldPath: "spec.containers{some-container}", }: &responseWrapperMock{data: strings.NewReader("test log content from source 1n")}, { Kind:      "Pod", Name:      "some-pod-2", FieldPath: "spec.containers{some-container}", }: &responseWrapperMock{data: strings.NewReader("test log content from source 2n")}, }, } o := NewLogsOptions(streams, false) o.LogsForObject = mock.mockLogsForObject o.ConsumeRequestFn = mock.mockConsumeRequest o.IgnoreLogErrors = true return o }, expectedOutSubstrings: []string{ "error-containern", "test log content from source 1n", "test log content from source 2n", }, }, { name: "get logs from multiple requests and an container fails", opts: func(streams genericclioptions.IOStreams) *LogsOptions { mock := &logTestMock{ logsForObjectRequests: map[corev1.ObjectReference]restclient.ResponseWrapper{ { Kind:      "Pod", Name:      "some-pod-error-container", FieldPath: "spec.containers{some-container}", }: &responseWrapperMock{err: errors.New("error-container")}, { Kind:      "Pod", Name:      "some-pod", FieldPath: "spec.containers{some-container}", }: &responseWrapperMock{data: strings.NewReader("test log content from sourcen")}, }, } o := NewLogsOptions(streams, false) o.LogsForObject = mock.mockLogsForObject o.ConsumeRequestFn = mock.mockConsumeRequest return o }, expectedErr: "error-container", }, { name: "follow logs from multiple requests and ignores the error if the container fails", opts: func(streams genericclioptions.IOStreams) *LogsOptions { mock := &logTestMock{ logsForObjectRequests: map[corev1.ObjectReference]restclient.ResponseWrapper{ { Kind:      "Pod", Name:      "some-pod-error-container", FieldPath: "spec.containers{some-container}", }: &responseWrapperMock{err: errors.New("error-container")}, { Kind:      "Pod", Name:      "some-pod-1", FieldPath: "spec.containers{some-container}", }: &responseWrapperMock{data: strings.NewReader("test log content from source 1n")}, { Kind:      "Pod", Name:      "some-pod-2", FieldPath: "spec.containers{some-container}", }: &responseWrapperMock{data: strings.NewReader("test log content from source 2n")}, }, } o := NewLogsOptions(streams, false) o.LogsForObject = mock.mockLogsForObject o.ConsumeRequestFn = mock.mockConsumeRequest o.IgnoreLogErrors = true o.Follow = true return o }, expectedOutSubstrings: []string{ "error-containern", "test log content from source 1n", "test log content from source 2n", }, }, { name: "follow logs from multiple requests and an container fails", opts: func(streams genericclioptions.IOStreams) *LogsOptions { mock := &logTestMock{ logsForObjectRequests: map[corev1.ObjectReference]restclient.ResponseWrapper{ { Kind:      "Pod", Name:      "some-pod-error-container", FieldPath: "spec.containers{some-container}", }: &responseWrapperMock{err: errors.New("error-container")}, { Kind:      "Pod", Name:      "some-pod", FieldPath: "spec.containers{some-container}", }: &responseWrapperMock{data: strings.NewReader("test log content from sourcen")}, }, } o := NewLogsOptions(streams, false) o.LogsForObject = mock.mockLogsForObject o.ConsumeRequestFn = mock.mockConsumeRequest o.Follow = true return o }, expectedErr: "error-container", }, </ins> } for _, test := range tests { t.Run(test.name, func(t *testing.T) {