github.com/franc20/ayesa_sap@v7.0.0-beta.28.0.20200124003224-302d4d52fa6c+incompatible/actor/sharedaction/logging.go (about) 1 package sharedaction 2 3 import ( 4 "context" 5 "errors" 6 "log" 7 "strings" 8 "time" 9 10 "code.cloudfoundry.org/go-loggregator/rpc/loggregator_v2" 11 logcache "code.cloudfoundry.org/log-cache/pkg/client" 12 "code.cloudfoundry.org/log-cache/pkg/rpc/logcache_v1" 13 "github.com/sirupsen/logrus" 14 ) 15 16 const ( 17 StagingLog = "STG" 18 RecentLogsLines = 100 19 ) 20 21 type LogMessage struct { 22 message string 23 messageType string 24 timestamp time.Time 25 sourceType string 26 sourceInstance string 27 } 28 29 func (log LogMessage) Message() string { 30 return log.message 31 } 32 33 func (log LogMessage) Type() string { 34 return log.messageType 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 string, timestamp time.Time, sourceType string, sourceInstance string) *LogMessage { 54 return &LogMessage{ 55 message: message, 56 messageType: messageType, 57 timestamp: timestamp, 58 sourceType: sourceType, 59 sourceInstance: sourceInstance, 60 } 61 } 62 63 type LogMessages []*LogMessage 64 65 func (lm LogMessages) Len() int { return len(lm) } 66 67 func (lm LogMessages) Less(i, j int) bool { 68 return lm[i].timestamp.Before(lm[j].timestamp) 69 } 70 71 func (lm LogMessages) Swap(i, j int) { 72 lm[i], lm[j] = lm[j], lm[i] 73 } 74 75 type channelWriter struct { 76 errChannel chan error 77 } 78 79 func (c channelWriter) Write(bytes []byte) (n int, err error) { 80 c.errChannel <- errors.New(strings.Trim(string(bytes), "\n")) 81 82 return len(bytes), nil 83 } 84 85 func GetStreamingLogs(appGUID string, client LogCacheClient) (<-chan LogMessage, <-chan error, context.CancelFunc) { 86 logrus.Info("Start Tailing Logs") 87 88 outgoingLogStream := make(chan LogMessage, 1000) 89 outgoingErrStream := make(chan error, 1000) 90 ctx, cancelFunc := context.WithCancel(context.Background()) 91 go func() { 92 defer close(outgoingLogStream) 93 defer close(outgoingErrStream) 94 95 logcache.Walk( 96 ctx, 97 appGUID, 98 logcache.Visitor(func(envelopes []*loggregator_v2.Envelope) bool { 99 logMessages := convertEnvelopesToLogMessages(envelopes) 100 for _, logMessage := range logMessages { 101 select { 102 case <-ctx.Done(): 103 return false 104 default: 105 outgoingLogStream <- *logMessage 106 } 107 } 108 109 return true 110 }), 111 client.Read, 112 logcache.WithWalkStartTime(time.Now().Add(-5*time.Second)), 113 logcache.WithWalkEnvelopeTypes(logcache_v1.EnvelopeType_LOG), 114 logcache.WithWalkBackoff(logcache.NewAlwaysRetryBackoff(250*time.Millisecond)), 115 logcache.WithWalkLogger(log.New(channelWriter{ 116 errChannel: outgoingErrStream, 117 }, "", 0)), 118 ) 119 }() 120 121 return outgoingLogStream, outgoingErrStream, cancelFunc 122 } 123 124 func GetRecentLogs(appGUID string, client LogCacheClient) ([]LogMessage, error) { 125 envelopes, err := client.Read( 126 context.Background(), 127 appGUID, 128 time.Time{}, 129 logcache.WithEnvelopeTypes(logcache_v1.EnvelopeType_LOG), 130 logcache.WithLimit(RecentLogsLines), 131 logcache.WithDescending(), 132 ) 133 if err != nil { 134 return nil, err 135 } 136 137 logMessages := convertEnvelopesToLogMessages(envelopes) 138 var reorderedLogMessages []LogMessage 139 for i := len(logMessages) - 1; i >= 0; i-- { 140 reorderedLogMessages = append(reorderedLogMessages, *logMessages[i]) 141 } 142 143 return reorderedLogMessages, nil 144 } 145 146 func convertEnvelopesToLogMessages(envelopes []*loggregator_v2.Envelope) []*LogMessage { 147 var logMessages []*LogMessage 148 for _, envelope := range envelopes { 149 logEnvelope, ok := envelope.GetMessage().(*loggregator_v2.Envelope_Log) 150 if !ok { 151 continue 152 } 153 log := logEnvelope.Log 154 155 logMessages = append(logMessages, NewLogMessage( 156 string(log.Payload), 157 loggregator_v2.Log_Type_name[int32(log.Type)], 158 time.Unix(0, envelope.GetTimestamp()), 159 envelope.GetTags()["source_type"], 160 envelope.GetInstanceId(), 161 )) 162 } 163 return logMessages 164 }