Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Build stage
FROM python:3.11-slim as builder

Check warning on line 2 in Dockerfile

View workflow job for this annotation

GitHub Actions / build

The 'as' keyword should match the case of the 'from' keyword

FromAsCasing: 'as' and 'FROM' keywords' casing do not match More info: https://docs.docker.com/go/dockerfile/rule/from-as-casing/
ENV PATH="/root/.local/bin/:$PATH"

RUN apt-get update \
Expand Down Expand Up @@ -63,7 +63,8 @@
ENV PYTHONUNBUFFERED=1
ENV VIRTUAL_ENV=/app/venv
ENV PATH="/venv/bin:$PATH"
ENV PYTHONPATH=$PYTHONPATH:.:/app/src

Check warning on line 66 in Dockerfile

View workflow job for this annotation

GitHub Actions / build

Variables should be defined before their use

UndefinedVar: Usage of undefined variable '$PYTHONPATH' More info: https://docs.docker.com/go/dockerfile/rule/undefined-var/
ENV MPLBACKEND=Agg

WORKDIR /app

Expand Down
2 changes: 1 addition & 1 deletion playbooks/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ include_trailing_comma = true
python = "^3.7.1"
Flask = "^2.0.2"
prometheus-api-client = "^0.5.4"
pygal = "^3.0.0"
matplotlib = "^3.10.8"
tinycss = "^0.4"
cssselect = "^1.1.0"
rsa = "^4.8"
Expand Down
8 changes: 4 additions & 4 deletions playbooks/robusta_playbooks/node_cpu_analysis.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import logging
import textwrap

import pygal

from robusta.api import (
FLOAT_PRECISION_LIMIT,
BarChart,
DividerBlock,
FileBlock,
HeaderBlock,
Expand All @@ -13,6 +12,7 @@
NodeCpuAnalyzer,
NodeEvent,
PrometheusParams,
TreemapChart,
action,
charts_style,
)
Expand Down Expand Up @@ -41,7 +41,7 @@ def node_cpu_enricher(event: NodeEvent, params: PrometheusParams):
per_pod_request = analyzer.get_per_pod_cpu_request()
all_pod_names = list(set(per_pod_usage_unbounded.keys()).union(per_pod_request.keys()))

treemap = pygal.Treemap(style=charts_style())
treemap = TreemapChart(style=charts_style())
treemap.title = f"CPU Usage on Node {node.metadata.name}"
treemap.value_formatter = lambda x: f"{int(x * 100)}%"
treemap.add("Non-container usage", [non_container_cpu_usage])
Expand All @@ -50,7 +50,7 @@ def node_cpu_enricher(event: NodeEvent, params: PrometheusParams):
treemap.add(pod_name, [cpu_usage])

MISSING_VALUE = -0.001
bar_chart = pygal.Bar(x_label_rotation=-40, style=charts_style())
bar_chart = BarChart(x_label_rotation=-40, style=charts_style())
bar_chart.title = f"Actual Vs Requested vCPUs on Node {node.metadata.name}"
bar_chart.x_labels = all_pod_names
bar_chart.value_formatter = lambda x: f"{x:.2f} vCPU" if x != MISSING_VALUE else "no data"
Expand Down
46 changes: 1 addition & 45 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,10 @@ datadog-api-client = { version = "^1.2.0", optional = true }
dpath = "^2.0.5"
websocket-client = "1.3.3"
prometheus-client = "^0.12.0"
pygal = "^3.0.0"
# Chart renderer for Prometheus/resource graphs (PSF-based permissive license;
# replaced LGPL-licensed pygal). Already present transitively via
# prometheus-api-client, so this adds no new packages to the image.
matplotlib = "^3.10.8"
pyyaml = "^6.0"
pytz = "^2021.3"
poetry-core = "1.1.0a7"
Expand Down
1 change: 1 addition & 0 deletions src/robusta/api/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@
ScanType,
SlackAnnotations,
)
from robusta.core.reporting.charts import BarChart, ChartStyle, TreemapChart, XYChart
from robusta.core.reporting.custom_rendering import RendererType, charts_style, render_value
from robusta.core.reporting.finding_subjects import KubeObjFindingSubject, PodFindingSubject
from robusta.core.reporting.holmes import HolmesRequest, HolmesResult, HolmesResultsBlock
Expand Down
30 changes: 9 additions & 21 deletions src/robusta/core/playbooks/prometheus_enrichment_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
from typing import Any, Callable, Dict, List, Optional, Tuple, Union

