From da605b42e3ece42e9a0103b4228da61c43bab794 Mon Sep 17 00:00:00 2001 From: Christophe Bedard Date: Sat, 3 Aug 2019 10:07:42 +0200 Subject: [PATCH 1/5] Move tracetools_read.utils to *.__init__ --- tracetools_read/tracetools_read/__init__.py | 87 +++++++++++++++++ tracetools_read/tracetools_read/utils.py | 100 -------------------- 2 files changed, 87 insertions(+), 100 deletions(-) delete mode 100644 tracetools_read/tracetools_read/utils.py diff --git a/tracetools_read/tracetools_read/__init__.py b/tracetools_read/tracetools_read/__init__.py index 4b18865..0396268 100644 --- a/tracetools_read/tracetools_read/__init__.py +++ b/tracetools_read/tracetools_read/__init__.py @@ -11,3 +11,90 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. + +"""Module with functions for reading traces.""" + +from typing import Any +from typing import Dict +from typing import Iterable +from typing import List + +import babeltrace + + +DictEvent = Dict[str, Any] + + +def _get_trace_ctf_events(trace_directory: str) -> Iterable[babeltrace.babeltrace.Event]: + """ + Get the events of a trace. + + :param trace_directory: the path to the main/top trace directory + :return: events iterable + """ + tc = babeltrace.TraceCollection() + tc.add_traces_recursive(trace_directory, 'ctf') + return tc.events + + +def get_trace_events(trace_directory: str) -> List[DictEvent]: + """ + Get the events of a trace. + + :param trace_directory: the path to the main/top trace directory + :return: events + """ + return [event_to_dict(event) for event in _get_trace_ctf_events(trace_directory)] + + +# List of ignored CTF fields +_IGNORED_FIELDS = [ + 'content_size', + 'events_discarded', + 'id', + 'packet_size', + 'packet_seq_num', + 'stream_id', + 'stream_instance_id', + 'timestamp_end', + 'timestamp_begin', + 'magic', + 'uuid', + 'v', +] +_DISCARD = 'events_discarded' + + +def event_to_dict(event: babeltrace.babeltrace.Event) -> DictEvent: + """ + Convert name, timestamp, and all other keys except those in IGNORED_FIELDS into a dictionary. + + :param event: the event to convert + :return: the event as a dictionary + """ + d = {'_name': event.name, '_timestamp': event.timestamp} + if hasattr(event, _DISCARD) and event[_DISCARD] > 0: + print(event[_DISCARD]) + for key in [key for key in event.keys() if key not in _IGNORED_FIELDS]: + d[key] = event[key] + return d + + +def get_field(event: DictEvent, field_name: str, default=None, raise_if_not_found=True) -> Any: + field_value = event.get(field_name, default) + # If enabled, raise exception as soon as possible to avoid headaches + if raise_if_not_found and field_value is None: + raise AttributeError(f"event field '{field_name}' not found for event: {event}") + return field_value + + +def get_event_name(event: DictEvent) -> str: + return event['_name'] + + +def get_event_timestamp(event: DictEvent) -> int: + return event['_timestamp'] + + +def get_procname(event: DictEvent) -> str: + return event['procname'] diff --git a/tracetools_read/tracetools_read/utils.py b/tracetools_read/tracetools_read/utils.py deleted file mode 100644 index 0396268..0000000 --- a/tracetools_read/tracetools_read/utils.py +++ /dev/null @@ -1,100 +0,0 @@ -# Copyright 2019 Robert Bosch GmbH -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Module with functions for reading traces.""" - -from typing import Any -from typing import Dict -from typing import Iterable -from typing import List - -import babeltrace - - -DictEvent = Dict[str, Any] - - -def _get_trace_ctf_events(trace_directory: str) -> Iterable[babeltrace.babeltrace.Event]: - """ - Get the events of a trace. - - :param trace_directory: the path to the main/top trace directory - :return: events iterable - """ - tc = babeltrace.TraceCollection() - tc.add_traces_recursive(trace_directory, 'ctf') - return tc.events - - -def get_trace_events(trace_directory: str) -> List[DictEvent]: - """ - Get the events of a trace. - - :param trace_directory: the path to the main/top trace directory - :return: events - """ - return [event_to_dict(event) for event in _get_trace_ctf_events(trace_directory)] - - -# List of ignored CTF fields -_IGNORED_FIELDS = [ - 'content_size', - 'events_discarded', - 'id', - 'packet_size', - 'packet_seq_num', - 'stream_id', - 'stream_instance_id', - 'timestamp_end', - 'timestamp_begin', - 'magic', - 'uuid', - 'v', -] -_DISCARD = 'events_discarded' - - -def event_to_dict(event: babeltrace.babeltrace.Event) -> DictEvent: - """ - Convert name, timestamp, and all other keys except those in IGNORED_FIELDS into a dictionary. - - :param event: the event to convert - :return: the event as a dictionary - """ - d = {'_name': event.name, '_timestamp': event.timestamp} - if hasattr(event, _DISCARD) and event[_DISCARD] > 0: - print(event[_DISCARD]) - for key in [key for key in event.keys() if key not in _IGNORED_FIELDS]: - d[key] = event[key] - return d - - -def get_field(event: DictEvent, field_name: str, default=None, raise_if_not_found=True) -> Any: - field_value = event.get(field_name, default) - # If enabled, raise exception as soon as possible to avoid headaches - if raise_if_not_found and field_value is None: - raise AttributeError(f"event field '{field_name}' not found for event: {event}") - return field_value - - -def get_event_name(event: DictEvent) -> str: - return event['_name'] - - -def get_event_timestamp(event: DictEvent) -> int: - return event['_timestamp'] - - -def get_procname(event: DictEvent) -> str: - return event['procname'] From e908c44fafffcccb83fb02cbb8cf74fa9f9c4b1c Mon Sep 17 00:00:00 2001 From: Christophe Bedard Date: Sat, 3 Aug 2019 10:08:08 +0200 Subject: [PATCH 2/5] Remove leading underscore from get_trace_ctf_events() --- tracetools_read/tracetools_read/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tracetools_read/tracetools_read/__init__.py b/tracetools_read/tracetools_read/__init__.py index 0396268..c627fd5 100644 --- a/tracetools_read/tracetools_read/__init__.py +++ b/tracetools_read/tracetools_read/__init__.py @@ -25,7 +25,7 @@ import babeltrace DictEvent = Dict[str, Any] -def _get_trace_ctf_events(trace_directory: str) -> Iterable[babeltrace.babeltrace.Event]: +def get_trace_ctf_events(trace_directory: str) -> Iterable[babeltrace.babeltrace.Event]: """ Get the events of a trace. @@ -44,7 +44,7 @@ def get_trace_events(trace_directory: str) -> List[DictEvent]: :param trace_directory: the path to the main/top trace directory :return: events """ - return [event_to_dict(event) for event in _get_trace_ctf_events(trace_directory)] + return [event_to_dict(event) for event in get_trace_ctf_events(trace_directory)] # List of ignored CTF fields From 9ddfaae8526a5c044e1213a8525e794b2c2a88ed Mon Sep 17 00:00:00 2001 From: Christophe Bedard Date: Sat, 3 Aug 2019 10:19:32 +0200 Subject: [PATCH 3/5] Add typing info and docstring for get_field() --- tracetools_read/tracetools_read/__init__.py | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/tracetools_read/tracetools_read/__init__.py b/tracetools_read/tracetools_read/__init__.py index c627fd5..000a3b4 100644 --- a/tracetools_read/tracetools_read/__init__.py +++ b/tracetools_read/tracetools_read/__init__.py @@ -80,7 +80,24 @@ def event_to_dict(event: babeltrace.babeltrace.Event) -> DictEvent: return d -def get_field(event: DictEvent, field_name: str, default=None, raise_if_not_found=True) -> Any: +def get_field( + event: DictEvent, + field_name: str, + default: Any = None, + raise_if_not_found: bool = True, +) -> Any: + """ + Get value of a field from an event. + + Can return a custom default value if not found. Will raise `AttributeError` by default if not + found, but it can be suppressed. These two options cannot be used together. + + :param event: the event + :param field_name: the name of the field + :param default: the value to use if not found + :param raise_if_not_found: whether to raise an error the field is not found + :return: `None` (or default value) if not found + """ field_value = event.get(field_name, default) # If enabled, raise exception as soon as possible to avoid headaches if raise_if_not_found and field_value is None: From 3b98bca63b4b49b1581a4928fe5ef6125ddf4590 Mon Sep 17 00:00:00 2001 From: Christophe Bedard Date: Sat, 3 Aug 2019 10:39:39 +0200 Subject: [PATCH 4/5] Make event_to_dict() more Pythonic --- tracetools_read/tracetools_read/__init__.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/tracetools_read/tracetools_read/__init__.py b/tracetools_read/tracetools_read/__init__.py index 000a3b4..c689173 100644 --- a/tracetools_read/tracetools_read/__init__.py +++ b/tracetools_read/tracetools_read/__init__.py @@ -72,12 +72,11 @@ def event_to_dict(event: babeltrace.babeltrace.Event) -> DictEvent: :param event: the event to convert :return: the event as a dictionary """ - d = {'_name': event.name, '_timestamp': event.timestamp} if hasattr(event, _DISCARD) and event[_DISCARD] > 0: print(event[_DISCARD]) - for key in [key for key in event.keys() if key not in _IGNORED_FIELDS]: - d[key] = event[key] - return d + meta = {'_name': event.name, '_timestamp': event.timestamp} + data = {key: event[key] for key in event.keys() if key not in _IGNORED_FIELDS} + return {**meta, **data} def get_field( From 7ad97f450dad750ef2907e28ae8a983d81f80512 Mon Sep 17 00:00:00 2001 From: Christophe Bedard Date: Sat, 3 Aug 2019 10:49:06 +0200 Subject: [PATCH 5/5] Update tracetools_read imports --- tracetools_test/tracetools_test/case.py | 12 ++++++------ tracetools_test/tracetools_test/utils.py | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/tracetools_test/tracetools_test/case.py b/tracetools_test/tracetools_test/case.py index c581b7a..94bb291 100644 --- a/tracetools_test/tracetools_test/case.py +++ b/tracetools_test/tracetools_test/case.py @@ -20,12 +20,12 @@ from typing import List from typing import Union import unittest -from tracetools_read.utils import DictEvent -from tracetools_read.utils import get_event_name -from tracetools_read.utils import get_event_timestamp -from tracetools_read.utils import get_field -from tracetools_read.utils import get_procname -from tracetools_read.utils import get_trace_events +from tracetools_read import DictEvent +from tracetools_read import get_event_name +from tracetools_read import get_event_timestamp +from tracetools_read import get_field +from tracetools_read import get_procname +from tracetools_read import get_trace_events from .utils import cleanup_trace from .utils import get_event_names diff --git a/tracetools_test/tracetools_test/utils.py b/tracetools_test/tracetools_test/utils.py index 3a976de..a212f12 100644 --- a/tracetools_test/tracetools_test/utils.py +++ b/tracetools_test/tracetools_test/utils.py @@ -25,8 +25,8 @@ from launch import LaunchService from launch_ros import get_default_launch_description from launch_ros.actions import Node from tracetools_launch.action import Trace -from tracetools_read.utils import DictEvent -from tracetools_read.utils import get_event_name +from tracetools_read import DictEvent +from tracetools_read import get_event_name def run_and_trace(