Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create start/pause/resume/stop sub-commands for 'ros2 trace' #70

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
12 changes: 12 additions & 0 deletions README.md
Expand Up @@ -133,6 +133,18 @@ By default, it will enable all ROS 2 tracepoints.
The trace will be written to `~/.ros/tracing/session-YYYYMMDDHHMMSS`.
Run the command with `-h` for more information.

The `ros2 trace` command requires user interaction to start and then stop tracing.
To trace without user interaction (e.g., in scripts), or for finer-grained tracing control, the following sub-commands can be used:

```
$ ros2 trace start session_name # Configure tracing session and start tracing
$ ros2 trace pause session_name # Pause tracing after starting
$ ros2 trace resume session_name # Resume tracing after pausing
$ ros2 trace stop session_name # Stop tracing after starting or resuming
```

Run each command with `-h` for more information.

You must [install the kernel tracer](#building) if you want to enable kernel events (using the `-k`/`--kernel-events` option).
If you have installed the kernel tracer, use kernel tracing, and still encounter an error here, make sure to [add your user to the `tracing` group](#tracing).

Expand Down
20 changes: 16 additions & 4 deletions ros2trace/ros2trace/command/trace.py
Expand Up @@ -14,16 +14,28 @@

"""Module for trace command extension implementation."""

from ros2cli.command import add_subparsers_on_demand
from ros2cli.command import CommandExtension
from tracetools_trace.tools import args
from tracetools_trace.trace import trace


class TraceCommand(CommandExtension):
"""Trace ROS nodes to get information on their execution."""
"""Trace ROS 2 nodes to get information on their execution. The main 'trace' command requires user interaction; to trace non-interactively, use the 'start'/'stop'/'pause'/'resume' sub-commands.""" # noqa: E501

def add_arguments(self, parser, cli_name):
def add_arguments(self, parser, cli_name) -> None:
self._subparser = parser
args.add_arguments(parser)

def main(self, *, parser, args):
return trace(args)
# Add arguments and sub-commands of verbs
add_subparsers_on_demand(parser, cli_name, '_verb', 'ros2trace.verb', required=False)

def main(self, *, parser, args) -> int:
if not hasattr(args, '_verb'):
# In case no verb was passed, do interactive tracing
return trace(args)

extension = getattr(args, '_verb')

# Call the verb's main method
return extension.main(args=args)
44 changes: 44 additions & 0 deletions ros2trace/ros2trace/verb/__init__.py
@@ -0,0 +1,44 @@
# Copyright 2017 Open Source Robotics Foundation, Inc.
mjcarroll marked this conversation as resolved.
Show resolved Hide resolved
#
# 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.

from ros2cli.plugin_system import PLUGIN_SYSTEM_VERSION
from ros2cli.plugin_system import satisfies_version


class VerbExtension:
"""
The extension point for 'trace' verb extensions.

The following properties must be defined:
* `NAME` (will be set to the entry point name)

The following methods must be defined:
* `main`

The following methods can be defined:
* `add_arguments`
"""

NAME = None
EXTENSION_POINT_VERSION = '0.1'

def __init__(self):
super(VerbExtension, self).__init__()
satisfies_version(PLUGIN_SYSTEM_VERSION, '^0.1')

def add_arguments(self, parser, cli_name):
pass

def main(self, *, args):
raise NotImplementedError()
27 changes: 27 additions & 0 deletions ros2trace/ros2trace/verb/pause.py
@@ -0,0 +1,27 @@
# Copyright 2023 Apex.AI, Inc.
#
# 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.

from ros2trace.verb import VerbExtension
from tracetools_trace.tools import args
from tracetools_trace.trace import pause


class PauseVerb(VerbExtension):
"""Pause tracing after starting."""

def add_arguments(self, parser, cli_name) -> None:
args.add_arguments_session_name(parser)

def main(self, *, args) -> int:
return pause(args)
27 changes: 27 additions & 0 deletions ros2trace/ros2trace/verb/resume.py
@@ -0,0 +1,27 @@
# Copyright 2023 Apex.AI, Inc.
#
# 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.

from ros2trace.verb import VerbExtension
from tracetools_trace.tools import args
from tracetools_trace.trace import resume


class ResumeVerb(VerbExtension):
"""Resume tracing after pausing."""

def add_arguments(self, parser, cli_name) -> None:
args.add_arguments_session_name(parser)

def main(self, *, args) -> int:
return resume(args)
27 changes: 27 additions & 0 deletions ros2trace/ros2trace/verb/start.py
@@ -0,0 +1,27 @@
# Copyright 2023 Apex.AI, Inc.
#
# 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.

from ros2trace.verb import VerbExtension
from tracetools_trace.tools import args
from tracetools_trace.trace import start


class StartVerb(VerbExtension):
"""Configure tracing session and start tracing."""

def add_arguments(self, parser, cli_name) -> None:
args.add_arguments_noninteractive(parser)

def main(self, *, args) -> int:
return start(args)
27 changes: 27 additions & 0 deletions ros2trace/ros2trace/verb/stop.py
@@ -0,0 +1,27 @@
# Copyright 2023 Apex.AI, Inc.
#
# 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.

from ros2trace.verb import VerbExtension
from tracetools_trace.tools import args
from tracetools_trace.trace import stop


class StopVerb(VerbExtension):
"""Stop tracing after starting or resuming."""

def add_arguments(self, parser, cli_name) -> None:
args.add_arguments_session_name(parser)

def main(self, *, args) -> int:
return stop(args)
9 changes: 9 additions & 0 deletions ros2trace/setup.py
Expand Up @@ -37,5 +37,14 @@
'ros2cli.command': [
f'trace = {package_name}.command.trace:TraceCommand',
],
'ros2cli.extension_point': [
f'{package_name}.verb = {package_name}.verb:VerbExtension',
],
f'{package_name}.verb': [
f'pause = {package_name}.verb.pause:PauseVerb',
f'resume = {package_name}.verb.resume:ResumeVerb',
f'start = {package_name}.verb.start:StartVerb',
f'stop = {package_name}.verb.stop:StopVerb',
],
}
)