def _answer_graph_image_request() -> None: try: host_name = request.var("host") if not host_name: raise MKGeneralException(_("Missing mandatory \"host\" parameter")) service_description = request.var("service", "_HOST_") site = request.var("site") # FIXME: We should really enforce site here. But it seems that the notification context # has no idea about the site of the host. This could be optimized later. #if not site: # raise MKGeneralException("Missing mandatory \"site\" parameter") try: row = get_graph_data_from_livestatus(site, host_name, service_description) except livestatus.MKLivestatusNotFoundError: if config.debug: raise raise Exception( _("Cannot render graph: host %s, service %s not found.") % (host_name, service_description)) site = row["site"] # Always use 25h graph in notifications end_time = time.time() start_time = end_time - (25 * 3600) graph_render_options = graph_image_render_options() graph_identification = ( "template", { "site": site, "host_name": host_name, "service_description": service_description, "graph_index": None, # all graphs }) graph_data_range = graph_image_data_range(graph_render_options, start_time, end_time) graph_recipes = graph_identification_types.create_graph_recipes( graph_identification, destination=html_render.GraphDestinations.notification) num_graphs = request.get_integer_input("num_graphs") or len(graph_recipes) graphs = [] for graph_recipe in graph_recipes[:num_graphs]: graph_artwork = artwork.compute_graph_artwork(graph_recipe, graph_data_range, graph_render_options) graph_png = render_graph_image(graph_artwork, graph_data_range, graph_render_options) graphs.append(base64.b64encode(graph_png).decode("ascii")) response.set_data(json.dumps(graphs)) except Exception as e: logger.error("Call to ajax_graph_images.py failed: %s\n%s", e, traceback.format_exc()) if config.debug: raise
def resolve_graph_recipe(graph_identification, destination=None): try: return graph_identification_types.create_graph_recipes(graph_identification, destination=None) except livestatus.MKLivestatusNotFoundError: return render_graph_error_html( "%s\n\n%s: %r" % (_("Cannot fetch data via Livestatus"), _("The graph specification is"), graph_identification), _("Cannot calculate graph recipes")) except Exception as e: return render_graph_error_html(e, _("Cannot calculate graph recipes"))
def render_graphs_from_specification_html(graph_identification, graph_data_range, graph_render_options, render_async=True): try: graph_recipes = graph_identification_types.create_graph_recipes(graph_identification) except livestatus.MKLivestatusNotFoundError: return render_graph_error_html( "%s\n\n%s: %r" % (_("Cannot fetch data via Livestatus"), _("The graph specification is"), graph_identification), _("Cannot calculate graph recipes")) except Exception as e: return render_graph_error_html(e, _("Cannot calculate graph recipes")) return render_graphs_from_definitions(graph_recipes, graph_data_range, graph_render_options, render_async)
def graph_recipes_for_api_request(request): # Get and validate the specification graph_identification = request.get("specification", []) if not graph_identification: raise MKUserError(None, _("The graph specification is missing")) if len(graph_identification) != 2: raise MKUserError(None, _("Invalid graph specification given")) graph_identification_types.verify(graph_identification[0]) # Default to 25h view default_time_range = (time.time() - (25 * 3600), time.time()) # Get and validate the data range graph_data_range = request.get("data_range", {}) graph_data_range.setdefault("time_range", default_time_range) time_range = graph_data_range["time_range"] if not time_range or len(time_range) != 2: raise MKUserError(None, _("The graph data range is wrong or missing")) try: float(time_range[0]) except ValueError: raise MKUserError(None, _("Invalid start time given")) try: float(time_range[1]) except ValueError: raise MKUserError(None, _("Invalid end time given")) graph_data_range["step"] = 60 try: graph_recipes = graph_identification_types.create_graph_recipes( graph_identification) except livestatus.MKLivestatusNotFoundError as e: raise MKUserError(None, _("Cannot calculate graph recipes: %s") % e) if request.get("consolidation_function"): for graph_recipe in graph_recipes: graph_recipe["consolidation_function"] = request.get( "consolidation_function") return graph_data_range, graph_recipes
def host_service_graph_dashlet_cmk(graph_identification, custom_graph_render_options): graph_render_options = default_dashlet_graph_render_options.copy() graph_render_options = artwork.add_default_render_options( graph_render_options) graph_render_options.update(custom_graph_render_options) width_var = html.request.get_float_input_mandatory("width", 0.0) width = int((width_var / html_size_per_ex)) height_var = html.request.get_float_input_mandatory("height", 0.0) height = int((height_var / html_size_per_ex)) bounds = _graph_margin_ex(graph_render_options) height -= _graph_title_height_ex(graph_render_options) height -= bounds.top + bounds.bottom width -= bounds.left + bounds.right graph_render_options["size"] = (width, height) # The timerange is specified in PNP like manner. range_secs = { "0": 4 * 3600, "1": 25 * 3600, "2": 7 * 86400, "3": 31 * 86400, "4": 366 * 86400, } secs_var = html.request.var("timerange") if secs_var not in range_secs: secs = 4 * 3600 else: secs = range_secs[secs_var] end_time = time.time() start_time = end_time - secs graph_data_range = { "time_range": (start_time, end_time), } graph_data_range["step"] = estimate_graph_step_for_html( graph_data_range["time_range"], graph_render_options) try: graph_recipes = graph_identification_types.create_graph_recipes( graph_identification, destination=GraphDestinations.dashlet) if graph_recipes: graph_recipe = graph_recipes[0] else: raise MKGeneralException(_("Failed to calculate a graph recipe.")) except livestatus.MKLivestatusNotFoundError: html.div(_("Cannot render graphs: cannot fetch data via Livestatus"), class_="error") return # When the legend is enabled, we need to reduce the height by the height of the legend to # make the graph fit into the dashlet area. if graph_render_options["show_legend"]: # TODO FIXME: This graph artwork is calulated twice. Once here and once in render_graphs_from_specification_html() graph_artwork = artwork.compute_graph_artwork(graph_recipe, graph_data_range, graph_render_options) if graph_artwork["curves"]: legend_height = graph_legend_height_ex(graph_render_options, graph_artwork) graph_render_options["size"] = (width, height - legend_height) html_code = render_graphs_from_definitions([graph_recipe], graph_data_range, graph_render_options, render_async=False) html.write(html_code)
def resolve_graph_recipe(graph_identification: GraphIdentifier, destination=None) -> Sequence[GraphRecipe]: return graph_identification_types.create_graph_recipes( graph_identification, destination=None, )