7
7
import sys
8
8
import json
9
9
import logging
10
+ from datetime import datetime , timedelta
10
11
import requests
11
- import dateparser
12
12
from retrying import retry
13
13
14
14
# set up logging
@@ -97,7 +97,6 @@ def get_current_metric_value(
97
97
data = []
98
98
if label_config :
99
99
label_list = [str (key + "=" + "'" + label_config [key ] + "'" ) for key in label_config ]
100
- # print(label_list)
101
100
query = metric_name + "{" + "," .join (label_list ) + "}"
102
101
else :
103
102
query = metric_name
@@ -123,9 +122,9 @@ def get_metric_range_data(
123
122
self ,
124
123
metric_name : str ,
125
124
label_config : dict = None ,
126
- start_time : str = "10m" ,
127
- end_time : str = " now" ,
128
- chunk_size : str = None ,
125
+ start_time : datetime = ( datetime . now () - timedelta ( minutes = 10 )) ,
126
+ end_time : datetime = datetime . now () ,
127
+ chunk_size : timedelta = None ,
129
128
store_locally : bool = False ,
130
129
params : dict = None ,
131
130
):
@@ -136,10 +135,10 @@ def get_metric_range_data(
136
135
:param metric_name: (str) The name of the metric.
137
136
:param label_config: (dict) A dictionary specifying metric labels and their
138
137
values.
139
- :param start_time: (str ) A string that specifies the metric range start time.
140
- :param end_time: (str ) A string that specifies the metric range end time.
141
- :param chunk_size: (str ) Duration of metric data downloaded in one request. For
142
- example, setting it to '3h' will download 3 hours worth of data in each
138
+ :param start_time: (datetime ) A datetime object that specifies the metric range start time.
139
+ :param end_time: (datetime ) A datetime object that specifies the metric range end time.
140
+ :param chunk_size: (timedelta ) Duration of metric data downloaded in one request. For
141
+ example, setting it to timedelta(hours=3) will download 3 hours worth of data in each
143
142
request made to the prometheus host
144
143
:param store_locally: (bool) If set to True, will store data locally at,
145
144
`"./metrics/hostname/metric_date/name_time.json.bz2"`
@@ -152,33 +151,44 @@ def get_metric_range_data(
152
151
params = params or {}
153
152
data = []
154
153
155
- start = int (dateparser .parse (str (start_time )).timestamp ())
156
- end = int (dateparser .parse (str (end_time )).timestamp ())
154
+ _LOGGER .debug ("start_time: %s" , start_time )
155
+ _LOGGER .debug ("end_time: %s" , end_time )
156
+ _LOGGER .debug ("chunk_size: %s" , chunk_size )
157
+
158
+ if not (isinstance (start_time , datetime ) and isinstance (end_time , datetime )):
159
+ raise TypeError ("start_time and end_time can only be of type datetime.datetime" )
157
160
158
161
if not chunk_size :
159
- chunk_seconds = int (end - start )
160
- chunk_size = str (int (chunk_seconds )) + "s"
161
- else :
162
- chunk_seconds = int (
163
- round ((dateparser .parse ("now" ) - dateparser .parse (chunk_size )).total_seconds ())
164
- )
162
+ chunk_size = end_time - start_time
163
+ if not isinstance (chunk_size , timedelta ):
164
+ raise TypeError ("chunk_size can only be of type datetime.timedelta" )
165
165
166
- if int (end - start ) < chunk_seconds :
166
+ start = round (start_time .timestamp ())
167
+ end = round (end_time .timestamp ())
168
+
169
+ if (end_time - start_time ).total_seconds () < chunk_size .total_seconds ():
167
170
sys .exit ("specified chunk_size is too big" )
171
+ chunk_seconds = round (chunk_size .total_seconds ())
168
172
169
173
if label_config :
170
174
label_list = [str (key + "=" + "'" + label_config [key ] + "'" ) for key in label_config ]
171
- # print(label_list)
172
175
query = metric_name + "{" + "," .join (label_list ) + "}"
173
176
else :
174
177
query = metric_name
178
+ _LOGGER .debug ("Prometheus Query: %s" , query )
175
179
176
180
while start < end :
181
+ if start + chunk_seconds > end :
182
+ chunk_seconds = end - start
183
+
177
184
# using the query API to get raw data
178
185
response = requests .get (
179
186
"{0}/api/v1/query" .format (self .url ),
180
187
params = {
181
- ** {"query" : query + "[" + chunk_size + "]" , "time" : start + chunk_seconds },
188
+ ** {
189
+ "query" : query + "[" + str (chunk_seconds ) + "s" + "]" ,
190
+ "time" : start + chunk_seconds ,
191
+ },
182
192
** params ,
183
193
},
184
194
verify = self .ssl_verification ,
@@ -207,7 +217,8 @@ def _store_metric_values_local(self, metric_name, values, end_timestamp, compres
207
217
208
218
:param metric_name: (str) the name of the metric being saved
209
219
:param values: (str) metric data in JSON string format
210
- :param end_timestamp: (str) timestamp in any format understood by dateparser
220
+ :param end_timestamp: (int) timestamp in any format understood by \
221
+ datetime.datetime.fromtimestamp()
211
222
:param compressed: (bool) whether or not to apply bz2 compression
212
223
:returns: (str) path to the saved metric file
213
224
"""
@@ -229,15 +240,16 @@ def _store_metric_values_local(self, metric_name, values, end_timestamp, compres
229
240
230
241
return file_path
231
242
232
- def _metric_filename (self , metric_name : str , end_timestamp : str ):
243
+ def _metric_filename (self , metric_name : str , end_timestamp : int ):
233
244
"""
234
245
Adds a timestamp to the filename before it is stored
235
246
236
247
:param metric_name: (str) the name of the metric being saved
237
- :param end_timestamp: (str) timestamp in any format understood by dateparser
248
+ :param end_timestamp: (int) timestamp in any format understood by \
249
+ datetime.datetime.fromtimestamp()
238
250
:returns: (str) the generated path
239
251
"""
240
- end_timestamp = dateparser . parse ( str ( end_timestamp ) )
252
+ end_timestamp = datetime . fromtimestamp ( end_timestamp )
241
253
directory_name = end_timestamp .strftime ("%Y%m%d" )
242
254
timestamp = end_timestamp .strftime ("%Y%m%d%H%M" )
243
255
object_path = (
@@ -286,15 +298,3 @@ def custom_query(self, query: str, params: dict = None):
286
298
)
287
299
288
300
return data
289
-
290
-
291
- def pretty_print_metric (metric_data ):
292
- """
293
- A function to pretty print the metric data downloaded using class PrometheusConnect.
294
-
295
- :param metric_data: (list) This is the metric data list returned from methods
296
- get_metric_range_data and get_current_metric_value
297
- """
298
- data = metric_data
299
- for metric in data :
300
- print (json .dumps (metric , indent = 4 , sort_keys = True ))
0 commit comments