Skip to content

Instantly share code, notes, and snippets.

@cupracer
Last active June 13, 2022 09:27
Show Gist options
  • Save cupracer/01f3177352a657020f8cb89ce0b1196f to your computer and use it in GitHub Desktop.
Save cupracer/01f3177352a657020f8cb89ce0b1196f to your computer and use it in GitHub Desktop.
Read specific multipath events from systemd-udevd.service via systemd-journal
#!/usr/bin/env python3
#
# use with:
# udevadm control --log-level=debug
#
# example output:
#
# ACTIVE: 0, STARTED: 142, SUCCEEDED: 142, BURSTS: 0, LONGEST: 0.366994 secs (device: dm-18, start: 11:22:09.099568, end: 11:22:09.466562)
# Burst detected. Resetting.
import select
from systemd import journal
import datetime
j = journal.Reader()
j.add_match(_SYSTEMD_UNIT="systemd-udevd.service")
j.add_match(_SYSTEMD_UNIT="multipathd.service")
j.seek_tail()
j.get_previous()
j.get_next()
p = select.poll()
p.register(j, j.get_events())
active_multipaths = {}
succeeded_but_not_in_list = []
counter_starting = 0
counter_succeeded = 0
max_start = None
max_end = None
max_duration = 0
max_dev = 'none'
counter_bursts = 0
while p.poll():
if j.process() != journal.APPEND:
continue
for entry in j:
# print(str(entry['__REALTIME_TIMESTAMP'] )+ ' ' + entry['MESSAGE'])
# print(entry)
if '/sbin/multipath -U' in entry['MESSAGE']:
if 'Starting' in entry['MESSAGE']: # or 'Running' in entry['MESSAGE']:
active_multipaths[entry['DEVICE']] = entry['_SOURCE_REALTIME_TIMESTAMP']
counter_starting = counter_starting + 1
if 'succeeded' in entry['MESSAGE']:
try:
diff = (entry['_SOURCE_REALTIME_TIMESTAMP'] - active_multipaths[entry['DEVICE']]).total_seconds()
if diff > max_duration:
max_start = active_multipaths[entry['DEVICE']]
max_end = entry['_SOURCE_REALTIME_TIMESTAMP']
max_duration = diff
max_dev = entry['DEVICE']
del(active_multipaths[entry['DEVICE']])
except (KeyError, ValueError):
succeeded_but_not_in_list.append(entry['DEVICE'])
counter_succeeded = counter_succeeded + 1
if 'burst' in entry['MESSAGE']:
counter_bursts = counter_bursts + 1
print('\r\nBurst detected. Resetting.')
active_multipaths = {}
succeeded_but_not_in_list = []
counter_starting = 0
counter_succeeded = 0
max_start = None
max_end = None
max_duration = 0
max_dev = 'none'
continue
current_str = ' '.join(active_multipaths)
current_str = (current_str[:30] + '...') if len(current_str) > 30 else current_str
output_str = "ACTIVE: " + str(len(active_multipaths))
if counter_bursts < 1:
output_str+= ', STARTED: ' + str(counter_starting) + ', SUCCEEDED: ' + str(counter_succeeded)
output_str+= ', BURSTS: ' + str(counter_bursts)
output_str+= ', LONGEST: ' + str(max_duration) + ' secs (device: ' + max_dev
if max_duration > 0:
output_str+= ', start: ' + max_start.strftime("%H:%M:%S.%f")
output_str+= ', end: ' + max_end.strftime("%H:%M:%S.%f")
output_str+= ')'
if current_str:
output_str+= ' (current: ' + current_str + ')'
print(end='\x1b[2K')
print(output_str, end='\r')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment