@@ -63,79 +63,114 @@ func (lc *Client) ProcessLogs(
63
63
dataChan chan []byte ,
64
64
isShutdown bool ,
65
65
) {
66
- // platformStartReqID is to identify the requestID for the function
67
- // logs under the assumption that function logs for a specific request
68
- // ID will be bounded by PlatformStart and PlatformEnd events.
69
- var platformStartReqID string
70
66
for {
71
67
select {
72
68
case logEvent := <- lc .logsChannel :
73
- lc .logger .Debugf ("Received log event %v for request ID %s" , logEvent .Type , logEvent .Record .RequestID )
74
- switch logEvent .Type {
75
- case PlatformStart :
76
- platformStartReqID = logEvent .Record .RequestID
77
- case PlatformRuntimeDone :
78
- if err := lc .invocationLifecycler .OnLambdaLogRuntimeDone (
79
- logEvent .Record .RequestID ,
80
- logEvent .Record .Status ,
81
- logEvent .Time ,
82
- ); err != nil {
83
- lc .logger .Warnf ("Failed to finalize invocation with request ID %s: %v" , logEvent .Record .RequestID , err )
84
- }
85
- // For invocation events the platform.runtimeDone would be the last possible event.
86
- if ! isShutdown && logEvent .Record .RequestID == requestID {
87
- lc .logger .Debugf (
88
- "Processed runtime done event for reqID %s as the last log event for the invocation" ,
89
- logEvent .Record .RequestID ,
90
- )
91
- return
92
- }
93
- case PlatformReport :
94
- fnARN , deadlineMs , ts , err := lc .invocationLifecycler .OnPlatformReport (logEvent .Record .RequestID )
95
- if err != nil {
96
- lc .logger .Warnf ("Failed to process platform report: %v" , err )
97
- } else {
98
- lc .logger .Debugf ("Received platform report for %s" , logEvent .Record .RequestID )
99
- processedMetrics , err := ProcessPlatformReport (fnARN , deadlineMs , ts , logEvent )
100
- if err != nil {
101
- lc .logger .Errorf ("Error processing Lambda platform metrics: %v" , err )
102
- } else {
103
- select {
104
- case dataChan <- processedMetrics :
105
- case <- ctx .Done ():
106
- }
107
- }
108
- }
109
- // For shutdown event the platform report metrics for the previous log event
110
- // would be the last possible log event. After processing this metric the
111
- // invocation lifecycler's cache should be empty.
112
- if isShutdown && lc .invocationLifecycler .Size () == 0 {
113
- lc .logger .Debugf (
114
- "Processed platform report event for reqID %s as the last log event before shutdown" ,
115
- logEvent .Record .RequestID ,
116
- )
117
- return
118
- }
119
- case PlatformLogsDropped :
120
- lc .logger .Warnf ("Logs dropped due to extension falling behind: %v" , logEvent .Record )
121
- case FunctionLog :
122
- processedLog , err := ProcessFunctionLog (
123
- platformStartReqID ,
124
- invokedFnArn ,
125
- logEvent ,
126
- )
127
- if err != nil {
128
- lc .logger .Warnf ("Error processing function log : %v" , err )
129
- } else {
130
- select {
131
- case dataChan <- processedLog :
132
- case <- ctx .Done ():
133
- }
134
- }
69
+ if shouldExit := lc .handleEvent (logEvent , ctx , requestID , invokedFnArn , dataChan , isShutdown ); shouldExit {
70
+ return
135
71
}
136
72
case <- ctx .Done ():
137
73
lc .logger .Debug ("Current invocation over. Interrupting logs processing goroutine" )
138
74
return
139
75
}
140
76
}
141
77
}
78
+
79
+ func (lc * Client ) FlushData (
80
+ ctx context.Context ,
81
+ requestID string ,
82
+ invokedFnArn string ,
83
+ dataChan chan []byte ,
84
+ isShutdown bool ,
85
+ ) {
86
+ lc .logger .Infof ("flushing %d buffered logs" , len (lc .logsChannel ))
87
+ for {
88
+ select {
89
+ case logEvent := <- lc .logsChannel :
90
+ if shouldExit := lc .handleEvent (logEvent , ctx , requestID , invokedFnArn , dataChan , isShutdown ); shouldExit {
91
+ return
92
+ }
93
+ case <- ctx .Done ():
94
+ lc .logger .Debug ("Current invocation over. Interrupting logs flushing" )
95
+ return
96
+ default :
97
+ if len (lc .logsChannel ) == 0 {
98
+ lc .logger .Debug ("Flush ended for logs - no data in buffer" )
99
+ return
100
+ }
101
+ }
102
+ }
103
+ }
104
+
105
+ func (lc * Client ) handleEvent (logEvent LogEvent ,
106
+ ctx context.Context ,
107
+ requestID string ,
108
+ invokedFnArn string ,
109
+ dataChan chan []byte ,
110
+ isShutdown bool ,
111
+ ) bool {
112
+ lc .logger .Debugf ("Received log event %v for request ID %s" , logEvent .Type , logEvent .Record .RequestID )
113
+ switch logEvent .Type {
114
+ case PlatformStart :
115
+ lc .invocationLifecycler .OnPlatformStart (logEvent .Record .RequestID )
116
+ case PlatformRuntimeDone :
117
+ if err := lc .invocationLifecycler .OnLambdaLogRuntimeDone (
118
+ logEvent .Record .RequestID ,
119
+ logEvent .Record .Status ,
120
+ logEvent .Time ,
121
+ ); err != nil {
122
+ lc .logger .Warnf ("Failed to finalize invocation with request ID %s: %v" , logEvent .Record .RequestID , err )
123
+ }
124
+ // For invocation events the platform.runtimeDone would be the last possible event.
125
+ if ! isShutdown && logEvent .Record .RequestID == requestID {
126
+ lc .logger .Debugf (
127
+ "Processed runtime done event for reqID %s as the last log event for the invocation" ,
128
+ logEvent .Record .RequestID ,
129
+ )
130
+ return true
131
+ }
132
+ case PlatformReport :
133
+ fnARN , deadlineMs , ts , err := lc .invocationLifecycler .OnPlatformReport (logEvent .Record .RequestID )
134
+ if err != nil {
135
+ lc .logger .Warnf ("Failed to process platform report: %v" , err )
136
+ } else {
137
+ lc .logger .Debugf ("Received platform report for %s" , logEvent .Record .RequestID )
138
+ processedMetrics , err := ProcessPlatformReport (fnARN , deadlineMs , ts , logEvent )
139
+ if err != nil {
140
+ lc .logger .Errorf ("Error processing Lambda platform metrics: %v" , err )
141
+ } else {
142
+ select {
143
+ case dataChan <- processedMetrics :
144
+ case <- ctx .Done ():
145
+ }
146
+ }
147
+ }
148
+ // For shutdown event the platform report metrics for the previous log event
149
+ // would be the last possible log event. After processing this metric the
150
+ // invocation lifecycler's cache should be empty.
151
+ if isShutdown && lc .invocationLifecycler .Size () == 0 {
152
+ lc .logger .Debugf (
153
+ "Processed platform report event for reqID %s as the last log event before shutdown" ,
154
+ logEvent .Record .RequestID ,
155
+ )
156
+ return true
157
+ }
158
+ case PlatformLogsDropped :
159
+ lc .logger .Warnf ("Logs dropped due to extension falling behind: %v" , logEvent .Record )
160
+ case FunctionLog :
161
+ processedLog , err := ProcessFunctionLog (
162
+ lc .invocationLifecycler .PlatformStartReqID (),
163
+ invokedFnArn ,
164
+ logEvent ,
165
+ )
166
+ if err != nil {
167
+ lc .logger .Warnf ("Error processing function log : %v" , err )
168
+ } else {
169
+ select {
170
+ case dataChan <- processedLog :
171
+ case <- ctx .Done ():
172
+ }
173
+ }
174
+ }
175
+ return false
176
+ }
0 commit comments