Ejemplo n.º 1
0
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
Ejemplo n.º 2
0
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"))
Ejemplo n.º 3
0
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)
Ejemplo n.º 4
0
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
Ejemplo n.º 5
0
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)
Ejemplo n.º 6
0
def resolve_graph_recipe(graph_identification: GraphIdentifier,
                         destination=None) -> Sequence[GraphRecipe]:
    return graph_identification_types.create_graph_recipes(
        graph_identification,
        destination=None,
    )