Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lttngpy/src/lttngpy/_lttngpy_pybind11.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ PYBIND11_MODULE(_lttngpy_pybind11, m) {
m.def(
"lttng_create_session_live",
&lttng_create_session_live,
"Create session.",
"Create live session.",
py::kw_only(),
py::arg("session_name"),
py::arg("url"),
Expand Down
43 changes: 41 additions & 2 deletions lttngpy/test/test_session.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,47 @@ def test_session_list_create_start_stop_destroy(self):
shutil.rmtree(tmpdir)

def test_session_live_list_create_start_stop_destroy(self):
# TODO(christophebedard): add test for lttngpy.lttng_create_session_live()
pass
session_name = 'test_session_live_list_create_start_stop_destroy'
tmpdir = self.create_test_tmpdir(session_name)

self.assertSetEqual(set(), lttngpy.get_session_names())
result = lttngpy.lttng_create_session_live(
session_name=session_name,
url=None,
timer_interval=1000000
)
self.assertEqual(0, result)
self.assertSetEqual({session_name}, lttngpy.get_session_names())
self.assertEqual(
0,
lttngpy.enable_channel(
session_name=session_name,
domain_type=lttngpy.LTTNG_DOMAIN_UST,
buffer_type=lttngpy.LTTNG_BUFFER_PER_UID,
channel_name='dummy_channel_live',
overwrite=None,
subbuf_size=None,
num_subbuf=None,
switch_timer_interval=None,
read_timer_interval=None,
output=None,
),
)
self.assertEqual(0, lttngpy.lttng_start_tracing(session_name=session_name))
self.assertEqual(0, lttngpy.lttng_stop_tracing(session_name=session_name))
self.assertEqual(0, lttngpy.lttng_destroy_session(session_name=session_name))
self.assertSetEqual(set(), lttngpy.get_session_names())

result = lttngpy.lttng_create_session_live(
session_name=session_name,
url=None,
timer_interval=1000000
)
self.assertEqual(0, result)
self.assertEqual(0, lttngpy.destroy_all_sessions())
self.assertSetEqual(set(), lttngpy.get_session_names())

shutil.rmtree(tmpdir)

def test_error(self):
session_name = 'test_error'
Expand Down
9 changes: 7 additions & 2 deletions tracetools_trace/tracetools_trace/tools/args.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,13 @@ def _add_arguments_configure(parser: argparse.ArgumentParser) -> None:
'--live', dest='live_timer_interval', type=int, nargs='?',
# Default value for 'lttng create-session --live':
# https://lttng.org/man/1/lttng-create/v2.13/#doc-opt--live
default=1000000,
help='TODO (default: %(default)s)')
const=100000,
help='Create a live tracing session. Optionally set the live timer interval '
'(default: %(default)s)')
parser.add_argument(
'--live-url', dest='live_url', type=str,
default='net://localhost',
help='Set the live tracing URL origin (default: %(default)s)')
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is just a note for some improvements later, no need to do anything now:

We should document what this all means (timer interval, URL, etc.), link to the relevant parts of the LTTng docs, provide some examples, etc. This could go in the README.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, understood 👍
I will raise a PR for the updates in the README after this.



def _add_arguments_default_session_name(parser: argparse.ArgumentParser) -> None:
Expand Down
31 changes: 17 additions & 14 deletions tracetools_trace/tracetools_trace/tools/lttng_impl.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import os
import shlex
import socket
import subprocess
from typing import Dict
from typing import List
Expand Down Expand Up @@ -158,6 +159,7 @@ def setup(
subbuffer_size_ust: int = 8 * 4096,
subbuffer_size_kernel: int = 32 * 4096,
live_timer_interval: Optional[int] = None,
live_url: Optional[str] = None,
) -> Optional[str]:
"""
Set up LTTng session, with events and context.
Expand Down Expand Up @@ -190,19 +192,16 @@ def setup(
the usual page size)
:param subbuffer_size_kernel: the size of the subbuffers for kernel events (defaults to 32
times the usual page size, since there can be way more kernel events than UST events)
:param live_timer_interval: the time interval at which the data should be flushed from the
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should also say that the tracing session will be in live mode if this value is not None.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

buffer and sent to the LTTng relay daemon. This is in microseconds.
The created tracing session will be in live mode if this value is not `None`.
:param live_url: the URL of the relay daemon to which the tracing output will be sent.
Used only if live_timer_interval is not `None`.
:return: the full path to the trace directory, or `None` if initialization failed
"""
# Validate parameters
if not session_name:
raise RuntimeError('empty session name')
# Resolve full tracing directory path
# TODO(christophebedard): do we need to join the base_path with session_name for a live session?
# We need to return a path, so maybe format it like:
# "net://localhost/host/$hostname/$session_name"
full_path = os.path.join(base_path, session_name)
if os.path.isdir(full_path) and not append_trace:
raise RuntimeError(
f'trace directory already exists, use the append option to append to it: {full_path}')

