github.com/Heebron/moby@v0.0.0-20221111184709-6eab4f55faf7/daemon/logger/logentries/logentries.go (about)

     1  // Package logentries provides the log driver for forwarding server logs
     2  // to logentries endpoints.
     3  package logentries // import "github.com/docker/docker/daemon/logger/logentries"
     4  
     5  import (
     6  	"fmt"
     7  	"strconv"
     8  
     9  	"github.com/bsphere/le_go"
    10  	"github.com/docker/docker/daemon/logger"
    11  	"github.com/pkg/errors"
    12  	"github.com/sirupsen/logrus"
    13  )
    14  
    15  type logentries struct {
    16  	tag           string
    17  	containerID   string
    18  	containerName string
    19  	writer        *le_go.Logger
    20  	extra         map[string]string
    21  	lineOnly      bool
    22  }
    23  
    24  const (
    25  	name     = "logentries"
    26  	token    = "logentries-token"
    27  	lineonly = "line-only"
    28  )
    29  
    30  func init() {
    31  	if err := logger.RegisterLogDriver(name, New); err != nil {
    32  		panic(err)
    33  	}
    34  	if err := logger.RegisterLogOptValidator(name, ValidateLogOpt); err != nil {
    35  		panic(err)
    36  	}
    37  }
    38  
    39  // New creates a logentries logger using the configuration passed in on
    40  // the context. The supported context configuration variable is
    41  // logentries-token.
    42  func New(info logger.Info) (logger.Logger, error) {
    43  	logrus.WithField("container", info.ContainerID).
    44  		WithField("token", info.Config[token]).
    45  		WithField("line-only", info.Config[lineonly]).
    46  		Debug("logging driver logentries configured")
    47  
    48  	log, err := le_go.Connect(info.Config[token])
    49  	if err != nil {
    50  		return nil, errors.Wrap(err, "error connecting to logentries")
    51  	}
    52  	var lineOnly bool
    53  	if info.Config[lineonly] != "" {
    54  		if lineOnly, err = strconv.ParseBool(info.Config[lineonly]); err != nil {
    55  			return nil, errors.Wrap(err, "error parsing lineonly option")
    56  		}
    57  	}
    58  	return &logentries{
    59  		containerID:   info.ContainerID,
    60  		containerName: info.ContainerName,
    61  		writer:        log,
    62  		lineOnly:      lineOnly,
    63  	}, nil
    64  }
    65  
    66  func (f *logentries) Log(msg *logger.Message) error {
    67  	if !f.lineOnly {
    68  		data := map[string]string{
    69  			"container_id":   f.containerID,
    70  			"container_name": f.containerName,
    71  			"source":         msg.Source,
    72  			"log":            string(msg.Line),
    73  		}
    74  		for k, v := range f.extra {
    75  			data[k] = v
    76  		}
    77  		ts := msg.Timestamp
    78  		logger.PutMessage(msg)
    79  		f.writer.Println(f.tag, ts, data)
    80  	} else {
    81  		line := string(msg.Line)
    82  		logger.PutMessage(msg)
    83  		f.writer.Println(line)
    84  	}
    85  	return nil
    86  }
    87  
    88  func (f *logentries) Close() error {
    89  	return f.writer.Close()
    90  }
    91  
    92  func (f *logentries) Name() string {
    93  	return name
    94  }
    95  
    96  // ValidateLogOpt looks for logentries specific log option logentries-address.
    97  func ValidateLogOpt(cfg map[string]string) error {
    98  	for key := range cfg {
    99  		switch key {
   100  		case "env":
   101  		case "env-regex":
   102  		case "labels":
   103  		case "labels-regex":
   104  		case "tag":
   105  		case key:
   106  		default:
   107  			return fmt.Errorf("unknown log opt '%s' for logentries log driver", key)
   108  		}
   109  	}
   110  
   111  	if cfg[token] == "" {
   112  		return fmt.Errorf("Missing logentries token")
   113  	}
   114  
   115  	return nil
   116  }