-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrequests_graph.py
executable file
·135 lines (122 loc) · 4.61 KB
/
requests_graph.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#!/usr/bin/env python3
import sys
import time
import array
import argparse
import datetime
import requests
import json
import os.path
import matplotlib as mpl
mpl.use('Agg')
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
# From https://github.com/ProgVal/Limnoria/blob/master/plugins/Time/plugin.py
def human_to_seconds(string):
seconds = 0
for arg in string.split(' '):
if not arg or arg[-1] not in 'ywdhms':
raise ValueError(arg)
(s, kind) = arg[:-1], arg[-1]
i = int(s)
if kind == 'y':
seconds += i*31536000
elif kind == 'w':
seconds += i*604800
elif kind == 'd':
seconds += i*86400
elif kind == 'h':
seconds += i*3600
elif kind == 'm':
seconds += i*60
elif kind == 's':
seconds += i
return seconds
# Parse arguments
parser = argparse.ArgumentParser(
description='Plots of graph of requests to the PPP')
parser.add_argument('outputfile')
parser.add_argument('-g', '--granulometry', type=str,
default='1h', help='Length of time slices (e.g. 2h, 3d, 1w).')
parser.add_argument('-i', '--interval', type=str,
default='48h', help='Time interval (e.g. 24h, 3d, 1w).')
parser.add_argument('-t', '--ticks', type=int,
default=6, help='Space between two labels on the x axis.')
parser.add_argument('-l', '--logger-url', type=str,
default='http://logger.frontend.askplatyp.us/',
help='The URL to the logger.')
parser.add_argument('-c', '--cache-file-name', type=str,
default=None,
help='The name of the file used to cache data.')
args = parser.parse_args()
OUTPUT_FILE = args.outputfile
INTERVAL = human_to_seconds(args.interval)
GRANULOMETRY = human_to_seconds(args.granulometry)
TICKS = args.ticks
LOGGER_URL = args.logger_url
DATA_CACHE_FILENAME = args.cache_file_name
# Initialize matplotlib
fig, ax = plt.subplots()
# Get data
if DATA_CACHE_FILENAME is not None and os.path.isfile(DATA_CACHE_FILENAME):
with open(DATA_CACHE_FILENAME) as data_cache:
data = json.load(data_cache)
print('Loaded the data from cache.')
else:
data = requests.get(LOGGER_URL, params={'limit': 10000}).json()
print('Downloaded the data.')
if DATA_CACHE_FILENAME is not None:
with open(DATA_CACHE_FILENAME, 'w') as data_cache:
json.dump(data, data_cache)
# Convert to datetime
data = [datetime.datetime(*time.strptime(x[1].split('.')[0], "%Y-%m-%d %H:%M:%S")[:6]) for x in data]
# Compute the difference
datemax = datetime.datetime.now()
data = [int(datemax.timestamp()) - int(x.timestamp()) for x in data]
delta = datetime.timedelta(seconds=INTERVAL)
datemin = datemax - delta
ax.set_xlim(datemin, datemax)
# Shrink and convert to seconds
data = [x//GRANULOMETRY for x in data]
# Compute the height of the bars
requests_per_slice = array.array('I', (0 for x in range(0, INTERVAL//GRANULOMETRY)))
for x in data:
if x >= INTERVAL//GRANULOMETRY:
continue
requests_per_slice[(INTERVAL//GRANULOMETRY) - x - 1] += 1
# Units
if INTERVAL < human_to_seconds('6h'):
locator = mdates.MinuteLocator(interval=TICKS)
fmt = mdates.DateFormatter('%H:%M')
elif INTERVAL < human_to_seconds('3d'):
locator = mdates.HourLocator(interval=TICKS)
fmt = mdates.DateFormatter('%H:00')
elif INTERVAL < human_to_seconds('16w'):
locator = mdates.DayLocator(interval=TICKS)
fmt = mdates.DateFormatter('%d-%m')
else:
locator = mdates.DayLocator(interval=TICKS)
fmt = mdates.DateFormatter('%m-%y')
ax.xaxis.set_major_locator(locator)
ax.xaxis.set_major_formatter(fmt)
# Final plot
x = list(map(lambda x:datemin + datetime.timedelta(seconds=x*GRANULOMETRY), range(0, INTERVAL//GRANULOMETRY)))
ax.plot(x, requests_per_slice, label=None)
# Titles
if INTERVAL < human_to_seconds('6h'):
plt.title("Requests to the PPP in the last %d hours" % (INTERVAL//3600))
elif INTERVAL < human_to_seconds('8d'):
plt.title("Requests to the PPP in the last %d days" % (INTERVAL//(24*3600)))
elif INTERVAL < human_to_seconds('16w'):
plt.title("Requests to the PPP in the last %d weeks" % (INTERVAL//(7*24*3600)))
else:
plt.title("Requests to the PPP in the last %d months" % (INTERVAL//((365.25/12)*24*3600)))
plt.xlabel("Time")
if GRANULOMETRY < human_to_seconds('2h'):
plt.ylabel("Requests (per slice of %d minutes)" % (GRANULOMETRY//60))
elif GRANULOMETRY < human_to_seconds('10h'):
plt.ylabel("Requests (per slice of %d hours)" % (GRANULOMETRY//3600))
else:
plt.ylabel("Requests (per slice of %d days)" % (GRANULOMETRY//(24*3600)))
#plt.legend()
plt.savefig(OUTPUT_FILE, dpi=300, transparent=True)