github.com/axw/juju@v0.0.0-20161005053422-4bd6544d08d4/api/logsender/logsender.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  // Package logsender implements the API for storing log
     5  // messages on the API server.
     6  package logsender
     7  
     8  import (
     9  	"io"
    10  	"net/url"
    11  
    12  	"github.com/juju/errors"
    13  
    14  	"github.com/juju/juju/api/base"
    15  	"github.com/juju/juju/apiserver/params"
    16  	"github.com/juju/juju/version"
    17  )
    18  
    19  // LogWriter is the interface that allows sending log
    20  // messages to the server for storage.
    21  type LogWriter interface {
    22  	// WriteLog writes the given log record.
    23  	WriteLog(*params.LogRecord) error
    24  
    25  	io.Closer
    26  }
    27  
    28  // API provides access to the LogSender API.
    29  type API struct {
    30  	connector base.StreamConnector
    31  }
    32  
    33  // NewAPI creates a new client-side logsender API.
    34  func NewAPI(connector base.StreamConnector) *API {
    35  	return &API{connector: connector}
    36  }
    37  
    38  // LogWriter returns a new log writer interface value
    39  // which must be closed when finished with.
    40  func (api *API) LogWriter() (LogWriter, error) {
    41  	attrs := make(url.Values)
    42  	attrs.Set("jujuclientversion", version.Current.String())
    43  	conn, err := api.connector.ConnectStream("/logsink", attrs)
    44  	if err != nil {
    45  		return nil, errors.Annotatef(err, "cannot connect to /logsink")
    46  	}
    47  	return writer{conn}, nil
    48  }
    49  
    50  type writer struct {
    51  	conn base.Stream
    52  }
    53  
    54  func (w writer) WriteLog(m *params.LogRecord) error {
    55  	// Note: due to the fire-and-forget nature of the
    56  	// logsink API, it is possible that when the
    57  	// connection dies, any logs that were "in-flight"
    58  	// will not be recorded on the server side.
    59  	if err := w.conn.WriteJSON(m); err != nil {
    60  		return errors.Annotatef(err, "cannot send log message")
    61  	}
    62  	return nil
    63  }
    64  
    65  func (w writer) Close() error {
    66  	return w.conn.Close()
    67  }