Merge branch 'master' into decouple-io
[deliverable/lttng-analyses.git] / linuxautomaton / linuxautomaton / common.py
CommitLineData
4ed24f86
JD
1#!/usr/bin/env python3
2#
3# The MIT License (MIT)
4#
a3fa57c0 5# Copyright (C) 2015 - Julien Desfossez <jdesfossez@efficios.com>
4ed24f86
JD
6#
7# Permission is hereby granted, free of charge, to any person obtaining a copy
8# of this software and associated documentation files (the "Software"), to deal
9# in the Software without restriction, including without limitation the rights
10# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11# copies of the Software, and to permit persons to whom the Software is
12# furnished to do so, subject to the following conditions:
13#
14# The above copyright notice and this permission notice shall be included in
15# all copies or substantial portions of the Software.
16#
17# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23# SOFTWARE.
24
bd3cd7c5
JD
25import math
26import re
27import time
28import datetime
29import socket
30import struct
bd3cd7c5
JD
31from linuxautomaton import sv
32
33NSEC_PER_SEC = 1000000000
34MSEC_PER_NSEC = 1000000
35
36O_CLOEXEC = 0o2000000
37
38
bd3cd7c5
JD
39def convert_size(size, padding_after=False, padding_before=False):
40 if padding_after and size < 1024:
3f52a605 41 space_after = ' '
bd3cd7c5 42 else:
3f52a605 43 space_after = ''
bd3cd7c5 44 if padding_before and size < 1024:
3f52a605 45 space_before = ' '
bd3cd7c5 46 else:
3f52a605 47 space_before = ''
bd3cd7c5 48 if size <= 0:
3f52a605
AB
49 return '0 ' + space_before + 'B' + space_after
50 size_name = ('B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB')
bd3cd7c5
JD
51 i = int(math.floor(math.log(size, 1024)))
52 p = math.pow(1024, i)
53 s = round(size/p, 2)
ced36aab 54 if s > 0:
bd3cd7c5 55 try:
3f52a605 56 v = '%0.02f' % s
8e05871d 57 return '%s %s%s%s' % (v, space_before, size_name[i], space_after)
bd3cd7c5
JD
58 except:
59 print(i, size_name)
3f52a605 60 raise Exception('Too big to be true')
bd3cd7c5
JD
61 else:
62 return '0 B'
63
64
ced36aab
AB
65def is_multi_day_trace_collection(handles):
66 time_begin = None
67
68 for handle in handles.values():
69 if time_begin is None:
70 time_begin = time.localtime(handle.timestamp_begin / NSEC_PER_SEC)
71 year_begin = time_begin.tm_year
72 month_begin = time_begin.tm_mon
73 day_begin = time_begin.tm_mday
74
75 time_end = time.localtime(handle.timestamp_end / NSEC_PER_SEC)
76 year_end = time_end.tm_year
77 month_end = time_end.tm_mon
78 day_end = time_end.tm_mday
79
80 if year_begin != year_end:
bd3cd7c5 81 return True
ced36aab 82 elif month_begin != month_end:
bd3cd7c5 83 return True
ced36aab 84 elif day_begin != day_end:
bd3cd7c5 85 return True
ced36aab 86
bd3cd7c5
JD
87 return False
88
89
ced36aab
AB
90def trace_collection_date(handles):
91 if is_multi_day_trace_collection(handles):
bd3cd7c5 92 return None
ced36aab 93
652bc6b7
AB
94 for handle in handles.values():
95 trace_time = time.localtime(handle.timestamp_begin / NSEC_PER_SEC)
96 year = trace_time.tm_year
97 month = trace_time.tm_mon
98 day = trace_time.tm_mday
99 return (year, month, day)
bd3cd7c5
JD
100
101
ced36aab 102def extract_timerange(handles, timerange, gmt):
5b395a93
AB
103 pattern = re.compile(r'^\[(?P<begin>.*),(?P<end>.*)\]$')
104 if not pattern.match(timerange):
bd3cd7c5 105 return None
5b395a93
AB
106 begin_str = pattern.search(timerange).group('begin').strip()
107 end_str = pattern.search(timerange).group('end').strip()
ced36aab
AB
108 begin = date_to_epoch_nsec(handles, begin_str, gmt)
109 end = date_to_epoch_nsec(handles, end_str, gmt)
bd3cd7c5
JD
110 return (begin, end)
111
112
ced36aab 113def date_to_epoch_nsec(handles, date, gmt):
bd3cd7c5 114 # match 2014-12-12 17:29:43.802588035 or 2014-12-12T17:29:43.802588035
5b395a93
AB
115 pattern1 = re.compile(r'^(?P<year>\d\d\d\d)-(?P<mon>[01]\d)-'
116 r'(?P<day>[0123]\d)[\sTt]'
117 r'(?P<hour>\d\d):(?P<min>\d\d):(?P<sec>\d\d).'
118 r'(?P<nsec>\d\d\d\d\d\d\d\d\d)$')
bd3cd7c5 119 # match 2014-12-12 17:29:43 or 2014-12-12T17:29:43
5b395a93
AB
120 pattern2 = re.compile(r'^(?P<year>\d\d\d\d)-(?P<mon>[01]\d)-'
121 r'(?P<day>[0123]\d)[\sTt]'
122 r'(?P<hour>\d\d):(?P<min>\d\d):(?P<sec>\d\d)$')
bd3cd7c5 123 # match 17:29:43.802588035
5b395a93
AB
124 pattern3 = re.compile(r'^(?P<hour>\d\d):(?P<min>\d\d):(?P<sec>\d\d).'
125 r'(?P<nsec>\d\d\d\d\d\d\d\d\d)$')
bd3cd7c5 126 # match 17:29:43
5b395a93
AB
127 pattern4 = re.compile(r'^(?P<hour>\d\d):(?P<min>\d\d):(?P<sec>\d\d)$')
128
129 if pattern1.match(date):
130 year = pattern1.search(date).group('year')
131 month = pattern1.search(date).group('mon')
132 day = pattern1.search(date).group('day')
133 hour = pattern1.search(date).group('hour')
134 minute = pattern1.search(date).group('min')
135 sec = pattern1.search(date).group('sec')
136 nsec = pattern1.search(date).group('nsec')
137 elif pattern2.match(date):
138 year = pattern2.search(date).group('year')
139 month = pattern2.search(date).group('mon')
140 day = pattern2.search(date).group('day')
141 hour = pattern2.search(date).group('hour')
142 minute = pattern2.search(date).group('min')
143 sec = pattern2.search(date).group('sec')
bd3cd7c5 144 nsec = 0
5b395a93 145 elif pattern3.match(date):
ced36aab
AB
146 collection_date = trace_collection_date(handles)
147 if collection_date is None:
bd3cd7c5
JD
148 print("Use the format 'yyyy-mm-dd hh:mm:ss[.nnnnnnnnn]' "
149 "for multi-day traces")
150 return None
ced36aab 151 (year, month, day) = collection_date
5b395a93
AB
152 hour = pattern3.search(date).group('hour')
153 minute = pattern3.search(date).group('min')
154 sec = pattern3.search(date).group('sec')
155 nsec = pattern3.search(date).group('nsec')
156 elif pattern4.match(date):
ced36aab
AB
157 collection_date = trace_collection_date(handles)
158 if collection_date is None:
bd3cd7c5
JD
159 print("Use the format 'yyyy-mm-dd hh:mm:ss[.nnnnnnnnn]' "
160 "for multi-day traces")
161 return None
ced36aab 162 (year, month, day) = collection_date
5b395a93
AB
163 hour = pattern4.search(date).group('hour')
164 minute = pattern4.search(date).group('min')
165 sec = pattern4.search(date).group('sec')
bd3cd7c5
JD
166 nsec = 0
167 else:
168 return None
169
ced36aab 170 date_time = datetime.datetime(int(year), int(month), int(day), int(hour),
5b395a93 171 int(minute), int(sec))
bd3cd7c5 172 if gmt:
ced36aab
AB
173 date_time = date_time + datetime.timedelta(seconds=time.timezone)
174 return int(date_time.timestamp()) * NSEC_PER_SEC + int(nsec)
bd3cd7c5
JD
175
176
177def ns_to_asctime(ns):
178 return time.asctime(time.localtime(ns/NSEC_PER_SEC))
179
180
181def ns_to_hour(ns):
ced36aab
AB
182 date = time.localtime(ns / NSEC_PER_SEC)
183 return '%02d:%02d:%02d' % (date.tm_hour, date.tm_min, date.tm_sec)
bd3cd7c5
JD
184
185
186def ns_to_hour_nsec(ns, multi_day=False, gmt=False):
187 if gmt:
ced36aab 188 date = time.gmtime(ns / NSEC_PER_SEC)
bd3cd7c5 189 else:
ced36aab 190 date = time.localtime(ns / NSEC_PER_SEC)
bd3cd7c5 191 if multi_day:
ced36aab
AB
192 return ('%04d-%02d-%02d %02d:%02d:%02date.%09d' %
193 (date.tm_year, date.tm_mon, date.tm_mday, date.tm_hour,
194 date.tm_min, date.tm_sec, ns % NSEC_PER_SEC))
bd3cd7c5 195 else:
ced36aab
AB
196 return ('%02d:%02d:%02date.%09d' %
197 (date.tm_hour, date.tm_min, date.tm_sec, ns % NSEC_PER_SEC))
bd3cd7c5
JD
198
199
200def ns_to_sec(ns):
ced36aab 201 return '%lu.%09u' % (ns / NSEC_PER_SEC, ns % NSEC_PER_SEC)
bd3cd7c5
JD
202
203
204def ns_to_day(ns):
ced36aab
AB
205 date = time.localtime(ns/NSEC_PER_SEC)
206 return '%04d-%02d-%02d' % (date.tm_year, date.tm_mon, date.tm_mday)
bd3cd7c5
JD
207
208
209def sec_to_hour(ns):
ced36aab
AB
210 date = time.localtime(ns)
211 return '%02d:%02d:%02d' % (date.tm_hour, date.tm_min, date.tm_sec)
bd3cd7c5
JD
212
213
214def sec_to_nsec(sec):
215 return sec * NSEC_PER_SEC
216
217
218def seq_to_ipv4(ip):
3f52a605 219 return '{}.{}.{}.{}'.format(ip[0], ip[1], ip[2], ip[3])
bd3cd7c5
JD
220
221
222def int_to_ipv4(ip):
3f52a605 223 return socket.inet_ntoa(struct.pack('!I', ip))
bd3cd7c5
JD
224
225
226def str_to_bytes(value):
3f52a605
AB
227 num = ''
228 unit = ''
bd3cd7c5 229 for i in value:
3f52a605 230 if i.isdigit() or i == '.':
bd3cd7c5
JD
231 num = num + i
232 elif i.isalnum():
233 unit = unit + i
234 num = float(num)
5faa923d 235 if not unit:
bd3cd7c5 236 return int(num)
3f52a605 237 if unit in ['B']:
bd3cd7c5 238 return int(num)
3f52a605 239 if unit in ['k', 'K', 'kB', 'KB']:
bd3cd7c5 240 return int(num * 1024)
3f52a605 241 if unit in ['m', 'M', 'mB', 'MB']:
bd3cd7c5 242 return int(num * 1024 * 1024)
3f52a605 243 if unit in ['g', 'G', 'gB', 'GB']:
bd3cd7c5 244 return int(num * 1024 * 1024 * 1024)
3f52a605 245 if unit in ['t', 'T', 'tB', 'TB']:
bd3cd7c5 246 return int(num * 1024 * 1024 * 1024 * 1024)
3f52a605 247 print('Unit', unit, 'not understood')
bd3cd7c5
JD
248 return None
249
250
251def get_v4_addr_str(ip):
252 # depending on the version of lttng-modules, the v4addr is a
253 # string (< 2.6) or sequence (>= 2.6)
254 try:
255 return seq_to_ipv4(ip)
256 except TypeError:
257 return int_to_ipv4(ip)
This page took 0.035474 seconds and 5 git commands to generate.