Esempio n. 1
0
    def __init__(self,
                 trace_events,
                 trace_output_dir,
                 trace_name="bioflow_trace"):
        if type(trace_events) is str:
            trace_events = [trace_events]
        self.trace_events = trace_events
        user = getpass.getuser()
        trace_name = "{name}_{user}".format(name=trace_name, user=user)
        self.sess_name = trace_name
        domain = lttng.Domain()
        domain.type = lttng.DOMAIN_UST
        handle = lttng.Handle(domain=domain, session_name=trace_name)
        self.domain = domain
        self.handle = handle
        new_handle = trace_output_dir
        count = 0
        while os.path.exists(new_handle):
            new_handle = "{trace_dir}_{cnt}".format(trace_dir=trace_output_dir,
                                                    cnt=count)
            count += 1
        trace_output_dir = new_handle
        os.makedirs(name=trace_output_dir, exist_ok=False)
        self.outdir = trace_output_dir

        curr_sessions = lttng.list_sessions()
        if trace_name in curr_sessions:
            lttng.destroy(trace_name)  # note: this doesn't delete any files
Esempio n. 2
0
def lttng_start(events=["*"], domain_type=lttng.DOMAIN_UST):
    if lttng.session_daemon_alive() == 0:
        daemon_cmd = "lttng-sessiond --background"
        daemon_cmd += " --pidfile " + sessiond_pidfile
        subprocess.check_call(daemon_cmd,
                              shell=True,
                              stdout=sessiond_logfile,
                              stderr=sessiond_logfile)

    lttng.destroy(session_name)
    ret = lttng.create_snapshot(session_name, trace_path)
    if ret < 0:
        raise RuntimeError("LTTng: " + lttng.strerror(ret))

    domain = lttng.Domain()
    domain.type = domain_type

    channel = lttng.Channel()
    channel.name = "channel0"
    lttng.channel_set_default_attr(domain, channel.attr)

    han = lttng.Handle(session_name, domain)
    if han is None:
        raise RuntimeError("LTTng: failed to create handle")

    ret = lttng.enable_channel(han, channel)
    if ret < 0:
        raise RuntimeError("LTTng: " + lttng.strerror(ret))

    for name in events:
        event = lttng.Event()
        event.name = name
        event.type = lttng.EVENT_TRACEPOINT
        event.loglevel = lttng.EVENT_LOGLEVEL_ALL
        ret = lttng.enable_event(han, event, channel.name)
        if ret < 0:
            raise RuntimeError("LTTng: " + lttng.strerror(ret))

    ret = lttng.start(session_name)
    if ret < 0:
        raise RuntimeError("LTTng: " + lttng.strerror(ret))
Esempio n. 3
0
def setup(
    session_name: str,
    base_path: str = DEFAULT_BASE_PATH,
    ros_events: Union[List[str], Set[str]] = DEFAULT_EVENTS_ROS,
    kernel_events: Union[List[str], Set[str]] = DEFAULT_EVENTS_KERNEL,
    context_names: Union[List[str], Set[str]] = DEFAULT_CONTEXT,
    channel_name_ust: str = 'ros2',
    channel_name_kernel: str = 'kchan',
) -> Optional[str]:
    """
    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 base_path: the path to the directory in which to create the tracing session directory
    :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
    :return: the full path to the trace directory
    """
    # Convert lists to sets
    if not isinstance(ros_events, set):
        ros_events = set(ros_events)
    if not isinstance(kernel_events, set):
        kernel_events = set(kernel_events)
    if not isinstance(context_names, set):
        context_names = set(context_names)

    # Resolve full tracing directory path
    full_path = get_full_session_path(session_name, base_path=base_path)

    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)
    # TODO make it possible to add context in userspace and kernel separately, since some context
    # types might only apply to userspace OR kernel; only consider userspace contexts for now
    handles_context = [handle_ust]
    enabled_handles = list(filter(None, handles_context))
    _add_context(enabled_handles, context_list)

    return full_path
class BabeltraceError(Exception):
    pass


# LTTNG-TOOLS

# Making sure session does not already exist
lttng.destroy(ses_name)

# Creating a new session and handle
ret = lttng.create(ses_name, trace_path)
if ret < 0:
    raise LTTngError(lttng.strerror(ret))

domain = lttng.Domain()
domain.type = lttng.DOMAIN_KERNEL

han = None
han = lttng.Handle(ses_name, domain)
if han is None:
    raise LTTngError("Handle not created")