import humanize
import pygal
from hikaru.model.rel_1_26 import Node
from prometrix import PrometheusQueryResult
from pydantic import BaseModel
Expand All @@ -19,7 +18,8 @@
)
from robusta.core.model.env_vars import FLOAT_PRECISION_LIMIT, PROMETHEUS_REQUEST_TIMEOUT_SECONDS
from robusta.core.reporting.blocks import GraphBlock, PrometheusBlock, PrometheusBlockLineData
from robusta.core.reporting.custom_rendering import PlotCustomCSS, charts_style
from robusta.core.reporting.charts import XYChart
from robusta.core.reporting.custom_rendering import charts_style
from robusta.integrations.prometheus.utils import get_prometheus_connect

ResourceKey = Tuple[ResourceChartResourceType, ResourceChartItemType]
Expand Down Expand Up @@ -162,7 +162,7 @@ def create_chart_from_prometheus_query(
filter_prom_jobs: bool = False,
hide_legends: Optional[bool] = False,
metrics_legends_labels: Optional[List[str]] = None,
) -> Tuple[pygal.Graph, PrometheusBlock]:
) -> Tuple[XYChart, PrometheusBlock]:
starts_at: datetime
ends_at: datetime
if not alert_starts_at:
Expand Down Expand Up @@ -197,7 +197,8 @@ def create_chart_from_prometheus_query(
f"Unsupported query result for robusta chart, Type received: {prometheus_query_result.result_type}, type supported 'matrix'"
)

# fix a pygal bug which causes infinite loops due to rounding errors with floating points
# sentinels for the min/max scan below; HIGHEST_END is a timestamp far past
# any real sample, so the first data point always replaces it
# TODO: change min_time time before Jan 19 3001
HIGHEST_END = 32536799999
LOWEST_START = 0
Expand Down Expand Up @@ -298,15 +299,9 @@ def create_chart_from_prometheus_query(

graph_plot_color_list = [plot_data.color for plot_data in plot_data_list]
graph_plot_color_list.extend(["#1e0047", "#2a0065"])
config = pygal.Config()
custom_css = PlotCustomCSS().get_css_file_path()
config.css.append(f"file://{custom_css}")
chart = pygal.XY(
config,
show_dots=True,
chart = XYChart(
style=charts_style(graph_colors=tuple(graph_plot_color_list)),
truncate_legend=15,
include_x_axis=include_x_axis,
width=1280,
height=500,
show_legend=hide_legends is not True,
Expand All @@ -328,7 +323,7 @@ def create_chart_from_prometheus_query(

# Fix for the case when the request and limit has the same value.
# 6 pixels where chosen as minimum distance based on current width and height of the slack graph
delta = (chart.range[1] - chart.range[0]) * 6 / chart.config.height
delta = (chart.range[1] - chart.range[0]) * 6 / chart.height
# Limit delta to a maximum of 2% of the Y-axis range (to prefent significant deviation)
delta = min(delta, (chart.range[1] - chart.range[0]) * 0.02)

Expand Down Expand Up @@ -405,7 +400,7 @@ def build_chart_from_prometheus_result(
prometheus_query_result: PrometheusQueryResult,
chart_title: Optional[str] = "Prometheus Chart",
values_format: Optional[ChartValuesFormat] = None,
) -> pygal.Graph:
) -> XYChart:
if prometheus_query_result.result_type != "matrix":
raise ValueError(f"Expected 'matrix' result_type, got '{prometheus_query_result.result_type}'")

Expand Down Expand Up @@ -475,19 +470,12 @@ def build_chart_from_prometheus_result(
if min_time == HIGHEST_END:
raise ValueError("No valid data points found in time series.")

config = pygal.Config()
custom_css = PlotCustomCSS().get_css_file_path()
config.css.append(f"file://{custom_css}")

graph_colors = [plot_data.color for plot_data in plot_data_list]
graph_colors.extend(["#1e0047", "#2a0065"])

chart = pygal.XY(
config,
show_dots=True,
chart = XYChart(
style=charts_style(graph_colors=tuple(graph_colors)),
truncate_legend=15,
include_x_axis=True,
width=1280,
height=500,
show_legend=True,
Expand Down
Loading
Loading