github.com/hanks177/podman/v4@v4.1.3-0.20220613032544-16d90015bc83/pkg/bindings/containers/logs.go (about)

     1  package containers
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"io"
     7  	"net/http"
     8  	"strconv"
     9  
    10  	"github.com/hanks177/podman/v4/pkg/bindings"
    11  	"github.com/pkg/errors"
    12  )
    13  
    14  // Logs obtains a container's logs given the options provided.  The logs are then sent to the
    15  // stdout|stderr channels as strings.
    16  func Logs(ctx context.Context, nameOrID string, options *LogOptions, stdoutChan, stderrChan chan string) error {
    17  	if options == nil {
    18  		options = new(LogOptions)
    19  	}
    20  	conn, err := bindings.GetClient(ctx)
    21  	if err != nil {
    22  		return err
    23  	}
    24  	params, err := options.ToParams()
    25  	if err != nil {
    26  		return err
    27  	}
    28  	// The API requires either stdout|stderr be used. If neither are specified, we specify stdout
    29  	if options.Stdout == nil && options.Stderr == nil {
    30  		params.Set("stdout", strconv.FormatBool(true))
    31  	}
    32  	response, err := conn.DoRequest(ctx, nil, http.MethodGet, "/containers/%s/logs", params, nil, nameOrID)
    33  	if err != nil {
    34  		return err
    35  	}
    36  	defer response.Body.Close()
    37  
    38  	buffer := make([]byte, 1024)
    39  	for {
    40  		fd, l, err := DemuxHeader(response.Body, buffer)
    41  		if err != nil {
    42  			if errors.Is(err, io.EOF) || errors.Is(err, io.ErrUnexpectedEOF) {
    43  				return nil
    44  			}
    45  			return err
    46  		}
    47  		frame, err := DemuxFrame(response.Body, buffer, l)
    48  		if err != nil {
    49  			return err
    50  		}
    51  
    52  		switch fd {
    53  		case 0:
    54  			stdoutChan <- string(frame)
    55  		case 1:
    56  			stdoutChan <- string(frame)
    57  		case 2:
    58  			stderrChan <- string(frame)
    59  		case 3:
    60  			return errors.New("from service in stream: " + string(frame))
    61  		default:
    62  			return fmt.Errorf("unrecognized input header: %d", fd)
    63  		}
    64  	}
    65  }