def bind_nodes(self, object_list, node_name="data"): """ For a list of Event objects, and a property name where we might find an (unfetched) NodeData on those objects, fetch all the data blobs for those NodeDatas with a single multi-get command to nodestore, and bind the returned blobs to the NodeDatas. It's not necessary to bind a single Event object since data will be lazily fetched on any attempt to access a property. """ with sentry_sdk.start_span(op="eventstore.base.bind_nodes"): object_node_list = [ (i, getattr(i, node_name)) for i in object_list if getattr(i, node_name).id ] # Remove duplicates from the list of nodes to be fetched node_ids = list({n.id for _, n in object_node_list}) if not node_ids: return node_results = nodestore.get_multi(node_ids) for item, node in object_node_list: data = node_results.get(node.id) or {} node.bind_data(data, ref=node.get_ref(item))
def bind_nodes(self, object_list, node_name="data"): """ For a list of Event objects, and a property name where we might find an (unfetched) NodeData on those objects, fetch all the data blobs for those NodeDatas with a single multi-get command to nodestore, and bind the returned blobs to the NodeDatas. It's not necessary to bind a single Event object since data will be lazily fetched on any attempt to access a property. """ # Temporarily make bind_nodes noop to prevent unnecessary additional calls # to nodestore by the event serializer. unfetched_object_list = [ i for i in object_list if not getattr(i, node_name)._node_data ] object_node_list = [(i, getattr(i, node_name)) for i in unfetched_object_list if getattr(i, node_name).id] node_ids = [n.id for _, n in object_node_list] if not node_ids: return node_results = nodestore.get_multi(node_ids) for item, node in object_node_list: data = node_results.get(node.id) or {} node.bind_data(data, ref=node.get_ref(item))
def _process_snuba_results(query_res, group: Group, user): event_ids = { row["latest_event_id"]: Event.generate_node_id(group.project_id, row["latest_event_id"]) for row in query_res } node_data = nodestore.get_multi(list(event_ids.values())) response = [] for row in query_res: response_item = { "hash": row["new_materialized_hash"], "eventCount": row["event_count"], } event_id = row["latest_event_id"] event_data = node_data.get(event_ids[event_id], None) if event_data is not None: event = Event(group.project_id, event_id, group_id=group.id, data=event_data) response_item["latestEvent"] = serialize(event, user, EventSerializer()) response.append(response_item) return response
def bind_nodes(self, object_list, *node_names): object_node_list = [] for name in node_names: object_node_list.extend(((i, getattr(i, name)) for i in object_list if getattr(i, name).id)) node_ids = [n.id for _, n in object_node_list] if not node_ids: return node_results = nodestore.get_multi(node_ids) for item, node in object_node_list: data = node_results.get(node.id) or {} node.bind_data(data, ref=node.get_ref(item))
def bind_nodes(self, object_list, *node_names): object_node_list = [] for name in node_names: object_node_list.extend( ((i, getattr(i, name)) for i in object_list if getattr(i, name).id) ) node_ids = [n.id for _, n in object_node_list] if not node_ids: return node_results = nodestore.get_multi(node_ids) for item, node in object_node_list: data = node_results.get(node.id) or {} node.bind_data(data, ref=node.get_ref(item))
def get(self, request: Request, organization) -> Response: """ Generate a list of data scrubbing selectors from existing event data. This list is used to auto-complete settings in "Data Scrubbing" / "Security and Privacy" settings. """ event_id = request.GET.get("eventId", None) # For organization settings we access all projects the user has access # to. For the project level, `get_projects` will give us back a single # project. # # Filtering by the projects that self.get_projects returns deals with # permission concerns. # # The org-wide search for the event ID is quite slow, but we cannot fix # that without product redesign. projects = self.get_projects(request, organization) project_ids = [project.id for project in projects] suggestions = {} if event_id: # go to nodestore directly instead of eventstore.get_events, which # would not return transaction events node_ids = [ Event.generate_node_id(p, event_id) for p in project_ids ] all_data = nodestore.get_multi(node_ids) for data in filter(None, all_data.values()): for selector in pii_selector_suggestions_from_event(data): examples_ = suggestions.setdefault(selector["path"], []) if selector["value"]: examples_.append(selector["value"]) return Response({ "suggestions": [{ "type": "value", "value": value, "examples": examples } for value, examples in suggestions.items()] })
def _process_snuba_results(query_res, group: Group, id: int, user): event_ids = { row["latest_event_id"]: Event.generate_node_id(group.project_id, row["latest_event_id"]) for row in query_res } node_data = nodestore.get_multi(list(event_ids.values())) response = [] for row in query_res: response_item = { "hash": row["new_materialized_hash"], "eventCount": row["event_count"], } event_id = row["latest_event_id"] event_data = node_data.get(event_ids[event_id], None) if event_data is not None: event = Event(group.project_id, event_id, group_id=group.id, data=event_data) response_item["latestEvent"] = serialize(event, user, EventSerializer()) tree_label = get_path( event_data, "hierarchical_tree_labels", id) or get_path( event_data, "hierarchical_tree_labels", -1) # Rough approximation of what happens with Group title event_type = get_event_type(event.data) metadata = dict(event.get_event_metadata()) metadata["current_tree_label"] = tree_label # Force rendering of grouping tree labels irrespective of platform metadata["display_title_with_tree_label"] = True title = event_type.get_title(metadata) response_item["title"] = title or event.title response_item["metadata"] = metadata response.append(response_item) return response
def bind_nodes(self, object_list, node_name='data'): """ For a list of Event objects, and a property name where we might find an (unfetched) NodeData on those objects, fetch all the data blobs for those NodeDatas with a single multi-get command to nodestore, and bind the returned blobs to the NodeDatas """ object_node_list = [(i, getattr(i, node_name)) for i in object_list if getattr(i, node_name).id] node_ids = [n.id for _, n in object_node_list] if not node_ids: return node_results = nodestore.get_multi(node_ids) for item, node in object_node_list: data = node_results.get(node.id) or {} node.bind_data(data, ref=node.get_ref(item))
def bind_nodes(self, object_list, *node_names): """ For a list of Event objects, and a property name where we might find an (unfetched) NodeData on those objects, fetch all the data blobs for those NodeDatas with a single multi-get command to nodestore, and bind the returned blobs to the NodeDatas """ object_node_list = [] for name in node_names: object_node_list.extend( ((i, getattr(i, name)) for i in object_list if getattr(i, name).id) ) node_ids = [n.id for _, n in object_node_list] if not node_ids: return node_results = nodestore.get_multi(node_ids) for item, node in object_node_list: data = node_results.get(node.id) or {} node.bind_data(data, ref=node.get_ref(item))