@@ -63,79 +63,114 @@ func (lc *Client) ProcessLogs(
6363 dataChan chan []byte ,
6464 isShutdown bool ,
6565) {
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
7066 for {
7167 select {
7268 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
13571 }
13672 case <- ctx .Done ():
13773 lc .logger .Debug ("Current invocation over. Interrupting logs processing goroutine" )
13874 return
13975 }
14076 }
14177}
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