github.com/cloudfoundry-attic/cli-with-i18n@v6.32.1-0.20171002233121-7401370d3b85+incompatible/actor/v3action/logging.go (about)

     1  package v3action
     2  
     3  import (
     4  	"time"
     5  
     6  	noaaErrors "github.com/cloudfoundry/noaa/errors"
     7  	"github.com/cloudfoundry/sonde-go/events"
     8  )
     9  
    10  const StagingLog = "STG"
    11  
    12  type NOAATimeoutError struct{}
    13  
    14  func (NOAATimeoutError) Error() string {
    15  	return "Timeout trying to connect to NOAA"
    16  }
    17  
    18  type LogMessage struct {
    19  	message        string
    20  	messageType    events.LogMessage_MessageType
    21  	timestamp      time.Time
    22  	sourceType     string
    23  	sourceInstance string
    24  }
    25  
    26  func (log LogMessage) Message() string {
    27  	return log.message
    28  }
    29  
    30  func (log LogMessage) Type() string {
    31  	if log.messageType == events.LogMessage_OUT {
    32  		return "OUT"
    33  	}
    34  	return "ERR"
    35  }
    36  
    37  func (log LogMessage) Staging() bool {
    38  	return log.sourceType == StagingLog
    39  }
    40  
    41  func (log LogMessage) Timestamp() time.Time {
    42  	return log.timestamp
    43  }
    44  
    45  func (log LogMessage) SourceType() string {
    46  	return log.sourceType
    47  }
    48  
    49  func (log LogMessage) SourceInstance() string {
    50  	return log.sourceInstance
    51  }
    52  
    53  func NewLogMessage(message string, messageType int, timestamp time.Time, sourceType string, sourceInstance string) *LogMessage {
    54  	return &LogMessage{
    55  		message:        message,
    56  		messageType:    events.LogMessage_MessageType(messageType),
    57  		timestamp:      timestamp,
    58  		sourceType:     sourceType,
    59  		sourceInstance: sourceInstance,
    60  	}
    61  }
    62  
    63  func (Actor) GetStreamingLogs(appGUID string, client NOAAClient) (<-chan *LogMessage, <-chan error) {
    64  	// Do not pass in token because client should have a TokenRefresher set
    65  	eventStream, errStream := client.TailingLogs(appGUID, "")
    66  
    67  	messages := make(chan *LogMessage)
    68  	errs := make(chan error)
    69  
    70  	go func() {
    71  		defer close(messages)
    72  		defer close(errs)
    73  
    74  	dance:
    75  		for {
    76  			select {
    77  			case event, ok := <-eventStream:
    78  				if !ok {
    79  					break dance
    80  				}
    81  
    82  				messages <- &LogMessage{
    83  					message:        string(event.GetMessage()),
    84  					messageType:    event.GetMessageType(),
    85  					timestamp:      time.Unix(0, event.GetTimestamp()),
    86  					sourceInstance: event.GetSourceInstance(),
    87  					sourceType:     event.GetSourceType(),
    88  				}
    89  			case err, ok := <-errStream:
    90  				if !ok {
    91  					break dance
    92  				}
    93  
    94  				if _, ok := err.(noaaErrors.RetryError); ok {
    95  					break
    96  				}
    97  
    98  				if err != nil {
    99  					errs <- err
   100  				}
   101  			}
   102  		}
   103  	}()
   104  
   105  	return messages, errs
   106  }
   107  
   108  func (actor Actor) GetStreamingLogsForApplicationByNameAndSpace(appName string, spaceGUID string, client NOAAClient) (<-chan *LogMessage, <-chan error, Warnings, error) {
   109  	app, allWarnings, err := actor.GetApplicationByNameAndSpace(appName, spaceGUID)
   110  	if err != nil {
   111  		return nil, nil, allWarnings, err
   112  	}
   113  
   114  	messages, logErrs := actor.GetStreamingLogs(app.GUID, client)
   115  
   116  	return messages, logErrs, allWarnings, err
   117  }