HealthCheckGetLargestInputsAndOutputsInIncidents
Returns inputs and outputs larger than 1 MB from all Cortex XSOAR investigations in the last 1 / 2 months.
python · System Diagnostics and Health Check
Source
import demistomock as demisto # noqa: F401 from CommonServerPython import * # noqa: F401 def get_investigations(raw_output, investigations): # in case getDBStatistics fails to fetch information it will return a message like so: # `Failed getting DB stats with filter [102020], minBytes [1000000]` - in this case there are no incidents to report if isinstance(raw_output, str): return for db in raw_output: buckets = db.get("buckets") for entry in buckets: if entry.startswith("investigations-"): investigations[entry] = buckets.get(entry) investigations[entry].update({"Date": db.get("dbName")}) def find_largest_input_or_output(all_args_list) -> dict: max_arg = {"Size(MB)": 0} for arg in all_args_list: if arg.get("Size(MB)") > max_arg.get("Size(MB)"): max_arg = arg return max_arg def get_largest_inputs_and_outputs(inputs_and_outputs, largest_inputs_and_outputs, incident_id) -> None: inputs = [] outputs = [] if inputs_and_outputs: # In case no inputs and outputs are found a getInvPlaybookMetaData will return a string. # in that case we ignore the results and move on. if isinstance(inputs_and_outputs, str): return for task in inputs_and_outputs: task_id = task.get("id") taskName = task.get("name") if "outputs" in task: for output in task.get("outputs"): size = float(output.get("size", 0)) outputs.append( { "IncidentID": f"{incident_id}", "Size(MB)": size, "Details": f"TaskName:{taskName},\nTaskID:{task_id},\nDirection: Output", } ) else: for arg in task.get("args"): argName = arg.get("name") size = float(arg.get("size", 0)) inputs.append( { "IncidentID": f"{incident_id}", "Size(MB)": size, "Details": f"TaskName: {taskName},\nTaskID:{task_id}, Argument Name: {argName},\nDirection: Input", } ) if inputs: largest_inputs_and_outputs.append(find_largest_input_or_output(inputs)) if outputs: largest_inputs_and_outputs.append(find_largest_input_or_output(outputs)) def get_extra_data_from_investigations(investigations: dict) -> list: largest_inputs_and_outputs: List = [] for inv in investigations: incident_id = inv.split("investigations-")[1] raw_output = execute_command( "getInvPlaybookMetaData", args={"incidentId": incident_id, "minSize": "1024"}, ) inputs_and_outputs = raw_output.get("tasks") get_largest_inputs_and_outputs(inputs_and_outputs, largest_inputs_and_outputs, incident_id) return largest_inputs_and_outputs def FormatTableAndSet(data): newFormat = [] for entry in data: newEntry = {} newEntry["incidentid"] = entry["IncidentID"] newEntry["size"] = FormatSize(entry["Size(MB)"]) newEntry["details"] = entry["Details"] newFormat.append(newEntry) return newFormat def FormatSize(size): power = 1000 n = 0 power_labels = {0: "KB", 1: "MB", 2: "GB"} while size > power: size /= power n += 1 if n == 2: break return f"{size:.2f} {power_labels[n]}" def main(): try: incident = demisto.incidents()[0] investigations: Dict = {} now = datetime.now() current_year = now.year current_month = now.month # Calculate previous month and handle year transition if current_month == 1: previous_month_year = current_year - 1 previous_month = 12 else: previous_month_year = current_year previous_month = current_month - 1 # Create a new date object for the previous month previous_month_date = datetime(previous_month_year, previous_month, 1) fromMonth = previous_month_date.strftime("%m%Y") toMonth = now.strftime("%m%Y") db_names = [fromMonth, toMonth] for db_name in db_names: raw_output = demisto.executeCommand("getDBStatistics", args={"filter": db_name}) get_investigations(raw_output[0].get("Contents", {}), investigations) data = get_extra_data_from_investigations(investigations) tableFormat = FormatTableAndSet(data) if incident.get("CustomFields").get("healthcheckinvestigationswithlargeinputoutput"): tableFormat.extend(incident.get("CustomFields").get("healthcheckinvestigationswithlargeinputoutput")) demisto.executeCommand("setIncident", {"healthcheckinvestigationswithlargeinputoutput": tableFormat}) actionableItems = [] incidentsList = [] incidentsListBiggerThan10 = [] for entry in data: if entry["Size(MB)"] > 10: incidentsListBiggerThan10.append(entry) else: incidentsList.append(entry) numIncidentsList = len(incidentsList) numIncidentsListBiggerThan10 = len(incidentsListBiggerThan10) DESCRIPTION = [ "incidents were found with large input and output, improve your task configuration", "incidents were found with very large input and output bigger than 10 MB, improve your task configuration", ] RESOLUTION = [ "Extending Context and Ignore Outputs: https://xsoar.pan.dev/docs/playbooks/playbooks-extend-context", ] if numIncidentsList >= 10: actionableItems.append( { "category": "DB analysis", "severity": "Medium", "description": f"{numIncidentsList} {DESCRIPTION[0]}", "resolution": RESOLUTION[0], } ) if numIncidentsListBiggerThan10 >= 1: actionableItems.append( { "category": "DB analysis", "severity": "High", "description": f"{numIncidentsListBiggerThan10} {DESCRIPTION[1]}", "resolution": RESOLUTION[0], } ) results = CommandResults(outputs_prefix="dbstatactionableitems", outputs=actionableItems) return_results(results) except Exception as exc: return_error(f"Failed to execute GetLargestInputsAndOutputsInIncidents.\nError: {exc}", error=exc) if __name__ in ("__main__", "__builtin__", "builtins"): main()