77from .client_ip import ClientIp
88from .update_companies import Company
99from .update_users import User
10+ from . import global_variable as gv
11+
1012from datetime import *
1113import base64
1214import json
1315import os
1416from pprint import pprint
1517import base64
18+
19+ import random
20+ import math
21+
1622try :
1723 from urllib import urlencode
1824except ImportError :
2430def get_time_took_in_ms (start_time , end_time ):
2531 return (end_time - start_time ).total_seconds () * 1000
2632
33+
2734def start_capture_outgoing (moesif_options ):
2835 try :
2936 if moesif_options .get ('DEBUG' , False ):
30- print ('Start capturing outgoing requests' )
37+ print ('[moesif] Start capturing outgoing requests' )
38+
3139 # Start capturing outgoing requests
3240 moesif_options ['APPLICATION_ID' ] = os .environ ["MOESIF_APPLICATION_ID" ]
3341 StartCapture ().start_capture_outgoing (moesif_options )
42+
43+ if moesif_options .get ('DEBUG' , False ):
44+ print ("[moesif] end capturing moesif options" )
3445 except Exception as e :
3546 print ('Error while starting to capture the outgoing events' )
3647 print (e )
48+ return
49+
3750
3851# Initialized the client
39- if os .environ ["MOESIF_APPLICATION_ID" ]:
40- api_client = MoesifAPIClient (os .environ ["MOESIF_APPLICATION_ID" ]).api
41- else :
42- raise Exception ('Moesif Application ID is required in settings' )
52+ api_client = gv .api_client
53+
4354
4455def update_user (user_profile , moesif_options ):
4556 User ().update_user (user_profile , api_client , moesif_options )
4657
58+
4759def update_users_batch (user_profiles , moesif_options ):
4860 User ().update_users_batch (user_profiles , api_client , moesif_options )
4961
62+
5063def update_company (company_profile , moesif_options ):
5164 Company ().update_company (company_profile , api_client , moesif_options )
5265
66+
5367def update_companies_batch (companies_profiles , moesif_options ):
5468 Company ().update_companies_batch (companies_profiles , api_client , moesif_options )
5569
@@ -70,12 +84,9 @@ def __init__(self, handler):
7084 self .event = None
7185 self .context = None
7286 self .payload_version = None
73-
74- # Intialized the client
75- if os .environ .get ("MOESIF_APPLICATION_ID" ):
76- self .api_client = MoesifAPIClient (os .environ ["MOESIF_APPLICATION_ID" ]).api
77- else :
78- raise Exception ('Moesif Application ID is required in settings' )
87+
88+ # Set the client
89+ self .api_client = api_client
7990
8091 def clear_state (self ):
8192 """Function to clear state of local variable"""
@@ -108,16 +119,16 @@ def get_user_id(self, event, context):
108119 username = rc_identity_id
109120 except :
110121 if self .DEBUG :
111- print ("MOESIF can not fetch apiKey from cognitoIdentityId event, setting userId to None." )
122+ print ("[moesif] can not fetch apiKey from cognitoIdentityId event, setting userId to None." )
112123 except Exception as e :
113124 if self .DEBUG :
114- print ("MOESIF can not execute identify_user function, please check moesif settings." )
125+ print ("[moesif] can not execute identify_user function, please check moesif settings." )
115126 print (e )
116127 end_time_get_user_id = datetime .utcnow ()
117128 if self .DEBUG :
118129 print ("[moesif] Time took in fetching user id in millisecond - " + str (get_time_took_in_ms (start_time_get_user_id , end_time_get_user_id )))
119130 return username
120-
131+
121132 def get_company_id (self , event , context ):
122133 """Function to fetch CompanyId"""
123134 start_time_get_company_id = datetime .utcnow ()
@@ -128,23 +139,23 @@ def get_company_id(self, event, context):
128139 company_id = identify_company (event , context )
129140 except Exception as e :
130141 if self .DEBUG :
131- print ("MOESIF can not execute identify_company function, please check moesif settings." )
142+ print ("[moesif] can not execute identify_company function, please check moesif settings." )
132143 print (e )
133144 end_time_get_company_id = datetime .utcnow ()
134145 if self .DEBUG :
135146 print ("[moesif] Time took in fetching company id in millisecond - " + str (get_time_took_in_ms (start_time_get_company_id , end_time_get_company_id )))
136147 return company_id
137-
148+
138149 def build_uri (self , event , payload_format_version_1_0 ):
139150
140- uri = event ['headers' ].get ('X-Forwarded-Proto' , event ['headers' ].get ('x-forwarded-proto' , 'http' )) + '://' + event ['headers' ].get ('Host' , event ['headers' ].get ('host' , 'localhost' ))
141-
151+ uri = event ['headers' ].get ('X-Forwarded-Proto' , event ['headers' ].get ('x-forwarded-proto' , 'http' )) + '://' + event ['headers' ].get ('Host' , event ['headers' ].get ('host' , 'localhost' ))
152+
142153 if payload_format_version_1_0 :
143154 uri = uri + event .get ('path' , '/' )
144155 if event .get ('multiValueQueryStringParameters' , {}):
145- uri = uri + '?' + urlencode (event ['multiValueQueryStringParameters' ], doseq = True )
156+ uri = uri + '?' + urlencode (event ['multiValueQueryStringParameters' ], doseq = True )
146157 elif event .get ('queryStringParameters' , {}):
147- uri = uri + '?' + urlencode (event ['queryStringParameters' ])
158+ uri = uri + '?' + urlencode (event ['queryStringParameters' ])
148159 else :
149160 uri = uri + event .get ('rawPath' , '/' )
150161 if event .get ('rawQueryString' , {}):
@@ -211,7 +222,7 @@ def before(self, event, context):
211222 else :
212223 request_verb = event .get ('requestContext' , {}).get ('http' , {}).get ('method' )
213224 if request_verb is None :
214- 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.' )
225+ 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.' )
215226 self .event = None
216227 self .context = None
217228 self .payload_version = None
@@ -224,23 +235,23 @@ def before(self, event, context):
224235 req_headers = APIHelper .json_deserialize (event ['headers' ])
225236 except Exception as e :
226237 if self .DEBUG :
227- print ('MOESIF Error while fetching request headers' )
238+ print ('[moesif] Error while fetching request headers' )
228239 print (e )
229240
230241 # Request Time
231242 if self .is_payload_format_version_1_0 (self .payload_version ):
232243 epoch = event and event .get ('requestContext' , {}).get ('requestTimeEpoch' )
233244 else :
234245 epoch = event and event .get ('requestContext' , {}).get ('timeEpoch' )
235- if epoch is not None :
246+ if epoch is not None :
236247 # Dividing by 1000 to convert from ms to seconds and `.0` to preserve millisecond precision
237248 request_time = datetime .utcfromtimestamp (epoch / 1000.0 )
238249 else :
239250 request_time = datetime .utcnow ()
240-
251+
241252 # Request Body
242253 req_body , req_transfer_encoding = self .process_body (event )
243-
254+
244255 # Metadata
245256 start_time_get_metadata = datetime .utcnow ()
246257 try :
@@ -258,15 +269,15 @@ def before(self, event, context):
258269 }
259270 except :
260271 if self .DEBUG :
261- print ("MOESIF can not fetch default function_name and request_context from aws context, setting metadata to None." )
272+ print ("[moesif] can not fetch default function_name and request_context from aws context, setting metadata to None." )
262273 except Exception as e :
263274 if self .DEBUG :
264- print ("MOESIF can not execute GET_METADATA function, please check moesif settings." )
275+ print ("[moesif] can not execute GET_METADATA function, please check moesif settings." )
265276 print (e )
266277 end_time_get_metadata = datetime .utcnow ()
267278 if self .DEBUG :
268279 print ("[moesif] Time took in fetching metadata in millisecond - " + str (get_time_took_in_ms (start_time_get_metadata , end_time_get_metadata )))
269-
280+
270281 # User Id
271282 start_time_identify_user = datetime .utcnow ()
272283 self .user_id = self .get_user_id (event , context )
@@ -294,10 +305,10 @@ def before(self, event, context):
294305 self .session_token = rc_api_key
295306 except KeyError :
296307 if self .DEBUG :
297- print ("MOESIF can not fetch apiKey from aws event, setting session_token to None." )
308+ print ("[moesif] can not fetch apiKey from aws event, setting session_token to None." )
298309 except Exception as e :
299310 if self .DEBUG :
300- print ("MOESIF can not execute GET_SESSION_TOKEN function, please check moesif settings." )
311+ print ("[moesif] can not execute GET_SESSION_TOKEN function, please check moesif settings." )
301312 print (e )
302313
303314 # Api Version
@@ -312,12 +323,12 @@ def before(self, event, context):
312323 api_version = context .function_version
313324 except KeyError :
314325 if self .DEBUG :
315- print ("MOESIF can not fetch default function_version from aws context, setting api_version to None." )
326+ print ("[moesif] can not fetch default function_version from aws context, setting api_version to None." )
316327 except Exception as e :
317328 if self .DEBUG :
318- print ("MOESIF can not execute GET_API_VERSION function, please check moesif settings." )
329+ print ("[moesif] can not execute GET_API_VERSION function, please check moesif settings." )
319330 print (e )
320-
331+
321332 # IpAddress
322333 if self .is_payload_format_version_1_0 (self .payload_version ):
323334 ip_address = event .get ('requestContext' , {}).get ('identity' , {}).get ('sourceIp' , None )
@@ -339,11 +350,12 @@ def before(self, event, context):
339350 print ("[moesif] Time took before the handler is invoked in millisecond - " + str (get_time_took_in_ms (start_time_before_handler_function , end_time_before_handler_function )))
340351 # Return event, context
341352 return event , context
342-
353+
343354 def after (self , retval ):
344355 """This function runs after the handler is invoked, is passed the response and must return an response too."""
345-
356+
346357 start_time_after_handler_function = datetime .utcnow ()
358+ event_send = None
347359 if self .event is not None :
348360 # Response body
349361 resp_body , resp_transfer_encoding = self .process_body (retval )
@@ -362,27 +374,27 @@ def after(self, retval):
362374 company_id = self .company_id ,
363375 session_token = self .session_token ,
364376 metadata = self .metadata )
365-
377+
366378 # Mask Event Model
367379 try :
368380 mask_event_model = self .moesif_options .get ('MASK_EVENT_MODEL' , None )
369381 if mask_event_model is not None :
370382 event_model = mask_event_model (event_model )
371- except :
383+ except Exception as e :
372384 if self .DEBUG :
373- print ("MOESIF Can not execute MASK_EVENT_MODEL function. Please check moesif settings." )
385+ print ("[moesif] Can not execute MASK_EVENT_MODEL function. Please check moesif settings." , e )
374386
375387 # Skip Event
376388 try :
377389 skip_event = self .moesif_options .get ('SKIP' , None )
378390 if skip_event is not None :
379391 if skip_event (self .event , self .context ):
380392 if self .DEBUG :
381- print ('MOESIF Skip sending event to Moesif' )
393+ print ('[moesif] Skip sending event to Moesif' )
382394 return retval
383- except :
395+ except Exception as e :
384396 if self .DEBUG :
385- print ("MOESIF Having difficulty executing skip_event function. Please check moesif settings." )
397+ print ("[moesif] Having difficulty executing skip_event function. Please check moesif settings." , e )
386398
387399 # Add direction field
388400 event_model .direction = "Incoming"
@@ -391,17 +403,56 @@ def after(self, retval):
391403 if self .DEBUG :
392404 print ('Moesif Event Model:' )
393405 print (json .dumps (self .event ))
394-
395- if self .DEBUG :
396- start_time_sending_event_w_rsp = datetime .utcnow ()
397- event_send = self .api_client .create_event (event_model )
398- end_time_sending_event_w_rsp = datetime .utcnow ()
399- if self .DEBUG :
400- print ("[moesif] Time took in sending event to moesif in millisecond - " + str (get_time_took_in_ms (start_time_sending_event_w_rsp , end_time_sending_event_w_rsp )))
401- print ('[moesif] Event Sent successfully ' + str (event_send ))
402- else :
403- self .api_client .create_event (event_model )
404-
406+
407+ # Sampling Rate
408+ try :
409+ random_percentage = random .random () * 100
410+ gv .sampling_percentage = gv .app_config .get_sampling_percentage (
411+ event_model ,
412+ gv .config ,
413+ self .user_id ,
414+ self .company_id ,
415+ )
416+
417+ if gv .sampling_percentage >= random_percentage :
418+ event_model .weight = 1 if gv .sampling_percentage == 0 else math .floor (
419+ 100 / gv .sampling_percentage )
420+
421+ if self .DEBUG :
422+ start_time_sending_event_w_rsp = datetime .utcnow ()
423+ event_send = self .api_client .create_event (event_model )
424+ end_time_sending_event_w_rsp = datetime .utcnow ()
425+ print ("[moesif] sampling_percentage" + str (
426+ gv .sampling_percentage ) + " and random percentage: " + str (random_percentage ))
427+ print ("[moesif] Time took in sending event to moesif in millisecond - " + str (
428+ get_time_took_in_ms (start_time_sending_event_w_rsp , end_time_sending_event_w_rsp )))
429+ print ('[moesif] Event Sent successfully ' + str (event_send ))
430+
431+ else :
432+ if datetime .utcnow () > gv .last_updated_time + timedelta (seconds = gv .refresh_config_time_seconds ):
433+ event_send = self .api_client .create_event (event_model )
434+ else :
435+ self .api_client .create_event (event_model )
436+
437+ try :
438+ # Check if we need to update config
439+ new_config_etag = event_send ['x-moesif-config-etag' ]
440+ if gv .config_etag is None or (gv .config_etag != new_config_etag ):
441+ gv .config_etag = new_config_etag
442+ gv .config = gv .app_config .get_config (self .api_client , self .DEBUG )
443+ except (KeyError , TypeError , ValueError ) as ex :
444+ # ignore the error because "event_send" is not set in non-blocking call
445+ pass
446+ finally :
447+ gv .last_updated_time = datetime .utcnow ()
448+
449+ else :
450+ if self .DEBUG :
451+ print ("Skipped Event due to sampling percentage: " + str (
452+ gv .sampling_percentage ) + " and random percentage: " + str (random_percentage ))
453+ except Exception as ex :
454+ print ("[moesif] Error when fetching sampling rate from app config" , ex )
455+
405456 end_time_after_handler_function = datetime .utcnow ()
406457 if self .DEBUG :
407458 print ("[moesif] Time took after the handler is invoked in millisecond - " + str (get_time_took_in_ms (start_time_after_handler_function , end_time_after_handler_function )))
0 commit comments