diff --git a/lisa/analysis/frequency.py b/lisa/analysis/frequency.py index a6c09a3135b7f6cc31151d1240681ae1bd75ba7e..97da69ef0f9003b3c125eb585b4b26de120c28a3 100644 --- a/lisa/analysis/frequency.py +++ b/lisa/analysis/frequency.py @@ -278,7 +278,7 @@ class FrequencyAnalysis(TraceAnalysisBase): :type clk: str """ - logger = self.get_logger() + logger = self.logger start = self.trace.start end = self.trace.end @@ -359,7 +359,7 @@ class FrequencyAnalysis(TraceAnalysisBase): If ``sched_overutilized`` events are available, the plots will also show the intervals of time where the system was overutilized. """ - logger = self.get_logger() + logger = self.logger df = self.trace.df_events('cpu_frequency') df = df[df.cpu == cpu] diff --git a/lisa/analysis/latency.py b/lisa/analysis/latency.py index 9713c3fd2620dd056b44a24d83777dc2cfb494d2..a18b8ff4a8d18bf53387e1769cbe8bd6a6e792c9 100644 --- a/lisa/analysis/latency.py +++ b/lisa/analysis/latency.py @@ -196,14 +196,14 @@ class LatencyAnalysis(TraceAnalysisBase): if wakeup: df = self.df_latency_wakeup(task) if df.empty: - self.get_logger().warning("No data to plot for wakeups") + self.logger.warning("No data to plot for wakeups") else: df.plot(ax=axis, style='+', label="Wakeup") if preempt: df = self.df_latency_preemption(task) if df.empty: - self.get_logger().warning("No data to plot for preemption") + self.logger.warning("No data to plot for preemption") else: df.plot(ax=axis, style='+', label="Preemption") diff --git a/lisa/analysis/proxy.py b/lisa/analysis/proxy.py index a33c8302df609590b88f1f8b86992e9498b99c5c..7b2d380d73abe2e20e4ded764ac9b5e9119ed5b6 100644 --- a/lisa/analysis/proxy.py +++ b/lisa/analysis/proxy.py @@ -66,7 +66,7 @@ class AnalysisProxy(Loggable): if attr.startswith('__') and attr.endswith('__'): return super().__getattribute__(attr) - logger = self.get_logger() + logger = self.logger # First, try to get the instance of the Analysis that was built if we # used it already on that proxy. diff --git a/lisa/analysis/rta.py b/lisa/analysis/rta.py index 1191212981693c6a4c5be9d3abfecffcb3d899af..9e103ea08da03def1938b36d8e825ebd1a7f06d2 100644 --- a/lisa/analysis/rta.py +++ b/lisa/analysis/rta.py @@ -664,7 +664,7 @@ class RTAEventsAnalysis(TraceAnalysisBase): ylabel = 'perf index of "{}"'.format(task) series = self.df_rtapp_stats(task)['perf_index'] mean = series.mean() - self.get_logger().info('perf index of task "{}": avg={:.2f} std={:.2f}' + self.logger.info('perf index of task "{}": avg={:.2f} std={:.2f}' .format(task, mean, series.std())) series.hist(bins=bins, ax=axis, alpha=0.4, label=ylabel, figure=axis.get_figure()) @@ -698,7 +698,7 @@ class PerfAnalysis(AnalysisHelpers): """ Load peformance data of an rt-app workload """ - logger = self.get_logger() + logger = self.logger if not task_log_map: raise ValueError('No tasks in the task log mapping') @@ -906,7 +906,7 @@ class PerfAnalysis(AnalysisHelpers): ylabel = 'perf index of "{}"'.format(task) series = self.get_df(task)['PerfIndex'] mean = series.mean() - self.get_logger().info('perf index of task "{}": avg={:.2f} std={:.2f}'.format( + self.logger.info('perf index of task "{}": avg={:.2f} std={:.2f}'.format( task, mean, series.std())) series.hist(bins=bins, ax=axis, alpha=0.4, label=ylabel) diff --git a/lisa/conf.py b/lisa/conf.py index 3f08a465451b0be5ca1a86763aee4089ddd8a0d0..bede11eb4403c292e373887c84666cdf75bd07b4 100644 --- a/lisa/conf.py +++ b/lisa/conf.py @@ -785,7 +785,7 @@ class MultiSrcConf(MultiSrcConfABC, Loggable, Mapping): mapping as a new source. """ - logger = self.get_logger() + logger = self.logger if logger.isEnabledFor(logging.DEBUG): caller, filename, lineno = get_call_site(1, exclude_caller_module=True) logger.debug('{caller} ({filename}:{lineno}) has set source "{src}":\n{conf}'.format( @@ -1089,7 +1089,7 @@ class MultiSrcConf(MultiSrcConfABC, Loggable, Mapping): val = self._eval_deferred_val(src, key) - logger = self.get_logger() + logger = self.logger if not quiet and logger.isEnabledFor(logging.DEBUG): caller, filename, lineno = get_call_site(2, exclude_caller_module=True) logger.debug('{caller} ({filename}:{lineno}) has used key {key} from source "{src}": {val}'.format( diff --git a/lisa/energy_meter.py b/lisa/energy_meter.py index cc8971ca1f6a19f01b98c15c7b3296d43c1dc6fc..2f0a5655f328753d99ec32aff8f7d4efb1fb5243 100644 --- a/lisa/energy_meter.py +++ b/lisa/energy_meter.py @@ -144,7 +144,7 @@ class HWMon(EnergyMeter): def __init__(self, target, channel_map, res_dir=None): super().__init__(target, res_dir) - logger = self.get_logger() + logger = self.logger # Energy readings self.readings = {} @@ -193,7 +193,7 @@ class HWMon(EnergyMeter): def sample(self): - logger = self.get_logger() + logger = self.logger samples = self._hwmon.take_measurement() for s in samples: site = s.channel.site @@ -219,7 +219,7 @@ class HWMon(EnergyMeter): for site in self.readings: self.readings[site]['delta'] = 0 self.readings[site]['total'] = 0 - self.get_logger().debug('RESET: %s', self.readings) + self.logger.debug('RESET: %s', self.readings) def report(self, out_dir, out_file='energy.json'): # Retrive energy consumption data @@ -232,7 +232,7 @@ class HWMon(EnergyMeter): 'Selected channels: {}'.format( channel, list(nrg.keys()))) nrg_total = nrg[site]['total'] - self.get_logger().debug('Energy [%16s]: %.6f', site, nrg_total) + self.logger.debug('Energy [%16s]: %.6f', site, nrg_total) clusters_nrg[channel] = nrg_total # Dump data as JSON file @@ -323,7 +323,7 @@ class AEP(_DevlibContinuousEnergyMeter): def __init__(self, target, resistor_values, labels=None, device_entry='/dev/ttyACM0', res_dir=None): super().__init__(target, res_dir) - logger = self.get_logger() + logger = self.logger # Configure channels for energy measurements self._instrument = devlib.EnergyProbeInstrument( @@ -414,7 +414,7 @@ class ACME(EnergyMeter): host='baylibre-acme.local', iio_capture_bin='iio-capture', res_dir=None): super().__init__(target, res_dir) - logger = self.get_logger() + logger = self.logger self._iiocapturebin = iio_capture_bin self._hostname = host @@ -453,7 +453,7 @@ class ACME(EnergyMeter): Reset energy meter and start sampling from channels specified in the target configuration. """ - logger = self.get_logger() + logger = self.logger # Terminate already running iio-capture instance (if any) wait_for_termination = 0 for proc in psutil.process_iter(): @@ -526,7 +526,7 @@ class ACME(EnergyMeter): if delta < self.REPORT_DELAY_S: sleep(self.REPORT_DELAY_S - delta) - logger = self.get_logger() + logger = self.logger channels_nrg = {} channels_stats = {} for channel, ch_id in self._channels.items(): diff --git a/lisa/energy_model.py b/lisa/energy_model.py index c0a34f3a505d6eb8a2e388b14585dce71a904d50..fcb276139ae15966720f1125673c5dab8dceb08e 100644 --- a/lisa/energy_model.py +++ b/lisa/energy_model.py @@ -168,7 +168,7 @@ class EnergyModelNode(_CpuTree): def __init__(self, active_states, idle_states, cpu=None, children=None, name=None): super().__init__(cpu, children) - logger = self.get_logger() + logger = self.logger def is_monotonic(l, decreasing=False): op = operator.ge if decreasing else operator.le @@ -343,7 +343,7 @@ class EnergyModel(Serializable, Loggable): """ def __init__(self, root_node, root_power_domain, freq_domains): - logger = self.get_logger() + logger = self.logger self.cpus = root_node.cpus if self.cpus != tuple(range(len(self.cpus))): raise ValueError('CPU IDs [{}] are sparse'.format(self.cpus)) @@ -711,7 +711,7 @@ class EnergyModel(Serializable, Loggable): num_candidates = len(self.cpus) ** len(tasks) - logger = self.get_logger() + logger = self.logger logger.debug( '%14s - Searching %d configurations for optimal task placement...', 'EnergyModel', num_candidates) diff --git a/lisa/target.py b/lisa/target.py index 387893efbd3bc39b5e7d20ef51124a7ea9974d17..36a4777eb4dd5455b9d0a210ddefccb0c9c3c846 100644 --- a/lisa/target.py +++ b/lisa/target.py @@ -214,7 +214,7 @@ class Target(Loggable, HideExekallID, ExekallTaggable, Configurable): ): super().__init__() - logger = self.get_logger() + logger = self.logger self.name = name @@ -496,7 +496,7 @@ class Target(Loggable, HideExekallID, ExekallTaggable, Configurable): """ Initialize the Target """ - logger = self.get_logger() + logger = self.logger conn_settings = {} # If the target is Android, we need just (eventually) the device @@ -647,7 +647,7 @@ class Target(Loggable, HideExekallID, ExekallTaggable, Configurable): ) def _get_res_dir(self, root, relative, name, append_time, symlink): - logger = self.get_logger() + logger = self.logger while True: time_str = datetime.now().strftime('%Y%m%d_%H%M%S.%f') if not name: @@ -721,7 +721,7 @@ class Target(Loggable, HideExekallID, ExekallTaggable, Configurable): """ Context manager that lets you freeze the userspace """ - logger = self.get_logger() + logger = self.logger if 'cgroups' not in self.target.modules: raise RuntimeError('Could not freeze userspace: "cgroups" devlib module is necessary') @@ -762,7 +762,7 @@ class Target(Loggable, HideExekallID, ExekallTaggable, Configurable): # This assumes that freq domains are tied to "idle domains" # We'll have to change this if this assumption no longer holds true - logger = self.get_logger() + logger = self.logger logger.info('Disabling idle states for all domains') try: diff --git a/lisa/tests/base.py b/lisa/tests/base.py index 41e494c7a4c84709e714a53081d6640dd5d47ba4..686aedc57a1840c8e3cc74df48ae1b3e27058cbe 100644 --- a/lisa/tests/base.py +++ b/lisa/tests/base.py @@ -910,7 +910,7 @@ class DmesgTestBundle(TestBundle): # Consider as an issue all levels more critical than `level` issue_levels = levels[:levels.index(level) + 1] - logger = self.get_logger() + logger = self.logger if ignored_patterns: logger.info('Will ignore patterns in dmesg output: {}'.format(ignored_patterns)) @@ -1147,7 +1147,7 @@ class RTATestBundle(FtraceTestBundle, DmesgTestBundle): if df_filter_task_ids(df, [task_id]).iloc[0].runtime_pct <= threshold ) - self.get_logger().info("Ignored PIDs for noise contribution: {}".format( + self.logger.info("Ignored PIDs for noise contribution: {}".format( ", ".join(map(str, ignored_ids)) )) diff --git a/lisa/tests/scheduler/load_tracking.py b/lisa/tests/scheduler/load_tracking.py index 376e17bba3c8d8b5deeee435ddadfdadefcb74f0..e950ba4dced33ed44bfae1cf3a10d8a3242d28cc 100644 --- a/lisa/tests/scheduler/load_tracking.py +++ b/lisa/tests/scheduler/load_tracking.py @@ -317,7 +317,7 @@ class InvarianceItem(LoadTrackingBase, ExekallTaggable): signal_name == 'load' and kernel_version.parts[:2] < (5, 1) ): - self.get_logger().warning('Load signal is assumed to be CPU invariant, which is true for recent mainline kernels, but may be wrong for {}'.format( + self.logger.warning('Load signal is assumed to be CPU invariant, which is true for recent mainline kernels, but may be wrong for {}'.format( kernel_version, )) @@ -576,7 +576,7 @@ class Invariance(TestBundle, LoadTrackingHelpers): .. seealso:: :class:`InvarianceItem.test_task_util_avg` """ - logger = self.get_logger() + logger = self.logger def make_group_bundle(cpu, item_group): bundle = AggregatedResultBundle( @@ -693,7 +693,7 @@ class PELTTask(LoadTrackingBase): containing the simulated signal, along with the column of the signal as found in the trace. """ - logger = self.get_logger() + logger = self.logger trace = self.trace task = trace.get_task_id(task) cpus = trace.analysis.tasks.cpus_of_tasks([task]) diff --git a/lisa/tests/staging/sched_android.py b/lisa/tests/staging/sched_android.py index 752bb4eb7a053f740771e7c5d901ed3c30c4f4c7..1ea4215eaa08af3cd28381e0693ba91df1ffc339 100644 --- a/lisa/tests/staging/sched_android.py +++ b/lisa/tests/staging/sched_android.py @@ -177,7 +177,7 @@ class SchedTuneFreqItem(SchedTuneItemBase): """ kernel_version = self.plat_info['kernel']['version'] if kernel_version.parts[:2] < (4, 14): - self.get_logger().warning('This test requires the RT boost hold, but it may be disabled in {}'.format(kernel_version)) + self.logger.warning('This test requires the RT boost hold, but it may be disabled in {}'.format(kernel_version)) cpu = self.plat_info['capacity-classes'][-1][0] freqs = self.plat_info['freqs'][cpu] diff --git a/lisa/trace.py b/lisa/trace.py index 3b952a6cc8f1b17052340db0d2b42022db6f086b..10a2bf384640fb7bd315149bd2282f089f4107b8 100644 --- a/lisa/trace.py +++ b/lisa/trace.py @@ -304,7 +304,7 @@ class Trace(Loggable, TraceBase): super().__init__() - logger = self.get_logger() + logger = self.logger if plat_info is None: plat_info = PlatformInfo() @@ -338,7 +338,7 @@ class Trace(Loggable, TraceBase): max_cpu = max(int(self.df_events(e)['__cpu'].max()) for e in self.available_events) count = max_cpu + 1 - self.get_logger().info("Estimated CPU count from trace: %s", count) + self.logger.info("Estimated CPU count from trace: %s", count) return count @deprecate('Direct access to underlying ftrace object is discouraged as this is now an implementation detail of that class which could change in the future', @@ -390,7 +390,7 @@ class Trace(Loggable, TraceBase): - SysTrace :type trace_format: str """ - logger = self.get_logger() + logger = self.logger logger.debug('Loading [sched] events from trace in [%s]...', path) logger.debug('Parsing events: %s', self.events) if trace_format.upper() == 'SYSTRACE' or path.endswith('html'): @@ -437,7 +437,7 @@ class Trace(Loggable, TraceBase): :param key: key to be used for TRAPpy filtering :type key: str """ - logger = self.get_logger() + logger = self.logger available_events = [] for val in self._ftrace.get_filters(key): obj = getattr(self._ftrace, val) @@ -527,7 +527,7 @@ class Trace(Loggable, TraceBase): self.end = self.start + duration self.time_range = self.end - self.start - self.get_logger().debug('Trace contains events from %s to %s', + self.logger.debug('Trace contains events from %s to %s', self.start, self.end) def get_task_name_pids(self, name, ignore_fork=True): @@ -837,7 +837,7 @@ class Trace(Loggable, TraceBase): Also convert between existing field name formats for sched_energy_diff """ - logger = self.get_logger() + logger = self.logger if not self.has_events('sched_energy_diff') \ or 'nrg-model' not in self.plat_info: return @@ -918,7 +918,7 @@ class Trace(Loggable, TraceBase): """ Rename some columns and add fake devlib frequency events """ - logger = self.get_logger() + logger = self.logger if not self.has_events('cpu_frequency_devlib') \ or 'freq-domains' not in self.plat_info: return diff --git a/lisa/utils.py b/lisa/utils.py index 06bbbf88f1bda396d1db41808d062e3b48fdef5f..b707177b70da4eeaef509bf380e83f96e892de1d 100644 --- a/lisa/utils.py +++ b/lisa/utils.py @@ -101,6 +101,24 @@ class Loggable: name += '.' + suffix return logging.getLogger(name) + @property + def logger(self): + """ + Default logger, shorthand to ``self.logger``. + """ + try: + return self.__dict__['logger'] + except KeyError: + logger = self.get_logger() + self.logger = logger + return logger + + # Devlib sets logger attribute on some of its classes, which means this + # property has to be settable + @logger.setter + def logger(self, logger): + self.__dict__['logger'] = logger + @classmethod def log_locals(cls, var_names=None, level='debug'): """ diff --git a/lisa/wa_results_collector.py b/lisa/wa_results_collector.py index 54006ca84f8c4876682400cea8d580968331c2ae..c4807b885c7c558353dcfc810f171b5e90914c8f 100644 --- a/lisa/wa_results_collector.py +++ b/lisa/wa_results_collector.py @@ -127,7 +127,7 @@ class WaResultsCollector(Loggable): kernel_repo_path=None, parse_traces=True, use_cached_trace_metrics=True, display_charts=True): - logger = self.get_logger() + logger = self.logger if base_dir: base_dir = os.path.expanduser(base_dir) @@ -178,7 +178,7 @@ class WaResultsCollector(Loggable): def _list_wa_dirs(self, base_dir, wa_dirs_re): dirs = [] - logger = self.get_logger() + logger = self.logger logger.info("Processing WA3 dirs matching [%s], rooted at %s", wa_dirs_re, base_dir) wa_dirs_re = re.compile(wa_dirs_re) @@ -222,7 +222,7 @@ class WaResultsCollector(Loggable): # |- pelt-wk1-jankbench-2/ # [etc] - logger = self.get_logger() + logger = self.logger # results.csv contains all the metrics reported by WA for all jobs. df = pd.read_csv(os.path.join(wa_dir, 'results.csv')) @@ -393,7 +393,7 @@ class WaResultsCollector(Loggable): metric,value,units """ - logger = self.get_logger() + logger = self.logger cache_path = os.path.join(os.path.dirname(trace_path), 'lisa_trace_metrics.csv') if self.use_cached_trace_metrics and os.path.exists(cache_path): return pd.read_csv(cache_path) @@ -489,7 +489,7 @@ class WaResultsCollector(Loggable): metric,value,units """ - logger = self.get_logger() + logger = self.logger # return # value,metric,units extra_metric_list = [] @@ -625,7 +625,7 @@ class WaResultsCollector(Loggable): """ Common helper for getting results to plot for a given metric """ - logger = self.get_logger() + logger = self.logger df = self._select(tag, kernel, test) if df.empty: @@ -931,7 +931,7 @@ class WaResultsCollector(Loggable): :param tests: regular expression to filter tests that should be plotted :type tests: str """ - logger = self.get_logger() + logger = self.logger if not self.display_charts: return @@ -990,7 +990,7 @@ class WaResultsCollector(Loggable): 'kernel' column in the results_df uses). If by='tag' then `base_id` should be a WA 'tag id' (as named in the WA agenda). """ - logger = self.get_logger() + logger = self.logger comparisons = [] # I dunno why I wrote this with a namedtuple instead of just a dict or @@ -1095,7 +1095,7 @@ class WaResultsCollector(Loggable): should be a WA 'tag id' (as named in the WA agenda). """ - logger = self.get_logger() + logger = self.logger if not self.display_charts: return diff --git a/lisa/wlgen/rta.py b/lisa/wlgen/rta.py index b3d8fff55cbb3ab3208e70e9ad0e2f6224740b90..cdea99f42c1ac6a29fe01485ac600c8b64fc06e8 100644 --- a/lisa/wlgen/rta.py +++ b/lisa/wlgen/rta.py @@ -103,7 +103,7 @@ class RTA(Workload): def run(self, cpus=None, cgroup=None, background=False, as_root=False): super().run(cpus, cgroup, background, as_root) - logger = self.get_logger() + logger = self.logger if background: # TODO: handle background case @@ -493,7 +493,7 @@ class Phase(Loggable): :returns: OrderedDict """ - logger = self.get_logger() + logger = self.logger phase = OrderedDict() # Convert time parameters to integer [us] units duration = int(self.duration_s * 1e6) diff --git a/lisa/wlgen/workload.py b/lisa/wlgen/workload.py index 5a210b7ada56264258d5213fdae0c2110ee20571..1004d43e7e4673841b5f97f8f15eddf6090a864b 100644 --- a/lisa/wlgen/workload.py +++ b/lisa/wlgen/workload.py @@ -93,7 +93,7 @@ class Workload(Loggable): self.run_dir = target.execute("mktemp -d -p {} {}".format( quote(wlgen_dir), quote(temp_fmt))).strip() - logger = self.get_logger() + logger = self.logger logger.info("Creating target's run directory: %s", self.run_dir) res_dir = res_dir if res_dir else target.get_res_dir( @@ -111,7 +111,7 @@ class Workload(Loggable): sessions. For other purposes, use :class:`Workload` instances as a context manager. """ - logger = self.get_logger() + logger = self.logger logger.info("Wiping target run directory: {}".format(self.run_dir)) self.target.execute("rm -rf {}".format(quote(self.run_dir))) @@ -147,7 +147,7 @@ class Workload(Loggable): The standard output will be saved into a file in ``self.res_dir`` """ - logger = self.get_logger() + logger = self.logger if not self.command: raise RuntimeError("Workload does not specify any command to execute")