Coverage for hiphive/input_output/logging_tools.py: 90%

45 statements  

« prev     ^ index     » next       coverage.py v7.6.8, created at 2024-11-28 11:20 +0000

1""" This module contains functions and variables to control hiPhive's logging 

2 

3* `logger` - the module logger 

4* set_config - function to control level and logfile 

5""" 

6 

7import logging 

8import sys 

9from timeit import default_timer as timer 

10 

11# This is the root logger of hiPhive 

12logger = logging.getLogger('hiphive') 

13 

14# Will process all levels of INFO or higher 

15logger.setLevel(logging.INFO) 

16 

17# If you know what you are doing you may set this to True 

18logger.propagate = False 

19 

20# The hiPhive logger will collect events from childs and the default behaviour 

21# is to print it directly to stdout 

22ch = logging.StreamHandler(sys.stdout) 

23logger.addHandler(ch) 

24 

25continuous_logging = False 

26 

27 

28# TODO: use Context management protocol instead 

29class Progress: 

30 """ Progress bar like functionality. """ 

31 

32 def __init__(self, tot=None, mode='frac', estimate_remaining=True): 

33 if tot is None: 33 ↛ 34line 33 didn't jump to line 34 because the condition on line 33 was never true

34 self._tot = '?' 

35 assert not estimate_remaining 

36 else: 

37 self._tot = tot 

38 self._progress = 0 

39 self._estimate_remaining = estimate_remaining 

40 self._last_update = 0 

41 self._start = timer() 

42 

43 def tick(self): 

44 self._progress += 1 

45 delta = timer() - self._last_update 

46 if continuous_logging and delta > 2: 

47 self._last_update = timer() 

48 print('\r' + ' ' * 70 + '\r', end='', flush=True) 

49 print('{}/{}={:.3%}'.format(self._progress, 

50 self._tot, self._progress/self._tot), end='', flush=True) 

51 if self._estimate_remaining and self._tot != '?': 51 ↛ exitline 51 didn't return from function 'tick' because the condition on line 51 was always true

52 remaining_time = (self._tot - self._progress) * ( 

53 timer() - self._start) / self._progress 

54 print(' time remaining: {:.3}'.format(remaining_time), end='', 

55 flush=True) 

56 

57 def close(self): 

58 if continuous_logging: 

59 print('\r' + ' ' * 70 + '\r', end='', flush=True) 

60 s = timer() - self._start 

61 d, remainder = divmod(s, 60*60*24) 

62 h, remainder = divmod(remainder, 60*60) 

63 m, s = divmod(remainder, 60) 

64 logger.info('Done in {}d {}h {}m {:.3}s' 

65 .format(int(d), int(h), int(m), s)) 

66 

67 

68def set_config(filename=None, level=None, continuous=None): 

69 """ 

70 Alters the way logging is handled. 

71 

72 Parameters 

73 ---------- 

74 filename : str 

75 name of file the log should be sent to 

76 level : int 

77 verbosity level; see `Python logging library 

78 <https://docs.python.org/3/library/logging.html>`_ for details 

79 continuous : bool 

80 if True the progress will be continously updated 

81 """ 

82 

83 # If a filename is provided a logfile will be created 

84 if filename is not None: 

85 fh = logging.FileHandler(filename) 

86 logger.addHandler(fh) 

87 

88 if level is not None: 88 ↛ 89line 88 didn't jump to line 89 because the condition on line 88 was never true

89 logger.setLevel(level) 

90 

91 if continuous is not None: 

92 global continuous_logging 

93 continuous_logging = continuous