# Enabling all events
event = lttng.Event()
event.type = lttng.EVENT_ALL
event.loglevel_type = lttng.EVENT_LOGLEVEL_ALL
ret = lttng.enable_event(han, event, None)
if ret < 0:
    raise LTTngError(lttng.strerror(ret))
def setup(
    *,
    session_name: str,
    base_path: str,
    ros_events: Union[List[str], Set[str]] = DEFAULT_EVENTS_ROS,
    kernel_events: Union[List[str], Set[str]] = [],
    context_fields: Union[List[str], Set[str],
                          Dict[str, List[str]]] = DEFAULT_CONTEXT,
    context_names: Optional[Union[List[str], Set[str],
                                  Dict[str, List[str]]]] = None,
    channel_name_ust: str = 'ros2',
    channel_name_kernel: str = 'kchan',
) -> Optional[str]:
    """
    Set up LTTng session, with events and context.

    See: https://lttng.org/docs/#doc-core-concepts

    Initialization will fail if the list of kernel events to be
    enabled is not empty and if the kernel tracer is not installed.

    :param session_name: the name of the session
    :param base_path: the path to the directory in which to create the tracing session directory
    :param ros_events: list of ROS events to enable
    :param kernel_events: list of kernel events to enable
    :param context_fields: the names of context fields to enable
        if it's a list or a set, the context fields are enabled for both kernel and userspace;
        if it's a dictionary: { domain type string -> context fields list }
    :param context_names: DEPRECATED, use context_fields instead
    :param channel_name_ust: the UST channel name
    :param channel_name_kernel: the kernel channel name
    :return: the full path to the trace directory, or `None` if initialization failed
    """
    # Use value from deprecated param if it is provided
    # TODO(christophebedard) remove context_names param in Rolling after Humble release
    if context_names is not None:
        context_fields = context_names
        warnings.warn(
            'context_names parameter is deprecated, use context_fields',
            stacklevel=4)

    # Check if there is a session daemon running
    if lttng.session_daemon_alive() == 0:
        # Otherwise spawn one and check if it worked
        subprocess.run(['lttng-sessiond', '--daemonize'], )
        if lttng.session_daemon_alive() == 0:
            print('error: failed to start lttng session daemon')
            return None

    # Make sure the kernel tracer is available if there are kernel events
    # Do this after spawning a session daemon, otherwise we can't detect the kernel tracer
    if 0 < len(kernel_events):
        kernel_tracer_available, message = is_kernel_tracer_available()
        if not kernel_tracer_available:
            print(
                f'error: kernel tracer is not available: {message}\n'
                '  cannot use kernel events:\n'
                "    'ros2 trace' command: cannot use '-k' option\n"
                "    'Trace' action: cannot set 'events_kernel'/'events-kernel' list\n"
                '  install the kernel tracer, e.g., on Ubuntu, install lttng-modules-dkms\n'
                '  see: https://gitlab.com/ros-tracing/ros2_tracing#building')
            return None

    # Convert lists to sets
    if not isinstance(ros_events, set):
        ros_events = set(ros_events)
    if not isinstance(kernel_events, set):
        kernel_events = set(kernel_events)
    if isinstance(context_fields, list):
        context_fields = set(context_fields)

    # Resolve full tracing directory path
    full_path = os.path.join(base_path, session_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
        # 2 sub-buffers of 8 times the usual page size
        # We use 2 sub-buffers because the number of sub-buffers is pointless in discard mode,
        # and switching between sub-buffers introduces noticeable CPU overhead
        channel_ust.attr.subbuf_size = 8 * 4096
        channel_ust.attr.num_subbuf = 2
        # 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 (only option for UST)
        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
        # 2 sub-buffers of 32 times the usual page size, since
        # there can be way more kernel events than UST events
        channel_kernel.attr.subbuf_size = 32 * 4096
        channel_kernel.attr.num_subbuf = 2
        # 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
    contexts_dict = _normalize_contexts_dict(
        {
            'kernel': handle_kernel,
            'userspace': handle_ust
        }, context_fields)
    _add_context(contexts_dict)

    return full_path
Esempio n. 6
0
def setup(
    session_name: str,
    base_path: str = DEFAULT_BASE_PATH,
    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 base_path: the path to the directory in which to create the tracing session directory
    :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
    """
    # Resolve full tracing directory path
    full_path = get_full_session_path(session_name, base_path=base_path)

    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)