6
6
from moesifapi .models import *
7
7
from .client_ip import ClientIp
8
8
from datetime import *
9
- from urllib .parse import urlencode
10
9
import base64
11
10
import json
12
11
import os
12
+ from pprint import pprint
13
+ import base64
14
+ try :
15
+ from urllib import urlencode
16
+ except ImportError :
17
+ from urllib .parse import urlencode
13
18
14
19
def MoesifLogger (moesif_options ):
15
20
class log_data (LambdaDecorator ):
@@ -26,8 +31,10 @@ def __init__(self, handler):
26
31
self .DEBUG = self .moesif_options .get ('DEBUG' , False )
27
32
self .event = None
28
33
self .context = None
34
+ self .start_time = datetime .utcnow ()
35
+
29
36
# Intialized the client
30
- if os .environ [ "MOESIF_APPLICATION_ID" ] :
37
+ if os .environ . get ( "MOESIF_APPLICATION_ID" ) :
31
38
self .api_client = MoesifAPIClient (os .environ ["MOESIF_APPLICATION_ID" ]).api
32
39
else :
33
40
raise Exception ('Moesif Application ID is required in settings' )
@@ -47,10 +54,10 @@ def get_user_id(self, event, context):
47
54
username = rc_identity_id
48
55
except :
49
56
if self .DEBUG :
50
- print ("can not fetch apiKey from cognitoIdentityId event, setting userId to None." )
57
+ print ("MOESIF can not fetch apiKey from cognitoIdentityId event, setting userId to None." )
51
58
except Exception as e :
52
59
if self .DEBUG :
53
- print ("can not execute identify_user function, please check moesif settings." )
60
+ print ("MOESIF can not execute identify_user function, please check moesif settings." )
54
61
print (e )
55
62
return username
56
63
@@ -63,89 +70,70 @@ def get_company_id(self, event, context):
63
70
company_id = identify_company (event , context )
64
71
except Exception as e :
65
72
if self .DEBUG :
66
- print ("can not execute identify_company function, please check moesif settings." )
73
+ print ("MOESIF can not execute identify_company function, please check moesif settings." )
67
74
print (e )
68
75
return company_id
69
76
70
- def process_request_body (self , raw_request_body ):
71
- """Function to process Request body"""
72
- req_body = None
73
- req_transfer_encoding = None
74
- try :
75
- if 'isBase64Encoded' in raw_request_body and 'body' in raw_request_body and raw_request_body ['isBase64Encoded' ] and raw_request_body ['body' ]:
76
- req_body = raw_request_body ['body' ]
77
- req_transfer_encoding = 'base64'
78
- else :
79
- if 'body' in raw_request_body and raw_request_body ['body' ] and isinstance (raw_request_body ['body' ], str ):
80
- req_body = json .loads (raw_request_body ['body' ])
81
- else :
82
- req_body = raw_request_body ['body' ]
83
- req_transfer_encoding = 'json'
84
- except Exception as e :
85
- if self .DEBUG :
86
- print ('Error while parsing request body' )
87
- print (e )
88
- return req_body , req_transfer_encoding
77
+ def build_uri (self , event ):
78
+
79
+ uri = event ['headers' ].get ('X-Forwarded-Proto' , event ['headers' ].get ('x-forwarded-proto' , 'http://' )) + event ['headers' ].get ('Host' , event ['headers' ].get ('host' , 'localhost' )) + event .get ('path' , '/' )
80
+
81
+ if event .get ('multiValueQueryStringParameters' , {}):
82
+ uri = uri + '?' + urlencode (event ['multiValueQueryStringParameters' ], doseq = True )
83
+ elif event .get ('queryStringParameters' , {}):
84
+ uri = uri + '?' + urlencode (event ['queryStringParameters' ])
85
+ return uri
89
86
90
- def process_response_body (self , raw_response_body ):
91
- """Function to process Response body"""
92
- resp_body = None
93
- resp_transfer_encoding = None
87
+ def process_body (self , body_wrapper ):
88
+ """Function to process body"""
89
+ if not (self .LOG_BODY and body_wrapper .get ('body' )):
90
+ return None , 'json'
91
+
92
+ body = None
93
+ transfer_encoding = None
94
94
try :
95
- if 'isBase64Encoded' in raw_response_body and 'body' in raw_response_body and raw_response_body [ 'isBase64Encoded' ] and raw_response_body [ 'body' ] :
96
- resp_body = raw_response_body [ 'body' ]
97
- resp_transfer_encoding = 'base64'
95
+ if body_wrapper . get ( 'isBase64Encoded' , False ) :
96
+ body = body_wrapper . get ( 'body' )
97
+ transfer_encoding = 'base64'
98
98
else :
99
- if 'body' in raw_response_body and raw_response_body [ 'body' ] and isinstance (raw_response_body ['body' ], str ):
100
- resp_body = json .loads (raw_response_body [ 'body' ] )
99
+ if isinstance (body_wrapper ['body' ], str ):
100
+ body = json .loads (body_wrapper . get ( 'body' ) )
101
101
else :
102
- resp_body = raw_response_body [ 'body' ]
103
- resp_transfer_encoding = 'json'
102
+ body = body_wrapper . get ( 'body' )
103
+ transfer_encoding = 'json'
104
104
except Exception as e :
105
- if self .DEBUG :
106
- print ('Error while parsing response body' )
107
- print (e )
108
- return resp_body , resp_transfer_encoding
105
+ body = base64 .b64encode (body_wrapper ['body' ].encode ("utf-8" ))
106
+ return str (encodedBytes , "utf-8" ), 'json'
107
+ return body , transfer_encoding
109
108
110
109
def before (self , event , context ):
111
110
"""This function runs before the handler is invoked, is passed the event & context and must return an event & context too."""
111
+
112
+ # Request Method
113
+ request_verb = event .get ('httpMethod' )
114
+ if request_verb is None :
115
+ print ('MOESIF: [before] AWS Lambda trigger must be a Load Balancer or API Gateway See https://docs.aws.amazon.com/lambda/latest/dg/services-alb.html or https://docs.aws.amazon.com/lambda/latest/dg/with-on-demand-https.html.' )
116
+ return event , context
117
+
112
118
# Request headers
113
119
req_headers = {}
114
120
try :
115
121
if 'headers' in event :
116
122
req_headers = APIHelper .json_deserialize (event ['headers' ])
117
123
except Exception as e :
118
124
if self .DEBUG :
119
- print ('Error while fetching request headers' )
125
+ print ('MOESIF Error while fetching request headers' )
120
126
print (e )
121
127
122
128
# Request Time
123
- request_time = datetime .utcnow ().strftime ("%Y-%m-%dT%H:%M:%S.%f" )[:- 3 ]
124
-
125
- # Request URI
126
- try :
127
- request_uri = event ['headers' ]['X-Forwarded-Proto' ] + '://' + event ['headers' ]['Host' ] + event ['path' ] + '?' + urlencode (event ['queryStringParameters' ])
128
- except :
129
- request_uri = '/'
130
-
131
- # Request Method
132
- try :
133
- request_verb = event ['httpMethod' ]
134
- except :
135
- if self .DEBUG :
136
- print ('Request method should not be empty.' )
129
+ epoch = event and event .get ('request_context' , {}).get ('requestTimeEpoch' )
130
+ if epoch is not None :
131
+ request_time = datetime .utcfromtimestamp (epoch )
132
+ else :
133
+ request_time = self .start_time
137
134
138
135
# Request Body
139
- req_body = None
140
- req_transfer_encoding = None
141
- try :
142
- if self .LOG_BODY and 'body' in event :
143
- if event ['body' ]:
144
- req_body , req_transfer_encoding = self .process_request_body (event )
145
- except Exception as e :
146
- if self .DEBUG :
147
- print ('Error while fetching request body' )
148
- print (e )
136
+ req_body , req_transfer_encoding = self .process_body (event )
149
137
150
138
# Metadata
151
139
try :
@@ -158,14 +146,15 @@ def before(self, event, context):
158
146
self .metadata = {
159
147
'trace_id' : str (context .aws_request_id ),
160
148
'function_name' : context .function_name ,
161
- 'request_context' : event ['requestContext' ]
149
+ 'request_context' : event ['requestContext' ],
150
+ 'context' : context
162
151
}
163
152
except :
164
153
if self .DEBUG :
165
- print ("can not fetch default function_name and request_context from aws context, setting metadata to None." )
154
+ print ("MOESIF can not fetch default function_name and request_context from aws context, setting metadata to None." )
166
155
except Exception as e :
167
156
if self .DEBUG :
168
- print ("can not execute GET_METADATA function, please check moesif settings." )
157
+ print ("MOESIF can not execute GET_METADATA function, please check moesif settings." )
169
158
print (e )
170
159
171
160
# User Id
@@ -187,10 +176,10 @@ def before(self, event, context):
187
176
self .session_token = rc_api_key
188
177
except KeyError :
189
178
if self .DEBUG :
190
- print ("can not fetch apiKey from aws event, setting session_token to None." )
179
+ print ("MOESIF can not fetch apiKey from aws event, setting session_token to None." )
191
180
except Exception as e :
192
181
if self .DEBUG :
193
- print ("can not execute GET_SESSION_TOKEN function, please check moesif settings." )
182
+ print ("MOESIF can not execute GET_SESSION_TOKEN function, please check moesif settings." )
194
183
print (e )
195
184
196
185
# Api Version
@@ -205,74 +194,41 @@ def before(self, event, context):
205
194
api_version = context .function_version
206
195
except KeyError :
207
196
if self .DEBUG :
208
- print ("can not fetch default function_version from aws context, setting api_version to None." )
197
+ print ("MOESIF can not fetch default function_version from aws context, setting api_version to None." )
209
198
except Exception as e :
210
199
if self .DEBUG :
211
- print ("can not execute GET_API_VERSION function, please check moesif settings." )
200
+ print ("MOESIF can not execute GET_API_VERSION function, please check moesif settings." )
212
201
print (e )
213
202
214
203
# IpAddress
215
- ip_address = None
216
- try :
217
- if 'headers' in event and 'requestContext' in event and 'identity' in event ['requestContext' ] and 'sourceIp' in event ['requestContext' ]['identity' ] and event ['requestContext' ]['identity' ]['sourceIp' ]:
218
- ip_address = self .client_ip .get_client_address (event ['headers' ], event ['requestContext' ]['identity' ]['sourceIp' ])
219
- except Exception as e :
220
- if self .DEBUG :
221
- print ("Error while fetching Client Ip address, setting Request Ip address to None." )
222
- print (e )
204
+ ip_address = event .get ('requestContext' , {}).get ('identity' , {}).get ('sourceIp' , None )
223
205
224
206
# Event Request Object
225
- self .event_req = EventRequestModel (time = request_time ,
226
- uri = request_uri ,
207
+ self .event_req = EventRequestModel (time = request_time . strftime ( "%Y-%m-%dT%H:%M:%S.%f" )[: - 3 ] ,
208
+ uri = self . build_uri ( event ) ,
227
209
verb = request_verb ,
228
210
api_version = api_version ,
229
- ip_address = ip_address ,
211
+ ip_address = self . client_ip . get_client_address ( event [ 'headers' ], ip_address ) ,
230
212
headers = req_headers ,
231
213
body = req_body ,
232
214
transfer_encoding = req_transfer_encoding )
233
215
234
216
# Set/Save event and context for use Skip Event function
235
217
self .event = event
236
218
self .context = context
237
-
219
+
238
220
# Return event, context
239
221
return event , context
240
222
241
223
def after (self , retval ):
242
224
"""This function runs after the handler is invoked, is passed the response and must return an response too."""
243
225
# Response body
244
- resp_body = None
245
- resp_transfer_encoding = None
246
- try :
247
- if self .LOG_BODY and 'body' in retval :
248
- if retval ['body' ]:
249
- resp_body , resp_transfer_encoding = self .process_response_body (retval )
250
- except Exception as e :
251
- if self .DEBUG :
252
- print ('Error while fetching response body' )
253
- print (e )
254
-
255
- # Response headers
256
- resp_headers = {}
257
- try :
258
- if 'headers' in retval :
259
- resp_headers = retval ['headers' ]
260
- except Exception as e :
261
- if self .DEBUG :
262
- print ('Error while fetching response headers' )
263
- print (e )
264
-
265
- # Response status code
266
- try :
267
- status_code = retval ['statusCode' ]
268
- except :
269
- if self .DEBUG :
270
- print ('Response status code should not be empty' )
226
+ resp_body , resp_transfer_encoding = self .process_body (retval )
271
227
272
228
# Event Response object
273
229
event_rsp = EventResponseModel (time = datetime .utcnow ().strftime ("%Y-%m-%dT%H:%M:%S.%f" )[:- 3 ],
274
- status = status_code ,
275
- headers = resp_headers ,
230
+ status = retval . get ( 'statusCode' , 599 ) ,
231
+ headers = retval . get ( 'headers' , {}) ,
276
232
body = resp_body ,
277
233
transfer_encoding = resp_transfer_encoding )
278
234
@@ -291,24 +247,28 @@ def after(self, retval):
291
247
event_model = mask_event_model (event_model )
292
248
except :
293
249
if self .DEBUG :
294
- print ("Can not execute MASK_EVENT_MODEL function. Please check moesif settings." )
250
+ print ("MOESIF Can not execute MASK_EVENT_MODEL function. Please check moesif settings." )
295
251
296
252
# Skip Event
297
253
try :
298
254
skip_event = self .moesif_options .get ('SKIP' , None )
299
255
if skip_event is not None :
300
256
if skip_event (self .event , self .context ):
301
257
if self .DEBUG :
302
- print ('Skip sending event to Moesif' )
258
+ print ('MOESIF Skip sending event to Moesif' )
303
259
return retval
304
260
except :
305
261
if self .DEBUG :
306
- print ("Having difficulty executing skip_event function. Please check moesif settings." )
262
+ print ("MOESIF Having difficulty executing skip_event function. Please check moesif settings." )
307
263
308
264
# Send event to Moesif
265
+ if self .DEBUG :
266
+ print ('Moesif Event Model:' )
267
+ pprint (self .event )
268
+
309
269
event_send = self .api_client .create_event (event_model )
310
270
if self .DEBUG :
311
- print ('Event Sent successfully' )
271
+ print ('MOESIF ' + str ( event_send ) )
312
272
313
273
# Send response
314
274
return retval
0 commit comments