42
42
TimeWindowSizeClass ,
43
43
_Aspect as AspectAbstract ,
44
44
)
45
+ from datahub .utilities .lossy_collections import LossySet
45
46
46
47
logger = logging .getLogger (__name__ )
47
48
@@ -170,7 +171,7 @@ def __init__(
170
171
self .config = config
171
172
self .looker_models = looker_models
172
173
# Later it will help to find out for what are the looker entities from query result
173
- self .id_vs_model : Dict [str , ModelForUsage ] = {
174
+ self .id_to_model : Dict [str , ModelForUsage ] = {
174
175
self .get_id (looker_object ): looker_object for looker_object in looker_models
175
176
}
176
177
self .post_filter = len (self .looker_models ) > 100
@@ -225,6 +226,10 @@ def get_id(self, looker_object: ModelForUsage) -> str:
225
226
def get_id_from_row (self , row : dict ) -> str :
226
227
pass
227
228
229
+ @abstractmethod
230
+ def report_skip_set (self ) -> LossySet [str ]:
231
+ pass
232
+
228
233
def create_mcp (
229
234
self , model : ModelForUsage , aspect : Aspect
230
235
) -> MetadataChangeProposalWrapper :
@@ -258,20 +263,11 @@ def _process_entity_timeseries_rows(
258
263
259
264
return entity_stat_aspect
260
265
261
- def _process_absolute_aspect (self ) -> List [Tuple [ModelForUsage , AspectAbstract ]]:
262
- aspects : List [Tuple [ModelForUsage , AspectAbstract ]] = []
263
- for looker_object in self .looker_models :
264
- aspects .append (
265
- (looker_object , self .to_entity_absolute_stat_aspect (looker_object ))
266
- )
267
-
268
- return aspects
269
-
270
266
def _fill_user_stat_aspect (
271
267
self ,
272
268
entity_usage_stat : Dict [Tuple [str , str ], Aspect ],
273
269
user_wise_rows : List [Dict ],
274
- ) -> Iterable [Tuple [ModelForUsage , Aspect ]]:
270
+ ) -> Iterable [Tuple [str , Aspect ]]:
275
271
logger .debug ("Entering fill user stat aspect" )
276
272
277
273
# We first resolve all the users using a threadpool to warm up the cache
@@ -300,7 +296,7 @@ def _fill_user_stat_aspect(
300
296
301
297
for row in user_wise_rows :
302
298
# Confirm looker object was given for stat generation
303
- looker_object = self .id_vs_model .get (self .get_id_from_row (row ))
299
+ looker_object = self .id_to_model .get (self .get_id_from_row (row ))
304
300
if looker_object is None :
305
301
logger .warning (
306
302
"Looker object with id({}) was not register with stat generator" .format (
@@ -338,7 +334,7 @@ def _fill_user_stat_aspect(
338
334
logger .debug ("Starting to yield answers for user-wise counts" )
339
335
340
336
for (id , _ ), aspect in entity_usage_stat .items ():
341
- yield self . id_vs_model [ id ] , aspect
337
+ yield id , aspect
342
338
343
339
def _execute_query (self , query : LookerQuery , query_name : str ) -> List [Dict ]:
344
340
rows = []
@@ -357,7 +353,7 @@ def _execute_query(self, query: LookerQuery, query_name: str) -> List[Dict]:
357
353
)
358
354
if self .post_filter :
359
355
logger .debug ("post filtering" )
360
- rows = [r for r in rows if self .get_id_from_row (r ) in self .id_vs_model ]
356
+ rows = [r for r in rows if self .get_id_from_row (r ) in self .id_to_model ]
361
357
logger .debug ("Filtered down to %d rows" , len (rows ))
362
358
except Exception as e :
363
359
logger .warning (f"Failed to execute { query_name } query: { e } " )
@@ -378,7 +374,8 @@ def generate_usage_stat_mcps(self) -> Iterable[MetadataChangeProposalWrapper]:
378
374
return
379
375
380
376
# yield absolute stat for looker entities
381
- for looker_object , aspect in self ._process_absolute_aspect (): # type: ignore
377
+ for looker_object in self .looker_models :
378
+ aspect = self .to_entity_absolute_stat_aspect (looker_object )
382
379
yield self .create_mcp (looker_object , aspect )
383
380
384
381
# Execute query and process the raw json which contains stat information
@@ -399,10 +396,13 @@ def generate_usage_stat_mcps(self) -> Iterable[MetadataChangeProposalWrapper]:
399
396
)
400
397
user_wise_rows = self ._execute_query (user_wise_query_with_filters , "user_query" )
401
398
# yield absolute stat for entity
402
- for looker_object , aspect in self ._fill_user_stat_aspect (
399
+ for object_id , aspect in self ._fill_user_stat_aspect (
403
400
entity_usage_stat , user_wise_rows
404
401
):
405
- yield self .create_mcp (looker_object , aspect )
402
+ if object_id in self .id_to_model :
403
+ yield self .create_mcp (self .id_to_model [object_id ], aspect )
404
+ else :
405
+ self .report_skip_set ().add (object_id )
406
406
407
407
408
408
class DashboardStatGenerator (BaseStatGenerator ):
@@ -425,6 +425,9 @@ def __init__(
425
425
def get_stats_generator_name (self ) -> str :
426
426
return "DashboardStats"
427
427
428
+ def report_skip_set (self ) -> LossySet [str ]:
429
+ return self .report .dashboards_skipped_for_usage
430
+
428
431
def get_filter (self ) -> Dict [ViewField , str ]:
429
432
return {
430
433
HistoryViewField .HISTORY_DASHBOARD_ID : "," .join (
@@ -541,6 +544,9 @@ def __init__(
541
544
def get_stats_generator_name (self ) -> str :
542
545
return "ChartStats"
543
546
547
+ def report_skip_set (self ) -> LossySet [str ]:
548
+ return self .report .charts_skipped_for_usage
549
+
544
550
def get_filter (self ) -> Dict [ViewField , str ]:
545
551
return {
546
552
LookViewField .LOOK_ID : "," .join (
0 commit comments