def __init__(self, time_units: str = 'ms', time_threshold_ms: int = 1, success_statuses: dict = [200]): """ :param time_units: time representation fixed in the units (see names in bombard.pretty_ns) :param time_threshold_ms: show times bigger than that in red :param success_statuses: dict of statuses treated as success """ self.DIMENSIONS = { TIME: { 'type': ARRAY_UINT64, 'pretty_func': self.pretty_time }, # time in ns up to 200 000 days. SIZE: { 'type': ARRAY_UINT32, 'pretty_func': pretty_sz }, # sizes up to 4 Gbytes } self.STAT_DEFAULT = { name: array(params['type']) for name, params in self.DIMENSIONS.items() } self.start_ns = time_ns() self.time_units = time_units self.time_threshold_ns = time_threshold_ms * 10**6 self.ok = success_statuses self.stat = {} # stat[request type][status]
def format(self, record: Any) -> str: record.threadid = thread_data.thread_id record.requestid = str(thread_data.request_id).rjust(4) record.colour = thread_data.colour record.requestname = thread_data.request_name record.dir = thread_data.dir record.elapsed = (pretty_ns(time_ns() - thread_data.start) if thread_data.start is not None else "") return super().format(record)
def sending(thread_id, request_id, request_name): """ Start sending request """ thread_data.thread_id = thread_id thread_data.request_id = request_id thread_data.request_name = request_name thread_data.dir = '>' * 3 thread_data.colour = GRAY thread_data.start = time_ns()
def sending(thread_id: int, request_id: str, request_name: str) -> None: """ Start sending request """ thread_data.thread_id = thread_id thread_data.request_id = request_id thread_data.request_name = request_name thread_data.dir = ">" * 3 thread_data.colour = GRAY thread_data.start = time_ns()
def worker(self, thread_id: int, job: Dict[str, Any]) -> None: """ Thread callable. Strike ammo from queue. """ try: # setup logging ASAP and as safe as possible if isinstance(job, dict): request = job.get("request", {}) ammo_id = job.get("id", "") ammo_name = request.get("name", "") else: request = {} ammo_id = None ammo_name = None request_logging.sending(thread_id, ammo_id, ammo_name) pretty_url = "" # we use it in `except` try: job = apply_supply_dict(job, dict(self.supply, **job["supply"])) url = request.get("url", "") method = request["method"] if "method" in request else "GET" body = json.dumps( request["body"]) if "body" in request else None headers = self.get_headers(request, body is not None) pretty_url = self.beautify_url(url, method, body) log.debug( # pylint: disable=logging-not-lazy f"Bomb to drop:\n{pretty_url}" + ("\n{body}" if body is not None else "")) if self.args.quiet and ammo_id in self.show_request: print( f"{self.show_request[ammo_id].format(id=ammo_id):>15}\r", end="") log.info(pretty_url) start_ns = time_ns() status: Union[str, int] if self.args.dry: status, resp = list(self.ok)[0], json.dumps( request.get("dry")) else: status, resp = http_request(url, method, headers, body, self.args.timeout) request_logging.receiving() self.process_resp(job, status, resp, time_ns() - start_ns, len(resp)) self.resp_count += 1 if self.args.quiet and self.resp_count in self.show_response: print( f"{self.show_response[self.resp_count].format(id=self.resp_count):>15}\r", end="", ) log.info( self.status_coloured(status) + f" ({pretty_sz(len(resp))}) " + pretty_url + " " + (red(resp) if status == EXCEPTION_STATUS else "")) except Exception as e: log.info( # pylint: disable=logging-not-lazy pretty_url + " " + red(str(e)), exc_info=True) finally: request_logging.main_thread()
def total_elapsed_ns(self): return time_ns() - self.start_ns