mirror of
https://github.com/containers/podman.git
synced 2025-06-26 04:46:57 +08:00
Merge pull request #8686 from Luap99/logs-stderr
podman logs honor stderr correctly
This commit is contained in:
@ -122,6 +122,7 @@ func logs(_ *cobra.Command, args []string) error {
|
||||
}
|
||||
logsOptions.Since = since
|
||||
}
|
||||
logsOptions.Writer = os.Stdout
|
||||
logsOptions.StdoutWriter = os.Stdout
|
||||
logsOptions.StderrWriter = os.Stderr
|
||||
return registry.ContainerEngine().ContainerLogs(registry.GetContext(), args, logsOptions.ContainerLogsOptions)
|
||||
}
|
||||
|
@ -210,3 +210,19 @@ func NewLogLine(line string) (*LogLine, error) {
|
||||
func (l *LogLine) Partial() bool {
|
||||
return l.ParseLogType == PartialLogType
|
||||
}
|
||||
|
||||
func (l *LogLine) Write(stdout io.Writer, stderr io.Writer, logOpts *LogOptions) {
|
||||
switch l.Device {
|
||||
case "stdout":
|
||||
if stdout != nil {
|
||||
fmt.Fprintln(stdout, l.String(logOpts))
|
||||
}
|
||||
case "stderr":
|
||||
if stderr != nil {
|
||||
fmt.Fprintln(stderr, l.String(logOpts))
|
||||
}
|
||||
default:
|
||||
// Warn the user if the device type does not match. Most likely the file is corrupted.
|
||||
logrus.Warnf("unknown Device type '%s' in log file from Container %s", l.Device, l.CID)
|
||||
}
|
||||
}
|
||||
|
@ -227,8 +227,10 @@ type ContainerLogsOptions struct {
|
||||
Tail int64
|
||||
// Show timestamps in the logs.
|
||||
Timestamps bool
|
||||
// Write the logs to Writer.
|
||||
Writer io.Writer
|
||||
// Write the stdout to this Writer.
|
||||
StdoutWriter io.Writer
|
||||
// Write the stderr to this Writer.
|
||||
StderrWriter io.Writer
|
||||
}
|
||||
|
||||
// ExecOptions describes the cli values to exec into
|
||||
|
@ -925,7 +925,7 @@ func (ic *ContainerEngine) ContainerRun(ctx context.Context, opts entities.Conta
|
||||
}
|
||||
|
||||
func (ic *ContainerEngine) ContainerLogs(ctx context.Context, containers []string, options entities.ContainerLogsOptions) error {
|
||||
if options.Writer == nil {
|
||||
if options.StdoutWriter == nil && options.StderrWriter == nil {
|
||||
return errors.New("no io.Writer set for container logs")
|
||||
}
|
||||
|
||||
@ -963,7 +963,7 @@ func (ic *ContainerEngine) ContainerLogs(ctx context.Context, containers []strin
|
||||
}()
|
||||
|
||||
for line := range logChannel {
|
||||
fmt.Fprintln(options.Writer, line.String(logOpts))
|
||||
line.Write(options.StdoutWriter, options.StderrWriter, logOpts)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -360,11 +360,12 @@ func (ic *ContainerEngine) ContainerCreate(ctx context.Context, s *specgen.SpecG
|
||||
func (ic *ContainerEngine) ContainerLogs(_ context.Context, nameOrIDs []string, options entities.ContainerLogsOptions) error {
|
||||
since := options.Since.Format(time.RFC3339)
|
||||
tail := strconv.FormatInt(options.Tail, 10)
|
||||
stdout := options.Writer != nil
|
||||
stdout := options.StdoutWriter != nil
|
||||
stderr := options.StderrWriter != nil
|
||||
opts := containers.LogOptions{
|
||||
Follow: &options.Follow,
|
||||
Since: &since,
|
||||
Stderr: &stdout,
|
||||
Stderr: &stderr,
|
||||
Stdout: &stdout,
|
||||
Tail: &tail,
|
||||
Timestamps: &options.Timestamps,
|
||||
@ -372,10 +373,11 @@ func (ic *ContainerEngine) ContainerLogs(_ context.Context, nameOrIDs []string,
|
||||
}
|
||||
|
||||
var err error
|
||||
outCh := make(chan string)
|
||||
stdoutCh := make(chan string)
|
||||
stderrCh := make(chan string)
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
go func() {
|
||||
err = containers.Logs(ic.ClientCxt, nameOrIDs[0], opts, outCh, outCh)
|
||||
err = containers.Logs(ic.ClientCxt, nameOrIDs[0], opts, stdoutCh, stderrCh)
|
||||
cancel()
|
||||
}()
|
||||
|
||||
@ -383,8 +385,14 @@ func (ic *ContainerEngine) ContainerLogs(_ context.Context, nameOrIDs []string,
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return err
|
||||
case line := <-outCh:
|
||||
_, _ = io.WriteString(options.Writer, line+"\n")
|
||||
case line := <-stdoutCh:
|
||||
if options.StdoutWriter != nil {
|
||||
_, _ = io.WriteString(options.StdoutWriter, line+"\n")
|
||||
}
|
||||
case line := <-stderrCh:
|
||||
if options.StderrWriter != nil {
|
||||
_, _ = io.WriteString(options.StderrWriter, line+"\n")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -355,4 +355,21 @@ var _ = Describe("Podman logs", func() {
|
||||
Expect(outlines[0]).To(Equal("1\r"))
|
||||
Expect(outlines[1]).To(Equal("2\r"))
|
||||
})
|
||||
|
||||
It("podman logs test stdout and stderr", func() {
|
||||
cname := "log-test"
|
||||
logc := podmanTest.Podman([]string{"run", "--name", cname, ALPINE, "sh", "-c", "echo stdout; echo stderr >&2"})
|
||||
logc.WaitWithDefaultTimeout()
|
||||
Expect(logc).To(Exit(0))
|
||||
|
||||
wait := podmanTest.Podman([]string{"wait", cname})
|
||||
wait.WaitWithDefaultTimeout()
|
||||
Expect(wait).To(Exit(0))
|
||||
|
||||
results := podmanTest.Podman([]string{"logs", cname})
|
||||
results.WaitWithDefaultTimeout()
|
||||
Expect(results).To(Exit(0))
|
||||
Expect(results.OutputToString()).To(Equal("stdout"))
|
||||
Expect(results.ErrorToString()).To(Equal("stderr"))
|
||||
})
|
||||
})
|
||||
|
@ -1072,7 +1072,7 @@ var _ = Describe("Podman play kube", func() {
|
||||
logs := podmanTest.Podman([]string{"logs", getCtrNameInPod(pod)})
|
||||
logs.WaitWithDefaultTimeout()
|
||||
Expect(logs.ExitCode()).To(Equal(0))
|
||||
Expect(logs.OutputToString()).To(ContainSubstring("Operation not permitted"))
|
||||
Expect(logs.ErrorToString()).To(ContainSubstring("Operation not permitted"))
|
||||
})
|
||||
|
||||
It("podman play kube seccomp pod level", func() {
|
||||
@ -1099,7 +1099,7 @@ var _ = Describe("Podman play kube", func() {
|
||||
logs := podmanTest.Podman([]string{"logs", getCtrNameInPod(pod)})
|
||||
logs.WaitWithDefaultTimeout()
|
||||
Expect(logs.ExitCode()).To(Equal(0))
|
||||
Expect(logs.OutputToString()).To(ContainSubstring("Operation not permitted"))
|
||||
Expect(logs.ErrorToString()).To(ContainSubstring("Operation not permitted"))
|
||||
})
|
||||
|
||||
It("podman play kube with pull policy of never should be 125", func() {
|
||||
|
@ -239,7 +239,7 @@ var _ = Describe("Toolbox-specific testing", func() {
|
||||
session = podmanTest.Podman([]string{"logs", "test"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
Expect(session.OutputToString()).To(ContainSubstring(expectedOutput))
|
||||
Expect(session.ErrorToString()).To(ContainSubstring(expectedOutput))
|
||||
})
|
||||
|
||||
It("podman create --userns=keep-id + podman exec - adding group with groupadd", func() {
|
||||
|
Reference in New Issue
Block a user