Test: client: start, stop, destroy: add tests for --glob/--all
[lttng-tools.git] / tests / utils / lttngtest / lttngctl.py
CommitLineData
ef945e4d
JG
1#!/usr/bin/env python3
2#
3# Copyright (C) 2022 Jérémie Galarneau <jeremie.galarneau@efficios.com>
4#
5# SPDX-License-Identifier: GPL-2.0-only
6
7import abc
8import random
9import string
10import pathlib
11import enum
12from typing import Optional, Type, Union, List
13
14"""
15Defines an abstract interface to control LTTng tracing.
16
17The various control concepts are defined by this module. You can use them with a
18Controller to interact with a session daemon.
19
20This interface is not comprehensive; it currently provides a subset of the
21control functionality that is used by tests.
22"""
23
24
ce8470c9
MJ
25def _generate_random_string(length):
26 # type: (int) -> str
ef945e4d
JG
27 return "".join(
28 random.choice(string.ascii_lowercase + string.digits) for _ in range(length)
29 )
30
31
32class ContextType(abc.ABC):
33 """Base class representing a tracing context field."""
34
35 pass
36
37
38class VpidContextType(ContextType):
39 """Application's virtual process id."""
40
41 pass
42
43
44class VuidContextType(ContextType):
45 """Application's virtual user id."""
46
47 pass
48
49
50class VgidContextType(ContextType):
51 """Application's virtual group id."""
52
53 pass
54
55
56class JavaApplicationContextType(ContextType):
57 """A java application-specific context field is a piece of state which the application provides."""
58
ce8470c9
MJ
59 def __init__(
60 self,
61 retriever_name, # type: str
62 field_name, # type: str
63 ):
64 self._retriever_name = retriever_name # type: str
65 self._field_name = field_name # type: str
ef945e4d
JG
66
67 @property
ce8470c9
MJ
68 def retriever_name(self):
69 # type: () -> str
ef945e4d
JG
70 return self._retriever_name
71
72 @property
ce8470c9
MJ
73 def field_name(self):
74 # type: () -> str
ef945e4d
JG
75 return self._field_name
76
77
544d8425 78@enum.unique
ef945e4d
JG
79class TracingDomain(enum.Enum):
80 """Tracing domain."""
81
544d8425
MJ
82 User = "User space tracing domain"
83 Kernel = "Linux kernel tracing domain."
84 Log4j = "Log4j tracing back-end."
85 JUL = "Java Util Logging tracing back-end."
86 Python = "Python logging module tracing back-end."
87
88 def __repr__(self):
89 return "<%s.%s>" % (self.__class__.__name__, self.name)
ef945e4d
JG
90
91
92class EventRule(abc.ABC):
93 """Event rule base class, see LTTNG-EVENT-RULE(7)."""
94
95 pass
96
97
98class LogLevelRule:
99 pass
100
101
102class LogLevelRuleAsSevereAs(LogLevelRule):
ce8470c9
MJ
103 def __init__(self, level):
104 # type: (int)
ef945e4d
JG
105 self._level = level
106
107 @property
ce8470c9
MJ
108 def level(self):
109 # type: () -> int
ef945e4d
JG
110 return self._level
111
112
113class LogLevelRuleExactly(LogLevelRule):
ce8470c9
MJ
114 def __init__(self, level):
115 # type: (int)
ef945e4d
JG
116 self._level = level
117
118 @property
ce8470c9
MJ
119 def level(self):
120 # type: () -> int
ef945e4d
JG
121 return self._level
122
123
124class TracepointEventRule(EventRule):
125 def __init__(
126 self,
ce8470c9
MJ
127 name_pattern=None, # type: Optional[str]
128 filter_expression=None, # type: Optional[str]
129 log_level_rule=None, # type: Optional[LogLevelRule]
130 name_pattern_exclusions=None, # type: Optional[List[str]]
ef945e4d 131 ):
ce8470c9
MJ
132 self._name_pattern = name_pattern # type: Optional[str]
133 self._filter_expression = filter_expression # type: Optional[str]
134 self._log_level_rule = log_level_rule # type: Optional[LogLevelRule]
135 self._name_pattern_exclusions = (
136 name_pattern_exclusions
137 ) # type: Optional[List[str]]
ef945e4d
JG
138
139 @property
ce8470c9
MJ
140 def name_pattern(self):
141 # type: () -> Optional[str]
ef945e4d
JG
142 return self._name_pattern
143
144 @property
ce8470c9
MJ
145 def filter_expression(self):
146 # type: () -> Optional[str]
ef945e4d
JG
147 return self._filter_expression
148
149 @property
ce8470c9
MJ
150 def log_level_rule(self):
151 # type: () -> Optional[LogLevelRule]
ef945e4d
JG
152 return self._log_level_rule
153
154 @property
ce8470c9
MJ
155 def name_pattern_exclusions(self):
156 # type: () -> Optional[List[str]]
ef945e4d
JG
157 return self._name_pattern_exclusions
158
159
160class UserTracepointEventRule(TracepointEventRule):
161 def __init__(
162 self,
ce8470c9
MJ
163 name_pattern=None, # type: Optional[str]
164 filter_expression=None, # type: Optional[str]
165 log_level_rule=None, # type: Optional[LogLevelRule]
166 name_pattern_exclusions=None, # type: Optional[List[str]]
ef945e4d
JG
167 ):
168 TracepointEventRule.__init__(**locals())
169
170
171class KernelTracepointEventRule(TracepointEventRule):
172 def __init__(
173 self,
ce8470c9
MJ
174 name_pattern=None, # type: Optional[str]
175 filter_expression=None, # type: Optional[str]
176 log_level_rule=None, # type: Optional[LogLevelRule]
177 name_pattern_exclusions=None, # type: Optional[List[str]]
ef945e4d
JG
178 ):
179 TracepointEventRule.__init__(**locals())
180
181
182class Channel(abc.ABC):
183 """
184 A channel is an object which is responsible for a set of ring buffers. It is
185 associated to a domain and
186 """
187
188 @staticmethod
ce8470c9
MJ
189 def _generate_name():
190 # type: () -> str
ef945e4d
JG
191 return "channel_{random_id}".format(random_id=_generate_random_string(8))
192
193 @abc.abstractmethod
ce8470c9
MJ
194 def add_context(self, context_type):
195 # type: (ContextType) -> None
ef945e4d
JG
196 pass
197
198 @property
199 @abc.abstractmethod
ce8470c9
MJ
200 def domain(self):
201 # type: () -> TracingDomain
ef945e4d
JG
202 pass
203
204 @property
205 @abc.abstractmethod
ce8470c9
MJ
206 def name(self):
207 # type: () -> str
ef945e4d
JG
208 pass
209
210 @abc.abstractmethod
ce8470c9
MJ
211 def add_recording_rule(self, rule) -> None:
212 # type: (Type[EventRule]) -> None
ef945e4d
JG
213 pass
214
215
216class SessionOutputLocation(abc.ABC):
217 pass
218
219
220class LocalSessionOutputLocation(SessionOutputLocation):
ce8470c9
MJ
221 def __init__(self, trace_path):
222 # type: (pathlib.Path)
ef945e4d
JG
223 self._path = trace_path
224
225 @property
ce8470c9
MJ
226 def path(self):
227 # type: () -> pathlib.Path
ef945e4d
JG
228 return self._path
229
230
231class ProcessAttributeTracker(abc.ABC):
232 """
233 Process attribute tracker used to filter before the evaluation of event
234 rules.
235
236 Note that this interface is currently limited as it doesn't allow changing
237 the tracking policy. For instance, it is not possible to set the tracking
238 policy back to "all" once it has transitioned to "include set".
239 """
240
544d8425 241 @enum.unique
ef945e4d 242 class TrackingPolicy(enum.Enum):
544d8425 243 INCLUDE_ALL = """
ef945e4d
JG
244 Track all possible process attribute value of a given type (i.e. no filtering).
245 This is the default state of a process attribute tracker.
544d8425
MJ
246 """
247 EXCLUDE_ALL = "Exclude all possible process attribute values of a given type."
248 INCLUDE_SET = "Track a set of specific process attribute values."
249
250 def __repr__(self):
251 return "<%s.%s>" % (self.__class__.__name__, self.name)
ef945e4d 252
ce8470c9
MJ
253 def __init__(self, policy):
254 # type: (TrackingPolicy)
ef945e4d
JG
255 self._policy = policy
256
257 @property
ce8470c9
MJ
258 def tracking_policy(self):
259 # type: () -> TrackingPolicy
ef945e4d
JG
260 return self._policy
261
262
263class ProcessIDProcessAttributeTracker(ProcessAttributeTracker):
264 @abc.abstractmethod
ce8470c9
MJ
265 def track(self, pid):
266 # type: (int) -> None
ef945e4d
JG
267 pass
268
269 @abc.abstractmethod
ce8470c9
MJ
270 def untrack(self, pid):
271 # type: (int) -> None
ef945e4d
JG
272 pass
273
274
275class VirtualProcessIDProcessAttributeTracker(ProcessAttributeTracker):
276 @abc.abstractmethod
ce8470c9
MJ
277 def track(self, vpid):
278 # type: (int) -> None
ef945e4d
JG
279 pass
280
281 @abc.abstractmethod
ce8470c9
MJ
282 def untrack(self, vpid):
283 # type: (int) -> None
ef945e4d
JG
284 pass
285
286
287class UserIDProcessAttributeTracker(ProcessAttributeTracker):
288 @abc.abstractmethod
ce8470c9
MJ
289 def track(self, uid):
290 # type: (Union[int, str]) -> None
ef945e4d
JG
291 pass
292
293 @abc.abstractmethod
ce8470c9
MJ
294 def untrack(self, uid):
295 # type: (Union[int, str]) -> None
ef945e4d
JG
296 pass
297
298
299class VirtualUserIDProcessAttributeTracker(ProcessAttributeTracker):
300 @abc.abstractmethod
ce8470c9
MJ
301 def track(self, vuid):
302 # type: (Union[int, str]) -> None
ef945e4d
JG
303 pass
304
305 @abc.abstractmethod
ce8470c9
MJ
306 def untrack(self, vuid):
307 # type: (Union[int, str]) -> None
ef945e4d
JG
308 pass
309
310
311class GroupIDProcessAttributeTracker(ProcessAttributeTracker):
312 @abc.abstractmethod
ce8470c9
MJ
313 def track(self, gid):
314 # type: (Union[int, str]) -> None
ef945e4d
JG
315 pass
316
317 @abc.abstractmethod
ce8470c9
MJ
318 def untrack(self, gid):
319 # type: (Union[int, str]) -> None
ef945e4d
JG
320 pass
321
322
323class VirtualGroupIDProcessAttributeTracker(ProcessAttributeTracker):
324 @abc.abstractmethod
ce8470c9
MJ
325 def track(self, vgid):
326 # type: (Union[int, str]) -> None
ef945e4d
JG
327 pass
328
329 @abc.abstractmethod
ce8470c9
MJ
330 def untrack(self, vgid):
331 # type: (Union[int, str]) -> None
ef945e4d
JG
332 pass
333
334
335class Session(abc.ABC):
336 @staticmethod
ce8470c9
MJ
337 def _generate_name():
338 # type: () -> str
ef945e4d
JG
339 return "session_{random_id}".format(random_id=_generate_random_string(8))
340
341 @property
342 @abc.abstractmethod
ce8470c9
MJ
343 def name(self):
344 # type: () -> str
ef945e4d
JG
345 pass
346
347 @property
348 @abc.abstractmethod
ce8470c9
MJ
349 def output(self):
350 # type: () -> Optional[Type[SessionOutputLocation]]
ef945e4d
JG
351 pass
352
353 @abc.abstractmethod
ce8470c9
MJ
354 def add_channel(self, domain, channel_name=None):
355 # type: (TracingDomain, Optional[str]) -> Channel
ef945e4d
JG
356 """Add a channel with default attributes to the session."""
357 pass
358
359 @abc.abstractmethod
ce8470c9
MJ
360 def start(self):
361 # type: () -> None
ef945e4d
JG
362 pass
363
364 @abc.abstractmethod
ce8470c9
MJ
365 def stop(self):
366 # type: () -> None
ef945e4d
JG
367 pass
368
369 @abc.abstractmethod
ce8470c9
MJ
370 def destroy(self):
371 # type: () -> None
ef945e4d
JG
372 pass
373
b9780062
JG
374 @abc.abstractmethod
375 def is_active(self):
376 # type: () -> bool
377 pass
378
ef945e4d 379 @abc.abstractproperty
ce8470c9
MJ
380 def kernel_pid_process_attribute_tracker(self):
381 # type: () -> Type[ProcessIDProcessAttributeTracker]
ef945e4d
JG
382 raise NotImplementedError
383
384 @abc.abstractproperty
ce8470c9
MJ
385 def kernel_vpid_process_attribute_tracker(self):
386 # type: () -> Type[VirtualProcessIDProcessAttributeTracker]
ef945e4d
JG
387 raise NotImplementedError
388
389 @abc.abstractproperty
390 def user_vpid_process_attribute_tracker(
391 self,
392 ) -> Type[VirtualProcessIDProcessAttributeTracker]:
ce8470c9 393 # type: () -> Type[VirtualProcessIDProcessAttributeTracker]
ef945e4d
JG
394 raise NotImplementedError
395
396 @abc.abstractproperty
ce8470c9
MJ
397 def kernel_gid_process_attribute_tracker(self):
398 # type: () -> Type[GroupIDProcessAttributeTracker]
ef945e4d
JG
399 raise NotImplementedError
400
401 @abc.abstractproperty
ce8470c9
MJ
402 def kernel_vgid_process_attribute_tracker(self):
403 # type: () -> Type[VirtualGroupIDProcessAttributeTracker]
ef945e4d
JG
404 raise NotImplementedError
405
406 @abc.abstractproperty
ce8470c9
MJ
407 def user_vgid_process_attribute_tracker(self):
408 # type: () -> Type[VirtualGroupIDProcessAttributeTracker]
ef945e4d
JG
409 raise NotImplementedError
410
411 @abc.abstractproperty
ce8470c9
MJ
412 def kernel_uid_process_attribute_tracker(self):
413 # type: () -> Type[UserIDProcessAttributeTracker]
ef945e4d
JG
414 raise NotImplementedError
415
416 @abc.abstractproperty
ce8470c9
MJ
417 def kernel_vuid_process_attribute_tracker(self):
418 # type: () -> Type[VirtualUserIDProcessAttributeTracker]
ef945e4d
JG
419 raise NotImplementedError
420
421 @abc.abstractproperty
ce8470c9
MJ
422 def user_vuid_process_attribute_tracker(self):
423 # type: () -> Type[VirtualUserIDProcessAttributeTracker]
ef945e4d
JG
424 raise NotImplementedError
425
426
427class ControlException(RuntimeError):
428 """Base type for exceptions thrown by a controller."""
429
ce8470c9
MJ
430 def __init__(self, msg):
431 # type: (str)
ef945e4d
JG
432 super().__init__(msg)
433
434
435class Controller(abc.ABC):
436 """
437 Interface of a top-level control interface. A control interface can be, for
438 example, the LTTng client or a wrapper around liblttng-ctl. It is used to
439 create and manage top-level objects of a session daemon instance.
440 """
441
442 @abc.abstractmethod
ce8470c9
MJ
443 def create_session(self, name=None, output=None):
444 # type: (Optional[str], Optional[SessionOutputLocation]) -> Session
ef945e4d
JG
445 """
446 Create a session with an output. Don't specify an output
447 to create a session without an output.
448 """
449 pass
b9780062
JG
450
451 @abc.abstractmethod
452 def start_session_by_name(self, name):
453 # type: (str) -> None
454 """
455 Start a session by name.
456 """
457 pass
458
459 @abc.abstractmethod
460 def start_session_by_glob_pattern(self, pattern):
461 # type: (str) -> None
462 """
463 Start sessions whose name matches `pattern`, see GLOB(7).
464 """
465 pass
466
467 @abc.abstractmethod
468 def start_sessions_all(self):
469 """
470 Start all sessions visible to the current user.
471 """
472 # type: () -> None
473 pass
474
475 @abc.abstractmethod
476 def stop_session_by_name(self, name):
477 # type: (str) -> None
478 """
479 Stop a session by name.
480 """
481 pass
482
483 @abc.abstractmethod
484 def stop_session_by_glob_pattern(self, pattern):
485 # type: (str) -> None
486 """
487 Stop sessions whose name matches `pattern`, see GLOB(7).
488 """
489 pass
490
491 @abc.abstractmethod
492 def stop_sessions_all(self):
493 """
494 Stop all sessions visible to the current user.
495 """
496 # type: () -> None
497 pass
498
499 @abc.abstractmethod
500 def destroy_session_by_name(self, name):
501 # type: (str) -> None
502 """
503 Destroy a session by name.
504 """
505 pass
506
507 @abc.abstractmethod
508 def destroy_session_by_glob_pattern(self, pattern):
509 # type: (str) -> None
510 """
511 Destroy sessions whose name matches `pattern`, see GLOB(7).
512 """
513 pass
514
515 @abc.abstractmethod
516 def destroy_sessions_all(self):
517 # type: () -> None
518 """
519 Destroy all sessions visible to the current user.
520 """
521 pass
522
523 @abc.abstractmethod
524 def list_sessions(self):
525 # type: () -> List[Session]
526 """
527 List all sessions visible to the current user.
528 """
529 pass
This page took 0.047189 seconds and 4 git commands to generate.