Skip to content

Commit 06e1f90

Browse files
Introduce functions for executing PromQL instant and range queries towards the Monitor Promehteus endpoints.
1 parent 9d18376 commit 06e1f90

File tree

5 files changed

+612
-0
lines changed

5 files changed

+612
-0
lines changed
Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
#!/usr/bin/env python
2+
#
3+
# This script shows the basics of getting data out of Sysdig Monitor by executing a PromQL query
4+
# that returns the top 5 Kubernetes workloads consuming the highest percentage of their allocated CPU
5+
# by comparing actual usage to defined CPU limits. The query is executed over a 5-minute time window.
6+
#
7+
8+
import sys
9+
import time
10+
from datetime import datetime
11+
12+
from sdcclient import SdcClient
13+
14+
def print_prometheus_results_as_table(results):
15+
if not results:
16+
print("No data found for the query.")
17+
return
18+
19+
# Store time series data
20+
all_timestamps = set()
21+
label_keys = []
22+
time_series_by_label = {}
23+
24+
for series in results:
25+
metric = series.get("metric", {})
26+
label = ','.join(f'{k}={v}' for k, v in sorted(metric.items()))
27+
label_keys.append(label)
28+
time_series_by_label[label] = {}
29+
30+
for timestamp, value in series.get("values", []):
31+
ts = int(float(timestamp))
32+
all_timestamps.add(ts)
33+
time_series_by_label[label][ts] = value
34+
35+
# Prepare header
36+
label_keys = sorted(set(label_keys))
37+
all_timestamps = sorted(all_timestamps)
38+
39+
print(f"{'Timestamp':<25} | " + " | ".join(f"{label}" for label in label_keys))
40+
print("-" * (26 + len(label_keys) * 25))
41+
42+
# Print each row, filling in missing values with "N/A"
43+
for ts in all_timestamps:
44+
dt = datetime.fromtimestamp(ts).isoformat()
45+
row_values = []
46+
for label in label_keys:
47+
value = time_series_by_label.get(label, {}).get(ts, "N/A")
48+
row_values.append(value)
49+
print(f"{dt:<25} | " + " | ".join(f"{val:>20}" for val in row_values))
50+
51+
#
52+
# Parse arguments
53+
#
54+
if len(sys.argv) != 3:
55+
print(('usage: %s <sysdig-token> <hostname>' % sys.argv[0]))
56+
print('You can find your token at https://app.sysdigcloud.com/#/settings/user')
57+
sys.exit(1)
58+
59+
sdc_token = sys.argv[1]
60+
hostname = sys.argv[2]
61+
62+
sdclient = SdcClient(sdc_token, hostname)
63+
64+
#
65+
# A PromQL query to execute. The query retrieves the top 5 workloads in a specific Kubernetes
66+
# cluster that are using the highest percentage of their allocated CPU resources. It calculates
67+
# this by comparing the actual CPU usage of each workload to the CPU limits set for them and
68+
# then ranks the results to show the top 5.
69+
#
70+
query = '''
71+
topk (5,
72+
sum by (kube_cluster_name, kube_namespace_name, kube_workload_name) (
73+
rate(
74+
sysdig_container_cpu_cores_used{
75+
kube_cluster_name="dev-cluster"
76+
}[10m]
77+
)
78+
)
79+
/
80+
sum by (kube_cluster_name, kube_namespace_name, kube_workload_name) (
81+
kube_pod_container_resource_limits{
82+
kube_cluster_name="dev-cluster",
83+
resource="cpu"
84+
}
85+
)
86+
)
87+
'''
88+
89+
#
90+
# Time window:
91+
# - end is the current time
92+
# - start is the current time minus 5 minutes
93+
#
94+
end = int(time.time())
95+
start = end - 5*60 # 5 minutes ago
96+
97+
#
98+
# Step:
99+
# - resolution step, how far should timestamp of each resulting sample be apart
100+
#
101+
step = 60
102+
103+
#
104+
# Load data
105+
#
106+
ok, response_json = sdclient.get_data_promql(query, start, end, step)
107+
108+
#
109+
# Show the result
110+
#
111+
if ok:
112+
#
113+
# Read response. The JSON looks like this:
114+
#
115+
# {
116+
# "data": {
117+
# "result": [
118+
# {
119+
# "metric": {},
120+
# "values": [
121+
# [
122+
# 1744210080,
123+
# "0.58"
124+
# ],
125+
# [
126+
# 1744210140,
127+
# "0.58"
128+
# ],
129+
# [
130+
# 1744210200,
131+
# "0.58"
132+
# ],
133+
# [
134+
# 1744210260,
135+
# "0.5799999999999998"
136+
# ],
137+
# [
138+
# 1744210320,
139+
# "0.5799999999999998"
140+
# ],
141+
# [
142+
# 1744210380,
143+
# "0.5799999999999998"
144+
# ]
145+
# ]
146+
# }
147+
# ],
148+
# "resultType": "matrix"
149+
# },
150+
# "status": "success"
151+
# }
152+
#
153+
154+
155+
#
156+
# Print summary (what, when)
157+
#
158+
results = response_json.get("data", {}).get("result", [])
159+
print_prometheus_results_as_table(results)
160+
161+
else:
162+
print(response_json)
163+
sys.exit(1)
164+
165+
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
#!/usr/bin/env python
2+
#
3+
# This script shows the basics of getting data out of Sysdig Monitor by executing a PromQL query
4+
# that returns the top 5 Kubernetes workloads consuming the highest percentage of their allocated CPU
5+
# by comparing actual usage to defined CPU limits. The query is executed at a timestamp 5 minutes ago.
6+
#
7+
8+
import sys
9+
import time
10+
from datetime import datetime
11+
12+
from sdcclient import SdcClient
13+
14+
def print_prometheus_instant_result(result):
15+
if not result:
16+
print("No data found for the instant query.")
17+
return
18+
19+
# Determine if any result has labels
20+
has_labels = any(entry.get("metric") for entry in result)
21+
22+
if has_labels:
23+
print(f"{'Timestamp':<25} | {'Metric':<40} | {'Value':>10}")
24+
print("-" * 80)
25+
else:
26+
print(f"{'Timestamp':<25} | {'Value':>10}")
27+
print("-" * 40)
28+
29+
for entry in result:
30+
timestamp, value = entry.get("value", [None, None])
31+
dt = datetime.fromtimestamp(float(timestamp)).isoformat() if timestamp else "N/A"
32+
metric = entry.get("metric", {})
33+
34+
if has_labels:
35+
label_str = ', '.join(f'{k}="{v}"' for k, v in sorted(metric.items()))
36+
print(f"{dt:<25} | {label_str:<40} | {value:>10}")
37+
else:
38+
print(f"{dt:<25} | {value:>10}")
39+
40+
#
41+
# Parse arguments
42+
#
43+
if len(sys.argv) != 3:
44+
print(('usage: %s <sysdig-token> <hostname>' % sys.argv[0]))
45+
print('You can find your token at https://app.sysdigcloud.com/#/settings/user')
46+
sys.exit(1)
47+
48+
sdc_token = sys.argv[1]
49+
hostname = sys.argv[2]
50+
51+
sdclient = SdcClient(sdc_token, hostname)
52+
53+
#
54+
# A PromQL query to execute. The query retrieves the top 5 workloads in a specific Kubernetes
55+
# cluster that are using the highest percentage of their allocated CPU resources. It calculates
56+
# this by comparing the actual CPU usage of each workload to the CPU limits set for them and
57+
# then ranks the results to show the top 5.
58+
#
59+
query = '''
60+
topk(5,
61+
sum by (kube_cluster_name, kube_namespace_name, kube_workload_name) (
62+
rate(
63+
sysdig_container_cpu_cores_used{
64+
kube_cluster_name="dev-cluster"
65+
}[10m]
66+
)
67+
)
68+
/
69+
sum by (kube_cluster_name, kube_namespace_name, kube_workload_name) (
70+
kube_pod_container_resource_limits{
71+
kube_cluster_name="dev-cluster",
72+
resource="cpu"
73+
}
74+
)
75+
)
76+
'''
77+
78+
#
79+
# Time:
80+
# - the parameter is optional; if not set, the current time is used
81+
#
82+
time = int(time.time()) - 5*60 # 5 minutes ago
83+
84+
#
85+
# Load data
86+
#
87+
ok, response_json = sdclient.get_data_promql_instant(query, 1744273000)
88+
89+
#
90+
# Show the result
91+
#
92+
if ok:
93+
#
94+
# Read response. The JSON looks like this:
95+
#
96+
# {
97+
# "result": [
98+
# {
99+
# "metric": {},
100+
# "value": [
101+
# 1744272414,
102+
# "0.58"
103+
# ]
104+
# }
105+
# ],
106+
# "resultType": "vector"
107+
# }
108+
#
109+
110+
111+
#
112+
# Print summary (what, when)
113+
#
114+
results = response_json.get("data", {}).get("result", [])
115+
print_prometheus_instant_result(results)
116+
117+
else:
118+
print(response_json)
119+
sys.exit(1)
120+
121+
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
#!/usr/bin/env python
2+
#
3+
# This script shows the basics of getting data out of Sysdig Monitor by creating a
4+
# simple query that returns the total CPU usage of all containers in all pods in the
5+
# last 10 minutes. The query is executed at a timestamp 5 minutes ago.
6+
#
7+
8+
import sys
9+
import time
10+
from datetime import datetime
11+
12+
from sdcclient import SdcClient
13+
14+
def print_prometheus_instant_result(result):
15+
if not result:
16+
print("No data found for the instant query.")
17+
return
18+
19+
# Determine if any result has labels
20+
has_labels = any(entry.get("metric") for entry in result)
21+
22+
if has_labels:
23+
print(f"{'Timestamp':<25} | {'Metric':<40} | {'Value':>10}")
24+
print("-" * 80)
25+
else:
26+
print(f"{'Timestamp':<25} | {'Value':>10}")
27+
print("-" * 40)
28+
29+
for entry in result:
30+
timestamp, value = entry.get("value", [None, None])
31+
dt = datetime.fromtimestamp(float(timestamp)).isoformat() if timestamp else "N/A"
32+
metric = entry.get("metric", {})
33+
34+
if has_labels:
35+
label_str = ', '.join(f'{k}="{v}"' for k, v in sorted(metric.items()))
36+
print(f"{dt:<25} | {label_str:<40} | {value:>10}")
37+
else:
38+
print(f"{dt:<25} | {value:>10}")
39+
40+
#
41+
# Parse arguments
42+
#
43+
if len(sys.argv) != 3:
44+
print(('usage: %s <sysdig-token> <hostname>' % sys.argv[0]))
45+
print('You can find your token at https://app.sysdigcloud.com/#/settings/user')
46+
sys.exit(1)
47+
48+
sdc_token = sys.argv[1]
49+
hostname = sys.argv[2]
50+
51+
sdclient = SdcClient(sdc_token, hostname)
52+
53+
#
54+
# A PromQL query to execute. In this example, we are querying for the total CPU usage
55+
# of all containers in all pods in the last 10 minutes.
56+
#
57+
query = '''
58+
sum (
59+
avg_over_time(kube_pod_container_resource_requests{resource="cpu"}[10m])
60+
)
61+
'''
62+
63+
#
64+
# Time:
65+
# - the parameter is optional; if not set, the current time is used
66+
#
67+
time = int(time.time()) - 5*60 # 5 minutes ago
68+
69+
#
70+
# Load data
71+
#
72+
ok, response_json = sdclient.get_data_promql_instant(query, time)
73+
74+
#
75+
# Show the result
76+
#
77+
if ok:
78+
#
79+
# Read response. The JSON looks like this:
80+
#
81+
# {
82+
# "result": [
83+
# {
84+
# "metric": {},
85+
# "value": [
86+
# 1744272414,
87+
# "0.58"
88+
# ]
89+
# }
90+
# ],
91+
# "resultType": "vector"
92+
# }
93+
#
94+
95+
96+
#
97+
# Print summary (what, when)
98+
#
99+
results = response_json.get("data", {}).get("result", [])
100+
print_prometheus_instant_result(results)
101+
102+
else:
103+
print(response_json)
104+
sys.exit(1)
105+
106+

0 commit comments

Comments
 (0)