Merge branch 'add-other-base-packages' into 'master'
Add other base packages Closes #6 See merge request micro-ROS/ros2_tracing!16
This commit is contained in:
commit
424a489828
33 changed files with 1128 additions and 2 deletions
3
ros2trace/.gitignore
vendored
Normal file
3
ros2trace/.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
*~
|
||||||
|
*.pyc
|
||||||
|
|
26
ros2trace/package.xml
Normal file
26
ros2trace/package.xml
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<?xml-model href="http://download.ros.org/schema/package_format2.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
|
||||||
|
<package format="2">
|
||||||
|
<name>ros2trace</name>
|
||||||
|
<version>0.0.1</version>
|
||||||
|
<description>
|
||||||
|
The trace command for ROS 2 command line tools.
|
||||||
|
</description>
|
||||||
|
<maintainer email="fixed-term.christophe.bourquebedard@de.bosch.com">Christophe Bedard</maintainer>
|
||||||
|
<maintainer email="ingo.luetkebohle@de.bosch.com">Ingo Lütkebohle</maintainer>
|
||||||
|
<license>Apache 2.0</license>
|
||||||
|
<author email="fixed-term.christophe.bourquebedard@de.bosch.com">Christophe Bedard</author>
|
||||||
|
|
||||||
|
<depend>ros2cli</depend>
|
||||||
|
<depend>tracetools_trace</depend>
|
||||||
|
|
||||||
|
<test_depend>ament_copyright</test_depend>
|
||||||
|
<test_depend>ament_flake8</test_depend>
|
||||||
|
<test_depend>ament_pep257</test_depend>
|
||||||
|
<test_depend>ament_xmllint</test_depend>
|
||||||
|
<test_depend>python3-pytest</test_depend>
|
||||||
|
|
||||||
|
<export>
|
||||||
|
<build_type>ament_python</build_type>
|
||||||
|
</export>
|
||||||
|
</package>
|
13
ros2trace/ros2trace/__init__.py
Normal file
13
ros2trace/ros2trace/__init__.py
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
# 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.
|
68
ros2trace/ros2trace/api/__init__.py
Normal file
68
ros2trace/ros2trace/api/__init__.py
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
"""API functions for the ROS 2 trace command."""
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
from tracetools_trace.tools import args
|
||||||
|
from tracetools_trace.tools import lttng
|
||||||
|
|
||||||
|
|
||||||
|
def add_trace_arguments(parser):
|
||||||
|
args.add_arguments(parser)
|
||||||
|
|
||||||
|
|
||||||
|
def init(args):
|
||||||
|
"""
|
||||||
|
Init and start tracing.
|
||||||
|
|
||||||
|
:param args: the parsed arguments object containing the right fields
|
||||||
|
"""
|
||||||
|
session_name = args.session_name
|
||||||
|
base_path = args.path
|
||||||
|
full_path = os.path.join(base_path, session_name)
|
||||||
|
ros_events = args.events_ust
|
||||||
|
kernel_events = args.events_kernel
|
||||||
|
|
||||||
|
ust_enabled = len(ros_events) > 0
|
||||||
|
kernel_enabled = len(kernel_events) > 0
|
||||||
|
if ust_enabled:
|
||||||
|
print(f'UST tracing enabled ({len(ros_events)} events)')
|
||||||
|
if args.list:
|
||||||
|
print(f'\tevents: {ros_events}')
|
||||||
|
else:
|
||||||
|
print('UST tracing disabled')
|
||||||
|
if kernel_enabled:
|
||||||
|
print(f'kernel tracing enabled ({len(kernel_events)} events)')
|
||||||
|
if args.list:
|
||||||
|
print(f'\tevents: {kernel_events}')
|
||||||
|
else:
|
||||||
|
print('kernel tracing disabled')
|
||||||
|
|
||||||
|
print(f'writting tracing session to: {full_path}')
|
||||||
|
input('press enter to start...')
|
||||||
|
lttng.lttng_init(session_name, full_path, ros_events=ros_events, kernel_events=kernel_events)
|
||||||
|
|
||||||
|
|
||||||
|
def fini(args):
|
||||||
|
"""
|
||||||
|
Stop and finalize tracing.
|
||||||
|
|
||||||
|
:param args: the parsed arguments object containing the right fields
|
||||||
|
"""
|
||||||
|
session_name = args.session_name
|
||||||
|
input('press enter to stop...')
|
||||||
|
print('stopping & destroying tracing session')
|
||||||
|
lttng.lttng_fini(session_name)
|
13
ros2trace/ros2trace/command/__init__.py
Normal file
13
ros2trace/ros2trace/command/__init__.py
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
# 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.
|
32
ros2trace/ros2trace/command/trace.py
Normal file
32
ros2trace/ros2trace/command/trace.py
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
# 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 for trace command extension implementation."""
|
||||||
|
|
||||||
|
from ros2cli.command import CommandExtension
|
||||||
|
from ros2trace.api import add_trace_arguments
|
||||||
|
from ros2trace.api import init
|
||||||
|
from ros2trace.api import fini
|
||||||
|
|
||||||
|
|
||||||
|
class TraceCommand(CommandExtension):
|
||||||
|
"""Trace ROS nodes to get information on their execution."""
|
||||||
|
|
||||||
|
def add_arguments(self, parser, cli_name):
|
||||||
|
add_trace_arguments(parser)
|
||||||
|
|
||||||
|
def main(self, *, parser, args):
|
||||||
|
init(args)
|
||||||
|
fini(args)
|
||||||
|
return 0
|
26
ros2trace/setup.py
Normal file
26
ros2trace/setup.py
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
from setuptools import find_packages
|
||||||
|
from setuptools import setup
|
||||||
|
|
||||||
|
setup(
|
||||||
|
name='ros2trace',
|
||||||
|
version='0.0.1',
|
||||||
|
packages=find_packages(exclude=['test']),
|
||||||
|
install_requires=['ros2cli'],
|
||||||
|
zip_safe=True,
|
||||||
|
maintainer='Christophe Bedard, Ingo Lütkebohle',
|
||||||
|
maintainer_email='fixed-term.christophe.bourquebedard@de.bosch.com, ingo.luetkebohle@de.bosch.com',
|
||||||
|
author='Christophe Bedard',
|
||||||
|
author_email='fixed-term.christophe.bourquebedard@de.bosch.com',
|
||||||
|
# url=',
|
||||||
|
keywords=[],
|
||||||
|
description='The run command for ROS 2 command line tools.',
|
||||||
|
long_description="""\
|
||||||
|
The package provides the trace command for the ROS 2 command line tools.""",
|
||||||
|
license='Apache 2.0',
|
||||||
|
tests_require=['pytest'],
|
||||||
|
entry_points={
|
||||||
|
'ros2cli.command': [
|
||||||
|
'trace = ros2trace.command.trace:TraceCommand',
|
||||||
|
],
|
||||||
|
}
|
||||||
|
)
|
23
ros2trace/test/test_copyright.py
Normal file
23
ros2trace/test/test_copyright.py
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
# Copyright 2017 Open Source Robotics Foundation, 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 ament_copyright.main import main
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.copyright
|
||||||
|
@pytest.mark.linter
|
||||||
|
def test_copyright():
|
||||||
|
rc = main(argv=['.', 'test'])
|
||||||
|
assert rc == 0, 'Found errors'
|
23
ros2trace/test/test_flake8.py
Normal file
23
ros2trace/test/test_flake8.py
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
# Copyright 2017 Open Source Robotics Foundation, 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 ament_flake8.main import main
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.flake8
|
||||||
|
@pytest.mark.linter
|
||||||
|
def test_flake8():
|
||||||
|
rc = main(argv=[])
|
||||||
|
assert rc == 0, 'Found errors'
|
23
ros2trace/test/test_pep257.py
Normal file
23
ros2trace/test/test_pep257.py
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
# Copyright 2017 Open Source Robotics Foundation, 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 ament_pep257.main import main
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.linter
|
||||||
|
@pytest.mark.pep257
|
||||||
|
def test_pep257():
|
||||||
|
rc = main(argv=[])
|
||||||
|
assert rc == 0, 'Found code style errors / warnings'
|
23
ros2trace/test/test_xmllint.py
Normal file
23
ros2trace/test/test_xmllint.py
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
# Copyright 2019 Open Source Robotics Foundation, 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 ament_xmllint.main import main
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.linter
|
||||||
|
@pytest.mark.xmllint
|
||||||
|
def test_xmllint():
|
||||||
|
rc = main(argv=[])
|
||||||
|
assert rc == 0, 'Found errors'
|
|
@ -6,7 +6,7 @@
|
||||||
<description>ROS 2 wrapper for instrumentation</description>
|
<description>ROS 2 wrapper for instrumentation</description>
|
||||||
<maintainer email="fixed-term.christophe.bourquebedard@de.bosch.com">Christophe Bedard</maintainer>
|
<maintainer email="fixed-term.christophe.bourquebedard@de.bosch.com">Christophe Bedard</maintainer>
|
||||||
<maintainer email="ingo.luetkebohle@de.bosch.com">Ingo Luetkebohle</maintainer>
|
<maintainer email="ingo.luetkebohle@de.bosch.com">Ingo Luetkebohle</maintainer>
|
||||||
<license>Apache Software License 2.0</license>
|
<license>Apache 2.0</license>
|
||||||
<author email="ingo.luetkebohle@de.bosch.com">Ingo Luetkebohle</author>
|
<author email="ingo.luetkebohle@de.bosch.com">Ingo Luetkebohle</author>
|
||||||
<author email="fixed-term.christophe.bourquebedard@de.bosch.com">Christophe Bedard</author>
|
<author email="fixed-term.christophe.bourquebedard@de.bosch.com">Christophe Bedard</author>
|
||||||
|
|
||||||
|
|
3
tracetools_launch/.gitignore
vendored
Normal file
3
tracetools_launch/.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
*~
|
||||||
|
*.pyc
|
||||||
|
|
35
tracetools_launch/launch/example.launch.py
Normal file
35
tracetools_launch/launch/example.launch.py
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
"""Example launch file for the Trace action."""
|
||||||
|
|
||||||
|
from launch import LaunchDescription
|
||||||
|
from launch_ros.actions import Node
|
||||||
|
from tracetools_launch.trace import Trace
|
||||||
|
|
||||||
|
|
||||||
|
def generate_launch_description():
|
||||||
|
return LaunchDescription([
|
||||||
|
Trace(
|
||||||
|
session_name='my-tracing-session',
|
||||||
|
base_path='/tmp'),
|
||||||
|
Node(
|
||||||
|
package='examples_rclcpp_minimal_publisher',
|
||||||
|
node_executable='publisher_member_function',
|
||||||
|
output='screen'),
|
||||||
|
Node(
|
||||||
|
package='examples_rclcpp_minimal_subscriber',
|
||||||
|
node_executable='subscriber_member_function',
|
||||||
|
output='screen'),
|
||||||
|
])
|
24
tracetools_launch/package.xml
Normal file
24
tracetools_launch/package.xml
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<?xml-model href="http://download.ros.org/schema/package_format2.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
|
||||||
|
<package format="2">
|
||||||
|
<name>tracetools_launch</name>
|
||||||
|
<version>0.0.1</version>
|
||||||
|
<description>Launch integration for tracing</description>
|
||||||
|
<maintainer email="fixed-term.christophe.bourquebedard@de.bosch.com">Christophe Bedard</maintainer>
|
||||||
|
<maintainer email="ingo.luetkebohle@de.bosch.com">Ingo Lütkebohle</maintainer>
|
||||||
|
<license>Apache 2.0</license>
|
||||||
|
<author email="fixed-term.christophe.bourquebedard@de.bosch.com">Christophe Bedard</author>
|
||||||
|
|
||||||
|
<depend>launch</depend>
|
||||||
|
<depend>launch_ros</depend>
|
||||||
|
<depend>tracetools_trace</depend>
|
||||||
|
|
||||||
|
<test_depend>ament_copyright</test_depend>
|
||||||
|
<test_depend>ament_flake8</test_depend>
|
||||||
|
<test_depend>ament_pep257</test_depend>
|
||||||
|
<test_depend>python3-pytest</test_depend>
|
||||||
|
|
||||||
|
<export>
|
||||||
|
<build_type>ament_python</build_type>
|
||||||
|
</export>
|
||||||
|
</package>
|
4
tracetools_launch/setup.cfg
Normal file
4
tracetools_launch/setup.cfg
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
[develop]
|
||||||
|
script-dir=$base/lib/tracetools_launch
|
||||||
|
[install]
|
||||||
|
install-scripts=$base/lib/tracetools_launch
|
26
tracetools_launch/setup.py
Normal file
26
tracetools_launch/setup.py
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
import glob
|
||||||
|
|
||||||
|
from setuptools import find_packages
|
||||||
|
from setuptools import setup
|
||||||
|
|
||||||
|
package_name = 'tracetools_launch'
|
||||||
|
|
||||||
|
setup(
|
||||||
|
name=package_name,
|
||||||
|
version='0.0.1',
|
||||||
|
packages=find_packages(exclude=['test']),
|
||||||
|
data_files=[
|
||||||
|
('share/' + package_name, ['package.xml']),
|
||||||
|
('share/' + package_name + '/launch', glob.glob('launch/*.launch.py')),
|
||||||
|
],
|
||||||
|
install_requires=['setuptools'],
|
||||||
|
maintainer='Christophe Bedard, Ingo Lütkebohle',
|
||||||
|
maintainer_email='fixed-term.christophe.bourquebedard@de.bosch.com, ingo.luetkebohle@de.bosch.com',
|
||||||
|
author='Christophe Bedard',
|
||||||
|
author_email='fixed-term.christophe.bourquebedard@de.bosch.com',
|
||||||
|
# url='',
|
||||||
|
keywords=['ROS'],
|
||||||
|
description='Launch integration for tracing',
|
||||||
|
license='Apache 2.0',
|
||||||
|
tests_require=['pytest'],
|
||||||
|
)
|
13
tracetools_launch/tracetools_launch/__init__.py
Normal file
13
tracetools_launch/tracetools_launch/__init__.py
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
# 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.
|
82
tracetools_launch/tracetools_launch/trace.py
Normal file
82
tracetools_launch/tracetools_launch/trace.py
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
# 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 for the Trace action."""
|
||||||
|
|
||||||
|
import os
|
||||||
|
from typing import List
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
from launch.action import Action
|
||||||
|
from launch.event import Event
|
||||||
|
from launch.event_handlers import OnShutdown
|
||||||
|
from launch.launch_context import LaunchContext
|
||||||
|
from tracetools_trace.tools import lttng
|
||||||
|
from tracetools_trace.tools import names
|
||||||
|
|
||||||
|
|
||||||
|
class Trace(Action):
|
||||||
|
"""
|
||||||
|
Tracing action for launch.
|
||||||
|
|
||||||
|
Sets up and enables tracing through a launch file description.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
*,
|
||||||
|
session_name: str,
|
||||||
|
base_path: str = '/tmp',
|
||||||
|
events_ust: List[str] = names.DEFAULT_EVENTS_ROS,
|
||||||
|
events_kernel: List[str] = names.DEFAULT_EVENTS_KERNEL,
|
||||||
|
**kwargs,
|
||||||
|
) -> None:
|
||||||
|
"""
|
||||||
|
Constructor.
|
||||||
|
|
||||||
|
:param session_name: the name of the tracing session
|
||||||
|
:param base_path: the base directory in which to create the trace directory
|
||||||
|
:param events_ust: the list of ROS UST events to enable
|
||||||
|
:param events_kernel: the list of kernel events to enable
|
||||||
|
"""
|
||||||
|
super().__init__(**kwargs)
|
||||||
|
self.__session_name = session_name
|
||||||
|
self.__path = os.path.join(base_path, session_name)
|
||||||
|
self.__events_ust = events_ust
|
||||||
|
self.__events_kernel = events_kernel
|
||||||
|
|
||||||
|
def execute(self, context: LaunchContext) -> Optional[List[Action]]:
|
||||||
|
# TODO make sure this is done as late as possible
|
||||||
|
context.register_event_handler(OnShutdown(on_shutdown=self._destroy))
|
||||||
|
# TODO make sure this is done as early as possible
|
||||||
|
self._setup()
|
||||||
|
|
||||||
|
def _setup(self) -> None:
|
||||||
|
lttng.lttng_init(
|
||||||
|
self.__session_name,
|
||||||
|
self.__path,
|
||||||
|
ros_events=self.__events_ust,
|
||||||
|
kernel_events=self.__events_kernel)
|
||||||
|
|
||||||
|
def _destroy(self, event: Event, context: LaunchContext) -> None:
|
||||||
|
lttng.lttng_fini(self.__session_name)
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return (
|
||||||
|
"Trace("
|
||||||
|
f"session_name='{self.__session_name}', "
|
||||||
|
f"path='{self.__path}', "
|
||||||
|
f"num_events_ust={len(self.__events_ust)}, "
|
||||||
|
f"num_events_kernel={len(self.__events_kernel)})"
|
||||||
|
)
|
|
@ -6,7 +6,7 @@
|
||||||
<description>Separate test package for tracetools</description>
|
<description>Separate test package for tracetools</description>
|
||||||
<maintainer email="fixed-term.christophe.bourquebedard@de.bosch.com">Christophe Bedard</maintainer>
|
<maintainer email="fixed-term.christophe.bourquebedard@de.bosch.com">Christophe Bedard</maintainer>
|
||||||
<maintainer email="ingo.luetkebohle@de.bosch.com">Ingo Luetkebohle</maintainer>
|
<maintainer email="ingo.luetkebohle@de.bosch.com">Ingo Luetkebohle</maintainer>
|
||||||
<license>Apache Software License 2.0</license>
|
<license>Apache 2.0</license>
|
||||||
<author email="fixed-term.christophe.bourquebedard@de.bosch.com">Christophe Bedard</author>
|
<author email="fixed-term.christophe.bourquebedard@de.bosch.com">Christophe Bedard</author>
|
||||||
|
|
||||||
<buildtool_depend>ament_cmake</buildtool_depend>
|
<buildtool_depend>ament_cmake</buildtool_depend>
|
||||||
|
|
3
tracetools_trace/.gitignore
vendored
Normal file
3
tracetools_trace/.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
*~
|
||||||
|
*.pyc
|
||||||
|
|
24
tracetools_trace/package.xml
Normal file
24
tracetools_trace/package.xml
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<?xml-model href="http://download.ros.org/schema/package_format2.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
|
||||||
|
<package format="2">
|
||||||
|
<name>tracetools_trace</name>
|
||||||
|
<version>0.0.1</version>
|
||||||
|
<description>Tools for setting up tracing sessions</description>
|
||||||
|
<maintainer email="fixed-term.christophe.bourquebedard@de.bosch.com">Christophe Bedard</maintainer>
|
||||||
|
<maintainer email="ingo.luetkebohle@de.bosch.com">Ingo Lütkebohle</maintainer>
|
||||||
|
<license>Apache 2.0</license>
|
||||||
|
<author email="fixed-term.christophe.bourquebedard@de.bosch.com">Christophe Bedard</author>
|
||||||
|
|
||||||
|
<!-- TODO consider adding python3-lttng to rosdep/python
|
||||||
|
https://github.com/ros/rosdistro/blob/master/rosdep/python.yaml
|
||||||
|
-->
|
||||||
|
|
||||||
|
<test_depend>ament_copyright</test_depend>
|
||||||
|
<test_depend>ament_flake8</test_depend>
|
||||||
|
<test_depend>ament_pep257</test_depend>
|
||||||
|
<test_depend>python3-pytest</test_depend>
|
||||||
|
|
||||||
|
<export>
|
||||||
|
<build_type>ament_python</build_type>
|
||||||
|
</export>
|
||||||
|
</package>
|
4
tracetools_trace/setup.cfg
Normal file
4
tracetools_trace/setup.cfg
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
[develop]
|
||||||
|
script-dir=$base/lib/tracetools_trace
|
||||||
|
[install]
|
||||||
|
install-scripts=$base/lib/tracetools_trace
|
28
tracetools_trace/setup.py
Normal file
28
tracetools_trace/setup.py
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
from setuptools import find_packages
|
||||||
|
from setuptools import setup
|
||||||
|
|
||||||
|
package_name = 'tracetools_trace'
|
||||||
|
|
||||||
|
setup(
|
||||||
|
name=package_name,
|
||||||
|
version='0.0.1',
|
||||||
|
packages=find_packages(exclude=['test']),
|
||||||
|
data_files=[
|
||||||
|
('share/' + package_name, ['package.xml']),
|
||||||
|
],
|
||||||
|
install_requires=['setuptools'],
|
||||||
|
maintainer='Christophe Bedard, Ingo Lütkebohle',
|
||||||
|
maintainer_email='fixed-term.christophe.bourquebedard@de.bosch.com, ingo.luetkebohle@de.bosch.com',
|
||||||
|
author='Christophe Bedard',
|
||||||
|
author_email='fixed-term.christophe.bourquebedard@de.bosch.com',
|
||||||
|
# url='',
|
||||||
|
keywords=['ROS'],
|
||||||
|
description='Tools for setting up tracing sessions',
|
||||||
|
entry_points={
|
||||||
|
'console_scripts': [
|
||||||
|
f'trace = {package_name}.trace:main',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
license='Apache 2.0',
|
||||||
|
tests_require=['pytest'],
|
||||||
|
)
|
23
tracetools_trace/test/test_copyright.py
Normal file
23
tracetools_trace/test/test_copyright.py
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
# Copyright 2017 Open Source Robotics Foundation, 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 ament_copyright.main import main
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.copyright
|
||||||
|
@pytest.mark.linter
|
||||||
|
def test_copyright():
|
||||||
|
rc = main(argv=['.', 'test'])
|
||||||
|
assert rc == 0, 'Found errors'
|
23
tracetools_trace/test/test_flake8.py
Normal file
23
tracetools_trace/test/test_flake8.py
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
# Copyright 2017 Open Source Robotics Foundation, 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 ament_flake8.main import main
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.flake8
|
||||||
|
@pytest.mark.linter
|
||||||
|
def test_flake8():
|
||||||
|
rc = main(argv=[])
|
||||||
|
assert rc == 0, 'Found errors'
|
23
tracetools_trace/test/test_pep257.py
Normal file
23
tracetools_trace/test/test_pep257.py
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
# Copyright 2015 Open Source Robotics Foundation, 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 ament_pep257.main import main
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.linter
|
||||||
|
@pytest.mark.pep257
|
||||||
|
def test_pep257():
|
||||||
|
rc = main(argv=[])
|
||||||
|
assert rc == 0, 'Found code style errors / warnings'
|
13
tracetools_trace/tracetools_trace/__init__.py
Normal file
13
tracetools_trace/tracetools_trace/__init__.py
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
# 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.
|
13
tracetools_trace/tracetools_trace/tools/__init__.py
Normal file
13
tracetools_trace/tracetools_trace/tools/__init__.py
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
# 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.
|
67
tracetools_trace/tracetools_trace/tools/args.py
Normal file
67
tracetools_trace/tracetools_trace/tools/args.py
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
# 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 containing parsing functions for tracing commands."""
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import time
|
||||||
|
|
||||||
|
from . import names
|
||||||
|
|
||||||
|
|
||||||
|
class DefaultArgValueCompleter:
|
||||||
|
"""Callable returning an arg's default value."""
|
||||||
|
|
||||||
|
def __init__(self, arg):
|
||||||
|
default = arg.default
|
||||||
|
self.list = default if isinstance(default, list) else [default]
|
||||||
|
|
||||||
|
def __call__(self, **kwargs):
|
||||||
|
return self.list
|
||||||
|
|
||||||
|
|
||||||
|
def parse_args():
|
||||||
|
"""
|
||||||
|
Parse args for tracing.
|
||||||
|
"""
|
||||||
|
parser = argparse.ArgumentParser(description='Setup and launch an LTTng tracing session.')
|
||||||
|
add_arguments(parser)
|
||||||
|
return parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
|
def add_arguments(parser):
|
||||||
|
parser.add_argument(
|
||||||
|
'--session-name', '-s', dest='session_name',
|
||||||
|
default=f'session-{time.strftime("%Y%m%d%H%M%S")}',
|
||||||
|
help='the name of the tracing session (default: session-YYYYMMDDHHMMSS)')
|
||||||
|
parser.add_argument(
|
||||||
|
'--path', '-p', dest='path',
|
||||||
|
default='/tmp',
|
||||||
|
help='path of the base directory for trace data (default: %(default)s)')
|
||||||
|
arg = parser.add_argument(
|
||||||
|
'--ust', '-u', nargs='*', dest='events_ust', default=names.DEFAULT_EVENTS_ROS,
|
||||||
|
help='the ROS UST events to enable (default: all events) '
|
||||||
|
'[to disable all UST events, '
|
||||||
|
'provide this flag without any event name]')
|
||||||
|
arg.completer = DefaultArgValueCompleter(arg)
|
||||||
|
arg = parser.add_argument(
|
||||||
|
'--kernel', '-k', nargs='*', dest='events_kernel',
|
||||||
|
default=names.DEFAULT_EVENTS_KERNEL,
|
||||||
|
help='the kernel events to enable (default: all events) '
|
||||||
|
'[to disable all UST events, '
|
||||||
|
'provide this flag without any event name]')
|
||||||
|
arg.completer = DefaultArgValueCompleter(arg)
|
||||||
|
parser.add_argument(
|
||||||
|
'--list', '-l', dest='list', action='store_true',
|
||||||
|
help='display lists of enabled events (default: %(default)s)')
|
309
tracetools_trace/tracetools_trace/tools/lttng.py
Normal file
309
tracetools_trace/tracetools_trace/tools/lttng.py
Normal file
|
@ -0,0 +1,309 @@
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
"""Interface for tracing with LTTng."""
|
||||||
|
|
||||||
|
import sys
|
||||||
|
|
||||||
|
# Temporary workaround
|
||||||
|
sys.path = ['/usr/local/lib/python3.6/site-packages'] + sys.path
|
||||||
|
from typing import List
|
||||||
|
|
||||||
|
import lttng # noqa: E402
|
||||||
|
|
||||||
|
from .names import ( # noqa: E402
|
||||||
|
DEFAULT_CONTEXT,
|
||||||
|
DEFAULT_EVENTS_KERNEL,
|
||||||
|
DEFAULT_EVENTS_ROS,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def lttng_init(
|
||||||
|
session_name: str,
|
||||||
|
full_path: str,
|
||||||
|
ros_events: List[str] = DEFAULT_EVENTS_ROS,
|
||||||
|
kernel_events: List[str] = DEFAULT_EVENTS_KERNEL,
|
||||||
|
context_names: List[str] = DEFAULT_CONTEXT
|
||||||
|
) -> None:
|
||||||
|
"""
|
||||||
|
Set up and start LTTng session.
|
||||||
|
|
||||||
|
:param session_name: the name of the session
|
||||||
|
:param full_path: the full path to the main directory to write trace data to
|
||||||
|
:param ros_events: list of ROS events to enable
|
||||||
|
:param kernel_events: list of kernel events to enable
|
||||||
|
:param context_names: list of context elements to enable
|
||||||
|
"""
|
||||||
|
_lttng_setup(session_name, full_path, ros_events, kernel_events, context_names)
|
||||||
|
_lttng_start(session_name)
|
||||||
|
|
||||||
|
|
||||||
|
def lttng_fini(session_name: str) -> None:
|
||||||
|
"""
|
||||||
|
Stop and destroy LTTng session.
|
||||||
|
|
||||||
|
:param session_name: the name of the session
|
||||||
|
"""
|
||||||
|
_lttng_stop(session_name)
|
||||||
|
_lttng_destroy(session_name)
|
||||||
|
|
||||||
|
|
||||||
|
def _lttng_setup(
|
||||||
|
session_name: str,
|
||||||
|
full_path: str,
|
||||||
|
ros_events: List[str] = DEFAULT_EVENTS_ROS,
|
||||||
|
kernel_events: List[str] = DEFAULT_EVENTS_KERNEL,
|
||||||
|
context_names: List[str] = DEFAULT_CONTEXT,
|
||||||
|
channel_name_ust: str = 'ros2',
|
||||||
|
channel_name_kernel: str = 'kchan',
|
||||||
|
) -> None:
|
||||||
|
"""
|
||||||
|
Set up LTTng session, with events and context.
|
||||||
|
|
||||||
|
See: https://lttng.org/docs/#doc-core-concepts
|
||||||
|
|
||||||
|
:param session_name: the name of the session
|
||||||
|
:param full_path: the full path to the main directory to write trace data to
|
||||||
|
:param ros_events: list of ROS events to enable
|
||||||
|
:param kernel_events: list of kernel events to enable
|
||||||
|
:param context_names: list of context elements to enable
|
||||||
|
:param channel_name_ust: the UST channel name
|
||||||
|
:param channel_name_kernel: the kernel channel name
|
||||||
|
"""
|
||||||
|
ust_enabled = ros_events is not None and len(ros_events) > 0
|
||||||
|
kernel_enabled = kernel_events is not None and len(kernel_events) > 0
|
||||||
|
|
||||||
|
# Domains
|
||||||
|
if ust_enabled:
|
||||||
|
domain_ust = lttng.Domain()
|
||||||
|
domain_ust.type = lttng.DOMAIN_UST
|
||||||
|
# Per-user buffer
|
||||||
|
domain_ust.buf_type = lttng.BUFFER_PER_UID
|
||||||
|
channel_ust = lttng.Channel()
|
||||||
|
channel_ust.name = channel_name_ust
|
||||||
|
# Discard, do not overwrite
|
||||||
|
channel_ust.attr.overwrite = 0
|
||||||
|
# 8 sub-buffers of 2 times the usual page size
|
||||||
|
channel_ust.attr.subbuf_size = 2 * 4096
|
||||||
|
channel_ust.attr.num_subbuf = 8
|
||||||
|
# Ignore switch timer interval and use read timer instead
|
||||||
|
channel_ust.attr.switch_timer_interval = 0
|
||||||
|
channel_ust.attr.read_timer_interval = 200
|
||||||
|
# mmap channel output instead of splice
|
||||||
|
channel_ust.attr.output = lttng.EVENT_MMAP
|
||||||
|
events_list_ust = _create_events(ros_events)
|
||||||
|
if kernel_enabled:
|
||||||
|
domain_kernel = lttng.Domain()
|
||||||
|
domain_kernel.type = lttng.DOMAIN_KERNEL
|
||||||
|
# Global buffer (only option for kernel domain)
|
||||||
|
domain_kernel.buf_type = lttng.BUFFER_GLOBAL
|
||||||
|
channel_kernel = lttng.Channel()
|
||||||
|
channel_kernel.name = channel_name_kernel
|
||||||
|
# Discard, do not overwrite
|
||||||
|
channel_kernel.attr.overwrite = 0
|
||||||
|
# 8 sub-buffers of 8 times the usual page size, since
|
||||||
|
# there can be way more kernel events than UST events
|
||||||
|
channel_kernel.attr.subbuf_size = 8 * 4096
|
||||||
|
channel_kernel.attr.num_subbuf = 8
|
||||||
|
# Ignore switch timer interval and use read timer instead
|
||||||
|
channel_kernel.attr.switch_timer_interval = 0
|
||||||
|
channel_kernel.attr.read_timer_interval = 200
|
||||||
|
# mmap channel output instead of splice
|
||||||
|
channel_kernel.attr.output = lttng.EVENT_MMAP
|
||||||
|
events_list_kernel = _create_events(kernel_events)
|
||||||
|
|
||||||
|
# Session
|
||||||
|
_create_session(session_name, full_path)
|
||||||
|
|
||||||
|
# Handles, channels, events
|
||||||
|
handle_ust = None
|
||||||
|
if ust_enabled:
|
||||||
|
handle_ust = _create_handle(session_name, domain_ust)
|
||||||
|
_enable_channel(handle_ust, channel_ust)
|
||||||
|
_enable_events(handle_ust, events_list_ust, channel_ust.name)
|
||||||
|
handle_kernel = None
|
||||||
|
if kernel_enabled:
|
||||||
|
handle_kernel = _create_handle(session_name, domain_kernel)
|
||||||
|
_enable_channel(handle_kernel, channel_kernel)
|
||||||
|
_enable_events(handle_kernel, events_list_kernel, channel_kernel.name)
|
||||||
|
|
||||||
|
# Context
|
||||||
|
context_list = _create_context_list(context_names)
|
||||||
|
enabled_handles = [h for h in [handle_ust, handle_kernel] if h is not None]
|
||||||
|
_add_context(enabled_handles, context_list)
|
||||||
|
|
||||||
|
|
||||||
|
def _lttng_start(session_name: str) -> None:
|
||||||
|
"""
|
||||||
|
Start LTTng session, and check for errors.
|
||||||
|
|
||||||
|
:param session_name: the name of the session
|
||||||
|
"""
|
||||||
|
result = lttng.start(session_name)
|
||||||
|
if result < 0:
|
||||||
|
raise RuntimeError(f'failed to start tracing: {lttng.strerror(result)}')
|
||||||
|
|
||||||
|
|
||||||
|
def _lttng_stop(session_name: str) -> None:
|
||||||
|
"""
|
||||||
|
Stop LTTng session, and check for errors.
|
||||||
|
|
||||||
|
:param session_name: the name of the session
|
||||||
|
"""
|
||||||
|
result = lttng.stop(session_name)
|
||||||
|
if result < 0:
|
||||||
|
raise RuntimeError(f'failed to stop tracing: {lttng.strerror(result)}')
|
||||||
|
|
||||||
|
|
||||||
|
def _lttng_destroy(session_name: str) -> None:
|
||||||
|
"""
|
||||||
|
Destroy LTTng session, and check for errors.
|
||||||
|
|
||||||
|
:param session_name: the name of the session
|
||||||
|
"""
|
||||||
|
result = lttng.destroy(session_name)
|
||||||
|
if result < 0:
|
||||||
|
raise RuntimeError(f'failed to destroy tracing session: {lttng.strerror(result)}')
|
||||||
|
|
||||||
|
|
||||||
|
def _create_events(event_names_list: List[str]) -> List[lttng.Event]:
|
||||||
|
"""
|
||||||
|
Create events list from names.
|
||||||
|
|
||||||
|
:param event_names_list: a list of names to create events for
|
||||||
|
:return: the list of events
|
||||||
|
"""
|
||||||
|
events_list = []
|
||||||
|
for event_name in event_names_list:
|
||||||
|
e = lttng.Event()
|
||||||
|
e.name = event_name
|
||||||
|
e.type = lttng.EVENT_TRACEPOINT
|
||||||
|
e.loglevel_type = lttng.EVENT_LOGLEVEL_ALL
|
||||||
|
events_list.append(e)
|
||||||
|
return events_list
|
||||||
|
|
||||||
|
|
||||||
|
def _create_session(session_name: str, full_path: str) -> None:
|
||||||
|
"""
|
||||||
|
Create session from name and full directory path, and check for errors.
|
||||||
|
|
||||||
|
:param session_name: the name of the session
|
||||||
|
:param full_path: the full path to the main directory to write trace data to
|
||||||
|
"""
|
||||||
|
result = lttng.create(session_name, full_path)
|
||||||
|
LTTNG_ERR_EXIST_SESS = 28
|
||||||
|
if result == -LTTNG_ERR_EXIST_SESS:
|
||||||
|
# Sessions seem to persist, so if it already exists,
|
||||||
|
# just destroy it and try again
|
||||||
|
lttng_destroy(session_name)
|
||||||
|
result = lttng.create(session_name, full_path)
|
||||||
|
if result < 0:
|
||||||
|
raise RuntimeError(f'session creation failed: {lttng.strerror(result)}')
|
||||||
|
|
||||||
|
|
||||||
|
def _create_handle(session_name: str, domain: lttng.Domain) -> lttng.Handle:
|
||||||
|
"""
|
||||||
|
Create a handle for a given session name and a domain, and check for errors.
|
||||||
|
|
||||||
|
:param session_name: the name of the session
|
||||||
|
:param domain: the domain to be used
|
||||||
|
:return: the handle
|
||||||
|
"""
|
||||||
|
handle = None
|
||||||
|
handle = lttng.Handle(session_name, domain)
|
||||||
|
if handle is None:
|
||||||
|
raise RuntimeError('handle creation failed')
|
||||||
|
return handle
|
||||||
|
|
||||||
|
|
||||||
|
def _enable_channel(handle: lttng.Handle, channel: lttng.Channel) -> None:
|
||||||
|
"""
|
||||||
|
Enable channel for a handle, and check for errors.
|
||||||
|
|
||||||
|
:param handle: the handle to be used
|
||||||
|
:param channel: the channel to enable
|
||||||
|
"""
|
||||||
|
result = lttng.enable_channel(handle, channel)
|
||||||
|
if result < 0:
|
||||||
|
raise RuntimeError(f'channel enabling failed: {lttng.strerror(result)}')
|
||||||
|
|
||||||
|
|
||||||
|
def _enable_events(
|
||||||
|
handle: lttng.Handle,
|
||||||
|
events_list: List[lttng.Event],
|
||||||
|
channel_name: str,
|
||||||
|
) -> None:
|
||||||
|
"""
|
||||||
|
Enable events list for a given handle and channel name, and check for errors.
|
||||||
|
|
||||||
|
:param handle: the handle to be used
|
||||||
|
:param events_list: the list of events to enable
|
||||||
|
:param channel_name: the name of the channel to associate
|
||||||
|
"""
|
||||||
|
for event in events_list:
|
||||||
|
result = lttng.enable_event(handle, event, channel_name)
|
||||||
|
if result < 0:
|
||||||
|
raise RuntimeError(f'event enabling failed: {lttng.strerror(result)}')
|
||||||
|
|
||||||
|
|
||||||
|
context_map = {
|
||||||
|
'procname': lttng.EVENT_CONTEXT_PROCNAME,
|
||||||
|
'pid': lttng.EVENT_CONTEXT_PID,
|
||||||
|
'vpid': lttng.EVENT_CONTEXT_VPID,
|
||||||
|
'vtid': lttng.EVENT_CONTEXT_VTID,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def _context_name_to_type(context_name: str) -> int:
|
||||||
|
"""
|
||||||
|
Convert from context name to LTTng enum/constant type.
|
||||||
|
|
||||||
|
:param context_name: the generic name for the context
|
||||||
|
:return: the associated type
|
||||||
|
"""
|
||||||
|
return context_map.get(context_name)
|
||||||
|
|
||||||
|
|
||||||
|
def _create_context_list(context_names_list: List[str]) -> List[lttng.EventContext]:
|
||||||
|
"""
|
||||||
|
Create context list from names, and check for errors.
|
||||||
|
|
||||||
|
:param context_names_list: the list of context names
|
||||||
|
:return: the event context list
|
||||||
|
"""
|
||||||
|
context_list = []
|
||||||
|
for c in context_names_list:
|
||||||
|
ec = lttng.EventContext()
|
||||||
|
context_type = _context_name_to_type(c)
|
||||||
|
if context_type is not None:
|
||||||
|
ec.ctx = context_type
|
||||||
|
context_list.append(ec)
|
||||||
|
return context_list
|
||||||
|
|
||||||
|
|
||||||
|
def _add_context(
|
||||||
|
handles: List[lttng.Handle],
|
||||||
|
context_list: List[lttng.EventContext],
|
||||||
|
) -> None:
|
||||||
|
"""
|
||||||
|
Add context list to given handles, and check for errors.
|
||||||
|
|
||||||
|
:param handles: the list of handles for which to add context
|
||||||
|
:param context_list: the list of event contexts to add to the handles
|
||||||
|
"""
|
||||||
|
for handle in handles:
|
||||||
|
for contex in context_list:
|
||||||
|
result = lttng.add_context(handle, contex, None, None)
|
||||||
|
if result < 0:
|
||||||
|
raise RuntimeError(f'failed to add context: {lttng.strerror(result)}')
|
81
tracetools_trace/tracetools_trace/tools/names.py
Normal file
81
tracetools_trace/tracetools_trace/tools/names.py
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
"""Lists of names (events, context) for tracing."""
|
||||||
|
|
||||||
|
EVENTS_KERNEL = [
|
||||||
|
'block_rq_complete',
|
||||||
|
'block_rq_insert',
|
||||||
|
'block_rq_issue',
|
||||||
|
'block_bio_frontmerge',
|
||||||
|
'irq_softirq_entry',
|
||||||
|
'irq_softirq_raise',
|
||||||
|
'irq_softirq_exit',
|
||||||
|
'irq_handler_entry',
|
||||||
|
'irq_handler_exit',
|
||||||
|
'lttng_statedump_process_state',
|
||||||
|
'lttng_statedump_start',
|
||||||
|
'lttng_statedump_end',
|
||||||
|
'lttng_statedump_network_interface',
|
||||||
|
'lttng_statedump_block_device',
|
||||||
|
'net_dev_queue',
|
||||||
|
'netif_receive_skb',
|
||||||
|
'net_if_receive_skb',
|
||||||
|
'power_cpu_frequency',
|
||||||
|
'sched_switch',
|
||||||
|
'sched_waking',
|
||||||
|
'sched_pi_setprio',
|
||||||
|
'sched_process_fork',
|
||||||
|
'sched_process_exit',
|
||||||
|
'sched_process_free',
|
||||||
|
'sched_wakeup',
|
||||||
|
'sched_migrate',
|
||||||
|
'sched_migrate_task',
|
||||||
|
'timer_hrtimer_start',
|
||||||
|
'timer_hrtimer_cancel',
|
||||||
|
'timer_hrtimer_expire_entry',
|
||||||
|
'timer_hrtimer_expire_exit',
|
||||||
|
]
|
||||||
|
|
||||||
|
DEFAULT_EVENTS_KERNEL = [
|
||||||
|
'power_cpu_frequency',
|
||||||
|
'sched_switch',
|
||||||
|
'sched_waking',
|
||||||
|
'sched_wakeup',
|
||||||
|
]
|
||||||
|
|
||||||
|
DEFAULT_EVENTS_ROS = [
|
||||||
|
'ros2:rcl_init',
|
||||||
|
'ros2:rcl_node_init',
|
||||||
|
'ros2:rcl_publisher_init',
|
||||||
|
'ros2:rcl_subscription_init',
|
||||||
|
'ros2:rclcpp_subscription_callback_added',
|
||||||
|
'ros2:rcl_service_init',
|
||||||
|
'ros2:rclcpp_service_callback_added',
|
||||||
|
'ros2:rcl_client_init',
|
||||||
|
'ros2:rcl_timer_init',
|
||||||
|
'ros2:rclcpp_timer_callback_added',
|
||||||
|
'ros2:rclcpp_callback_register',
|
||||||
|
'ros2:callback_start',
|
||||||
|
'ros2:callback_end',
|
||||||
|
]
|
||||||
|
|
||||||
|
DEFAULT_CONTEXT = [
|
||||||
|
'procname',
|
||||||
|
'perf:thread:instructions',
|
||||||
|
'perf:thread:cycles',
|
||||||
|
'perf:thread:cpu-cycles',
|
||||||
|
'vpid',
|
||||||
|
'vtid',
|
||||||
|
]
|
55
tracetools_trace/tracetools_trace/trace.py
Normal file
55
tracetools_trace/tracetools_trace/trace.py
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
"""Entrypoint/script to setup and start an LTTng tracing session."""
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
from tracetools_trace.tools import args
|
||||||
|
from tracetools_trace.tools import lttng
|
||||||
|
from tracetools_trace.tools import names
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
params = args.parse_args()
|
||||||
|
|
||||||
|
session_name = params.session_name
|
||||||
|
base_path = params.path
|
||||||
|
full_path = os.path.join(base_path, session_name)
|
||||||
|
ros_events = params.events_ust
|
||||||
|
kernel_events = params.events_kernel
|
||||||
|
|
||||||
|
ust_enabled = len(ros_events) > 0
|
||||||
|
kernel_enabled = len(kernel_events) > 0
|
||||||
|
if ust_enabled:
|
||||||
|
print(f'UST tracing enabled ({len(ros_events)} events)')
|
||||||
|
if params.list:
|
||||||
|
print(f'\tevents: {ros_events}')
|
||||||
|
else:
|
||||||
|
print('UST tracing disabled')
|
||||||
|
if kernel_enabled:
|
||||||
|
print(f'kernel tracing enabled ({len(kernel_events)} events)')
|
||||||
|
if params.list:
|
||||||
|
print(f'\tevents: {kernel_events}')
|
||||||
|
else:
|
||||||
|
print('kernel tracing disabled')
|
||||||
|
|
||||||
|
print(f'writting tracing session to: {full_path}')
|
||||||
|
input('press enter to start...')
|
||||||
|
lttng.lttng_init(session_name, full_path, ros_events=ros_events, kernel_events=kernel_events)
|
||||||
|
input('press enter to stop...')
|
||||||
|
|
||||||
|
print('stopping & destroying tracing session')
|
||||||
|
lttng.lttng_fini(session_name)
|
Loading…
Add table
Add a link
Reference in a new issue