github.com/elopio/cli@v6.21.2-0.20160902224010-ea909d1fdb2f+incompatible/cf/api/logs/loggregator_logs_repository.go (about)

     1  package logs
     2  
     3  import (
     4  	"errors"
     5  	"time"
     6  
     7  	. "code.cloudfoundry.org/cli/cf/i18n"
     8  
     9  	"code.cloudfoundry.org/cli/cf/api/authentication"
    10  	"code.cloudfoundry.org/cli/cf/configuration/coreconfig"
    11  	consumer "github.com/cloudfoundry/loggregator_consumer"
    12  	"github.com/cloudfoundry/loggregatorlib/logmessage"
    13  	noaa_errors "github.com/cloudfoundry/noaa/errors"
    14  )
    15  
    16  type LoggregatorLogsRepository struct {
    17  	consumer       consumer.LoggregatorConsumer
    18  	config         coreconfig.Reader
    19  	tokenRefresher authentication.TokenRefresher
    20  	messageQueue   *LoggregatorMessageQueue
    21  	BufferTime     time.Duration
    22  }
    23  
    24  func NewLoggregatorLogsRepository(config coreconfig.Reader, consumer consumer.LoggregatorConsumer, refresher authentication.TokenRefresher) *LoggregatorLogsRepository {
    25  	return &LoggregatorLogsRepository{
    26  		config:         config,
    27  		consumer:       consumer,
    28  		tokenRefresher: refresher,
    29  		messageQueue:   NewLoggregatorMessageQueue(),
    30  		BufferTime:     defaultBufferTime,
    31  	}
    32  }
    33  
    34  func (repo *LoggregatorLogsRepository) Close() {
    35  	_ = repo.consumer.Close()
    36  }
    37  
    38  func loggableMessagesFromLoggregatorMessages(messages []*logmessage.LogMessage) []Loggable {
    39  	loggableMessages := make([]Loggable, len(messages))
    40  
    41  	for i, m := range messages {
    42  		loggableMessages[i] = NewLoggregatorLogMessage(m)
    43  	}
    44  
    45  	return loggableMessages
    46  }
    47  
    48  func (repo *LoggregatorLogsRepository) RecentLogsFor(appGUID string) ([]Loggable, error) {
    49  	messages, err := repo.consumer.Recent(appGUID, repo.config.AccessToken())
    50  
    51  	switch err.(type) {
    52  	case nil: // do nothing
    53  	case *noaa_errors.UnauthorizedError:
    54  		_, _ = repo.tokenRefresher.RefreshAuthToken()
    55  		return repo.RecentLogsFor(appGUID)
    56  	default:
    57  		return loggableMessagesFromLoggregatorMessages(messages), err
    58  	}
    59  
    60  	consumer.SortRecent(messages)
    61  
    62  	return loggableMessagesFromLoggregatorMessages(messages), nil
    63  }
    64  
    65  func (repo *LoggregatorLogsRepository) TailLogsFor(appGUID string, onConnect func(), logChan chan<- Loggable, errChan chan<- error) {
    66  	ticker := time.NewTicker(repo.BufferTime)
    67  	endpoint := repo.config.LoggregatorEndpoint()
    68  	if endpoint == "" {
    69  		errChan <- errors.New(T("Loggregator endpoint missing from config file"))
    70  		return
    71  	}
    72  
    73  	repo.consumer.SetOnConnectCallback(onConnect)
    74  	c, err := repo.consumer.Tail(appGUID, repo.config.AccessToken())
    75  
    76  	switch err.(type) {
    77  	case nil: // do nothing
    78  	case *noaa_errors.UnauthorizedError:
    79  		_, _ = repo.tokenRefresher.RefreshAuthToken()
    80  		c, err = repo.consumer.Tail(appGUID, repo.config.AccessToken())
    81  	default:
    82  		errChan <- err
    83  		return
    84  	}
    85  
    86  	if err != nil {
    87  		errChan <- err
    88  		return
    89  	}
    90  
    91  	go func() {
    92  		for range ticker.C {
    93  			repo.flushMessages(logChan)
    94  		}
    95  	}()
    96  
    97  	go func() {
    98  		for msg := range c {
    99  			repo.messageQueue.PushMessage(msg)
   100  		}
   101  
   102  		repo.flushMessages(logChan)
   103  		close(logChan)
   104  	}()
   105  }
   106  
   107  func (repo *LoggregatorLogsRepository) flushMessages(c chan<- Loggable) {
   108  	repo.messageQueue.EnumerateAndClear(func(m *logmessage.LogMessage) {
   109  		c <- NewLoggregatorLogMessage(m)
   110  	})
   111  }