def chrony_system_time(self): """In normal operation, chronyd never steps the system clock, because any jump in the timescale can have adverse consequences for certain application programs. Instead, any error in the system clock is corrected by slightly speeding up or slowing down the system clock until the error has been removed, and then returning to the system clock’s normal speed. A consequence of this is that there will be a period when the system clock (as read by other programs using the gettimeofday() system call, or by the date command in the shell) will be different from chronyd's estimate of the current true time (which it reports to NTP clients when it is operating in server mode). The value reported on this line is the difference due to this effect. :return: """ stderr, chrony = self.chrony.chrony_tracking() reference_name = chrony.get('reference_name') system_time = chrony.get('system_time', 0.0) st = normalize_timespec(float(system_time)) l1 = '{0} SysTime'.format(reference_name) l2 = '{0}{1} {2}'.format(int(st[0]), chr(228) + "s" if st[1] == 'µs' else st[1], "fast" if st[0] > 1 else "slow") return (l1, 0), (l2, 1)
def chrony_tracking(self): indata = {} stderr, stdout = self.shell.shell_run(self.chronyc_path + ' -c tracking') data = stdout.decode('utf-8') data_raw = data.strip() clock_data = data_raw.split(',') if len(self.tracking_fields) == len(clock_data): for ndx, clock in enumerate(clock_data): indata[self.tracking_fields[ndx]] = clock clock_offset_from_ntp = float(clock_data[4]) clock_offset = normalize_timespec(clock_offset_from_ntp) if abs(clock_offset_from_ntp) >= self.maximum_divergence_tolerated: clock_status = '{co}[max{mt}s] NOK'.format( co=int(clock_offset_from_ntp), mt=int(self.maximum_divergence_tolerated)) else: clock_status = '{co}{co_unit}[{mt}s] OK'.format( co=int(clock_offset[0]), co_unit=clock_offset[1], mt=int(self.maximum_divergence_tolerated)) indata['clock_status'] = clock_status else: stderr = b'Unexpected error on Chrony tracking' return stderr.decode('UTF-8'), indata
def chrony_root_delay(self): """This is the total of the network path delays to the stratum-1 computer from which the computer is ultimately synchronised. In certain extreme situations, this value can be negative. (This can arise in a symmetric peer arrangement where the computers’ frequencies are not tracking each other and the network delay is very short relative to the turn-around time at each computer.) :return: """ stderr, chrony = self.chrony.chrony_tracking() reference_name = chrony.get('reference_name') root_delay = chrony.get('root_delay') root_root_dispersion = chrony.get('root_dispersion') _root_delay = normalize_timespec(float(root_delay)) _root_root_dispersion = normalize_timespec(float(root_root_dispersion)) l1 = '{} Root Delay'.format(reference_name) l2 = '{root_delay} {root_delay_unit}'.format( root_delay=int(_root_delay[0]), root_delay_unit=_root_delay[1]) return (l1, 0, 'CENTER'), (l2, 1, 'CENTER')
def chrony_root_dispersion(self): """This is the total dispersion accumulated through all the computers back to the stratum-1 computer from which the computer is ultimately synchronised. Dispersion is due to system clock resolution, statistical measurement variations etc. :return: """ stderr, chrony = self.chrony.chrony_tracking() reference_name = chrony.get('reference_name') root_delay = chrony.get('root_delay') root_root_dispersion = chrony.get('root_dispersion') _root_delay = normalize_timespec(float(root_delay)) _root_root_dispersion = normalize_timespec(float(root_root_dispersion)) l1 = '{} Root Disper'.format(reference_name) l2 = '{root_root_dispersion} {root_root_dispersion_unit}'.format( root_root_dispersion=int(_root_root_dispersion[0]), root_root_dispersion_unit=chr(228) + "s" if _root_root_dispersion[1] == 'µs' else _root_root_dispersion[1]) return (l1, 0, 'CENTER'), (l2, 1, 'CENTER')
def chrony_rms_offset(self): """This is a long-term average of the offset value. :return: """ stderr, chrony = self.chrony.chrony_tracking() reference_name = chrony.get('reference_name') rms_offset = chrony.get('rms_offset', 0.0) rms_off = normalize_timespec(float(rms_offset)) l1 = '{} RMS offset'.format(reference_name) l2 = '{rms_off} {rms_off_unit}'.format( rms_off=int(rms_off[0]), rms_off_unit=chr(228) + "s" if rms_off[1] == 'µs' else rms_off[1]) return (l1, 0), (l2, 1)
def chrony_last_offset(self): """This is the estimated local offset on the last clock update. :return: """ stderr, chrony = self.chrony.chrony_tracking() reference_name = chrony.get('reference_name') last_offset = chrony.get('last_offset', 0.0) last_off = normalize_timespec(float(last_offset)) l1 = '{} Last offset'.format(reference_name) l2 = '{last_off} {last_off_unit}'.format( last_off=int(last_off[0]), last_off_unit=chr(228) + "s" if last_off[1] == 'µs' else last_off[1]) return (l1, 0), (l2, 1)