# If there is no session daemon running, try to spawn one
if is_session_daemon_not_alive():
Expand Down Expand Up @@ -248,15 +247,22 @@ def setup(

# Create session
if live_timer_interval is None:
# Resolve full tracing directory path
full_path = os.path.join(base_path, session_name)
if os.path.isdir(full_path) and not append_trace:
raise RuntimeError(
f'trace directory already exists, use the append option to append to it: {full_path}')
# LTTng will create the parent directories if needed
_create_session(
session_name=session_name,
full_path=full_path,
)
else:
live_tracing_url = f'{live_url}/host/{socket.gethostname()}/{session_name}'
full_path = live_tracing_url
_create_session_live(
session_name=session_name,
full_path=full_path,
url=live_url,
timer_interval=live_timer_interval,
)

Expand Down Expand Up @@ -440,18 +446,15 @@ def _create_session(
def _create_session_live(
*,
session_name: str,
full_path: str,
url: str,
timer_interval: int,
) -> None:
"""
TODO
"""
result = lttngpy.lttng_create_session_live(
session_name=session_name,
# TODO(christophebedard): figure out what to provide here as the URL
# This depends on how we expect users to use live tracing
# See the documentation for the url param of lttng_create_session_live()
url=None,
url=url,
timer_interval=timer_interval,
)
if result < 0:
Expand Down
37 changes: 32 additions & 5 deletions tracetools_trace/tracetools_trace/trace.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import argparse
import os
import socket
import sys
from typing import Callable
from typing import List
Expand All @@ -43,6 +44,7 @@ def _display_info(
syscalls: List[str],
context_fields: List[str],
display_list: bool,
live_timer_interval: int = None,
) -> None:
if ros_events:
print(f'userspace tracing enabled ({len(ros_events)} events)')
Expand All @@ -66,6 +68,8 @@ def _display_info(
print(f'context ({len(context_fields)} fields)')
if display_list:
print_names_list(context_fields)
if live_timer_interval:
print(f'live timer interval set to: {live_timer_interval}')


def _resolve_session_path(
Expand All @@ -79,6 +83,14 @@ def _resolve_session_path(
print(f'writing tracing session to: {full_session_path}')
return base_path, full_session_path

def _resolve_session_live_url(
*,
live_url: Optional[str],
session_name: str,
) -> str:
full_live_url = f'{live_url}/host/{socket.gethostname()}/{session_name}'
print(f'live trace data will be sent to the relay daemon at {full_live_url}')
return full_live_url

def init(
*,
Expand All @@ -90,6 +102,7 @@ def init(
syscalls: List[str],
context_fields: List[str],
live_timer_interval: Optional[int],
live_url: Optional[str],
display_list: bool,
interactive: bool,
) -> bool:
Expand Down Expand Up @@ -120,12 +133,19 @@ def init(
syscalls=syscalls,
context_fields=context_fields,
display_list=display_list,
live_timer_interval=live_timer_interval,
)

base_path, full_session_path = _resolve_session_path(
session_name=session_name,
base_path=base_path,
)
if live_timer_interval is None:
base_path, full_session_path = _resolve_session_path(
session_name=session_name,
base_path=base_path,
)
else:
full_live_url = _resolve_session_live_url(
live_url=live_url,
session_name=session_name,
)

if interactive:
input('press enter to start...')
Expand All @@ -138,11 +158,15 @@ def init(
syscalls=syscalls,
context_fields=context_fields,
live_timer_interval=live_timer_interval,
live_url=live_url,
)
if trace_directory is None:
return False
# Simple sanity check
assert trace_directory == full_session_path
if live_timer_interval is None:
assert trace_directory == full_session_path
Comment on lines +166 to +167
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The value returned by lttng.lttng_init() (trace_directory) should be equivalent to full_live_url if we're in live mode, so we should assert that they are equal too

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

else:
assert trace_directory == full_live_url
return True


Expand Down Expand Up @@ -227,6 +251,7 @@ def work() -> int:
syscalls=args.syscalls,
context_fields=args.context_fields,
live_timer_interval=args.live_timer_interval,
live_url=args.live_url,
display_list=args.list,
interactive=True,
):
Expand Down Expand Up @@ -256,6 +281,8 @@ def work() -> int:
kernel_events=args.events_kernel,
syscalls=args.syscalls,
context_fields=args.context_fields,
live_timer_interval=args.live_timer_interval,
live_url=args.live_url,
display_list=args.list,
interactive=False,
)
Expand Down
Loading