77import sys
88import json
99import logging
10+ from datetime import datetime , timedelta
1011import requests
11- import dateparser
1212from retrying import retry
1313
1414# set up logging
@@ -97,7 +97,6 @@ def get_current_metric_value(
9797 data = []
9898 if label_config :
9999 label_list = [str (key + "=" + "'" + label_config [key ] + "'" ) for key in label_config ]
100- # print(label_list)
101100 query = metric_name + "{" + "," .join (label_list ) + "}"
102101 else :
103102 query = metric_name
@@ -123,9 +122,9 @@ def get_metric_range_data(
123122 self ,
124123 metric_name : str ,
125124 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 ,
129128 store_locally : bool = False ,
130129 params : dict = None ,
131130 ):
@@ -136,10 +135,10 @@ def get_metric_range_data(
136135 :param metric_name: (str) The name of the metric.
137136 :param label_config: (dict) A dictionary specifying metric labels and their
138137 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
143142 request made to the prometheus host
144143 :param store_locally: (bool) If set to True, will store data locally at,
145144 `"./metrics/hostname/metric_date/name_time.json.bz2"`
@@ -152,33 +151,44 @@ def get_metric_range_data(
152151 params = params or {}
153152 data = []
154153
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" )
157160
158161 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" )
165165
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 ():
167170 sys .exit ("specified chunk_size is too big" )
171+ chunk_seconds = round (chunk_size .total_seconds ())
168172
169173 if label_config :
170174 label_list = [str (key + "=" + "'" + label_config [key ] + "'" ) for key in label_config ]
171- # print(label_list)
172175 query = metric_name + "{" + "," .join (label_list ) + "}"
173176 else :
174177 query = metric_name
178+ _LOGGER .debug ("Prometheus Query: %s" , query )
175179
176180 while start < end :
181+ if start + chunk_seconds > end :
182+ chunk_seconds = end - start
183+
177184 # using the query API to get raw data
178185 response = requests .get (
179186 "{0}/api/v1/query" .format (self .url ),
180187 params = {
181- ** {"query" : query + "[" + chunk_size + "]" , "time" : start + chunk_seconds },
188+ ** {
189+ "query" : query + "[" + str (chunk_seconds ) + "s" + "]" ,
190+ "time" : start + chunk_seconds ,
191+ },
182192 ** params ,
183193 },
184194 verify = self .ssl_verification ,
@@ -207,7 +217,8 @@ def _store_metric_values_local(self, metric_name, values, end_timestamp, compres
207217
208218 :param metric_name: (str) the name of the metric being saved
209219 :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()
211222 :param compressed: (bool) whether or not to apply bz2 compression
212223 :returns: (str) path to the saved metric file
213224 """
@@ -229,15 +240,16 @@ def _store_metric_values_local(self, metric_name, values, end_timestamp, compres
229240
230241 return file_path
231242
232- def _metric_filename (self , metric_name : str , end_timestamp : str ):
243+ def _metric_filename (self , metric_name : str , end_timestamp : int ):
233244 """
234245 Adds a timestamp to the filename before it is stored
235246
236247 :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()
238250 :returns: (str) the generated path
239251 """
240- end_timestamp = dateparser . parse ( str ( end_timestamp ) )
252+ end_timestamp = datetime . fromtimestamp ( end_timestamp )
241253 directory_name = end_timestamp .strftime ("%Y%m%d" )
242254 timestamp = end_timestamp .strftime ("%Y%m%d%H%M" )
243255 object_path = (
@@ -286,15 +298,3 @@ def custom_query(self, query: str, params: dict = None):
286298 )
287299
288300 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