LSST Applications g00274db5b6+edbf708997,g00d0e8bbd7+edbf708997,g199a45376c+5137f08352,g1fd858c14a+1d4b6db739,g262e1987ae+f4d9505c4f,g29ae962dfc+7156fb1a53,g2cef7863aa+73c82f25e4,g35bb328faa+edbf708997,g3e17d7035e+5b3adc59f5,g3fd5ace14f+852fa6fbcb,g47891489e3+6dc8069a4c,g53246c7159+edbf708997,g64539dfbff+9f17e571f4,g67b6fd64d1+6dc8069a4c,g74acd417e5+ae494d68d9,g786e29fd12+af89c03590,g7ae74a0b1c+a25e60b391,g7aefaa3e3d+536efcc10a,g7cc15d900a+d121454f8d,g87389fa792+a4172ec7da,g89139ef638+6dc8069a4c,g8d7436a09f+28c28d8d6d,g8ea07a8fe4+db21c37724,g92c671f44c+9f17e571f4,g98df359435+b2e6376b13,g99af87f6a8+b0f4ad7b8d,gac66b60396+966efe6077,gb88ae4c679+7dec8f19df,gbaa8f7a6c5+38b34f4976,gbf99507273+edbf708997,gc24b5d6ed1+9f17e571f4,gca7fc764a6+6dc8069a4c,gcc769fe2a4+97d0256649,gd7ef33dd92+6dc8069a4c,gdab6d2f7ff+ae494d68d9,gdbb4c4dda9+9f17e571f4,ge410e46f29+6dc8069a4c,geaed405ab2+e194be0d2b,w.2025.47
LSST Data Management Base Package
Loading...
Searching...
No Matches
lsst.dax.apdb.monitor.MonService Class Reference
Inheritance diagram for lsst.dax.apdb.monitor.MonService:

Public Member Functions

None set_filters (self, Iterable[str] rules)
 
Iterable[MonHandlerhandlers (self)
 
None add_handler (self, MonHandler handler)
 
None remove_handler (self, MonHandler handler)
 
Iterator[None] context_tags (self, _TagsType tags)
 

Protected Member Functions

None _add_record (self, *, str agent_name, str record_name, Mapping[str, Any] values, Mapping[str, str|int]|None tags=None, float|None timestamp=None)
 
None _default_init (self)
 
_TagsType|None _add_context_tags (self, _TagsType tags)
 

Static Protected Attributes

list _handlers = []
 
_TagsType _context_tags = None
 
list _filters = []
 
bool _initialized = False
 

Detailed Description

Class implementing monitoring service functionality.

Notes
-----
This is a singleton class which serves all client agents in an application.
It accepts records from agents, filters it based on a set of configured
rules and forwards them to one or more configured handlers. By default
there are no handlers defined which means that all records are discarded.
Default set of filtering rules is empty which accepts all agent names.

To produce a useful output from this service one has to add at least one
handler using `add_handler` method (e.g. `LoggingMonHandler` instance).
The `set_filters` methods can be used to specify the set of filtering
rules.

Definition at line 193 of file monitor.py.

Member Function Documentation

◆ _add_context_tags()

_TagsType | None lsst.dax.apdb.monitor.MonService._add_context_tags ( self,
_TagsType tags )
protected
Extend the tag context with new tags, overriding any tags that may
already exist in a current context.

Definition at line 361 of file monitor.py.

361 def _add_context_tags(self, tags: _TagsType) -> _TagsType | None:
362 """Extend the tag context with new tags, overriding any tags that may
363 already exist in a current context.
364 """
365 old_tags = self._context_tags
366 if not self._context_tags:
367 self._context_tags = tags
368 else:
369 all_tags = dict(self._context_tags)
370 all_tags.update(tags)
371 self._context_tags = all_tags
372 return old_tags
373

◆ _add_record()

None lsst.dax.apdb.monitor.MonService._add_record ( self,
* ,
str agent_name,
str record_name,
Mapping[str, Any] values,
Mapping[str, str | int] | None tags = None,
float | None timestamp = None )
protected
Add one monitoring record, this method is for use by agents only.

Definition at line 259 of file monitor.py.

267 ) -> None:
268 """Add one monitoring record, this method is for use by agents only."""
269 if not self._initialized:
270 try:
271 self._default_init()
272 self._initialized = True
273 except Exception as exc:
274 # Complain but continue.
275 message = f"Error in configuration of monitoring service: {exc}"
276 # Stack level does not really matter.
277 warnings.warn(message, stacklevel=3)
278 if self._handlers:
279 accept: bool | None = None
280 # Check every filter, accept if none makes any decision.
281 for filter in self._filters:
282 accept = filter.accept(agent_name)
283 if accept is False:
284 return
285 if accept is True:
286 break
287 if timestamp is None:
288 timestamp = time.time()
289 if tags is None:
290 tags = self._context_tags or {}
291 else:
292 if self._context_tags:
293 all_tags = dict(self._context_tags)
294 all_tags.update(tags)
295 tags = all_tags
296 for handler in self._handlers:
297 handler.handle(record_name, timestamp, tags, values, agent_name)
298

◆ _default_init()

None lsst.dax.apdb.monitor.MonService._default_init ( self)
protected
Perform default initialization of the service.

Definition at line 299 of file monitor.py.

299 def _default_init(self) -> None:
300 """Perform default initialization of the service."""
301 if env := os.environ.get(_CONFIG_ENV):
302 # Configuration is specified as colon-separated list of key:value
303 # pairs or simple values. Simple values are treated as filters
304 # (see set_filters for syntax). key-values pairs pairs specify
305 # handlers, for now the only supported handler is logging, it
306 # is specified as "logging:<logger-name>[:<level>]".
307 filters = []
308 handlers: list[MonHandler] = []
309 for item in env.split(","):
310 pieces = item.split(":")
311 if len(pieces) in (2, 3) and pieces[0] == "logging":
312 logger_name = pieces[1]
313 if len(pieces) == 3:
314 level_name = pieces[2]
315 level = logging.getLevelNamesMapping().get(level_name.upper())
316 if level is None:
317 raise ValueError(
318 f"Unknown logging level name {level_name!r} in {_CONFIG_ENV}={env!r}"
319 )
320 else:
321 level = logging.INFO
322 handlers.append(LoggingMonHandler(logger_name, level))
323 elif len(pieces) == 1:
324 filters.extend(pieces)
325 else:
326 raise ValueError(f"Unexpected format of item {item!r} in {_CONFIG_ENV}={env!r}")
327 for handler in handlers:
328 self.add_handler(handler)
329 self.set_filters(filters)
330

◆ add_handler()

None lsst.dax.apdb.monitor.MonService.add_handler ( self,
MonHandler handler )
Add one monitoring handler.

Parameters
----------
handler : `MonHandler`
    Handler instance.

Definition at line 336 of file monitor.py.

336 def add_handler(self, handler: MonHandler) -> None:
337 """Add one monitoring handler.
338
339 Parameters
340 ----------
341 handler : `MonHandler`
342 Handler instance.
343 """
344 # Manually adding handler means default initialization should be
345 # skipped.
346 self._initialized = True
347 if handler not in self._handlers:
348 self._handlers.append(handler)
349

◆ context_tags()

Iterator[None] lsst.dax.apdb.monitor.MonService.context_tags ( self,
_TagsType tags )
Context manager that adds a set of tags to all records created
inside the context.

Typically clients will be using `MonAgent.context_tags`, which forwards
to this method.

Definition at line 375 of file monitor.py.

375 def context_tags(self, tags: _TagsType) -> Iterator[None]:
376 """Context manager that adds a set of tags to all records created
377 inside the context.
378
379 Typically clients will be using `MonAgent.context_tags`, which forwards
380 to this method.
381 """
382 old_context = self._add_context_tags(tags)
383 try:
384 yield
385 finally:
386 # Restore old context.
387 self._context_tags = old_context
388
389

◆ handlers()

Iterable[MonHandler] lsst.dax.apdb.monitor.MonService.handlers ( self)
Set of handlers defined currently.

Definition at line 332 of file monitor.py.

332 def handlers(self) -> Iterable[MonHandler]:
333 """Set of handlers defined currently."""
334 return self._handlers
335

◆ remove_handler()

None lsst.dax.apdb.monitor.MonService.remove_handler ( self,
MonHandler handler )
Remove a monitoring handler.

Parameters
----------
handler : `MonHandler`
    Handler instance.

Definition at line 350 of file monitor.py.

350 def remove_handler(self, handler: MonHandler) -> None:
351 """Remove a monitoring handler.
352
353 Parameters
354 ----------
355 handler : `MonHandler`
356 Handler instance.
357 """
358 if handler in self._handlers:
359 self._handlers.remove(handler)
360

◆ set_filters()

None lsst.dax.apdb.monitor.MonService.set_filters ( self,
Iterable[str] rules )
Define a sequence of rules for filtering of the agent names.

Parameters
----------
rules : `~collections.abc.Iterable` [`str`]
    Ordered collection of rules.  Each string specifies filtering rule
    for a single name, or catch-all rule.  The rule consist of the
    agent name prefixed by minus or optional plus sign. Catch-all rule
    uses name "any". If the rule starts with minus sign then matching
    agent will be rejected. Otherwise matching agent is accepted.

Notes
-----
The catch-all rule (`-any`, `+any`, or `any`) can be specified in any
location in the sequence but it is always applied last. E.g.
`["-any", "+agent1"]` behaves the same as `["+agent1", "-any"]`.
If the set of rues does not include catch-all rule, filtering behaves
as if it is added implicitly as `+any`.

Filtering code evaluates each rule in order. First rule that matches
the agent name wins. Agent names are matched literally, wildcards are
not supported and there are no parent/child relations between agent
names (e.g `lsst.dax.apdb` and `lsst.dax.apdb.sql` are treated as
independent names).

Definition at line 222 of file monitor.py.

222 def set_filters(self, rules: Iterable[str]) -> None:
223 """Define a sequence of rules for filtering of the agent names.
224
225 Parameters
226 ----------
227 rules : `~collections.abc.Iterable` [`str`]
228 Ordered collection of rules. Each string specifies filtering rule
229 for a single name, or catch-all rule. The rule consist of the
230 agent name prefixed by minus or optional plus sign. Catch-all rule
231 uses name "any". If the rule starts with minus sign then matching
232 agent will be rejected. Otherwise matching agent is accepted.
233
234 Notes
235 -----
236 The catch-all rule (`-any`, `+any`, or `any`) can be specified in any
237 location in the sequence but it is always applied last. E.g.
238 `["-any", "+agent1"]` behaves the same as `["+agent1", "-any"]`.
239 If the set of rues does not include catch-all rule, filtering behaves
240 as if it is added implicitly as `+any`.
241
242 Filtering code evaluates each rule in order. First rule that matches
243 the agent name wins. Agent names are matched literally, wildcards are
244 not supported and there are no parent/child relations between agent
245 names (e.g `lsst.dax.apdb` and `lsst.dax.apdb.sql` are treated as
246 independent names).
247 """
248 match_all: MonFilter | None = None
249 self._filters = []
250 for rule in rules:
251 mon_filter = MonFilter(rule)
252 if mon_filter.is_match_all():
253 match_all = mon_filter
254 else:
255 self._filters.append(mon_filter)
256 if match_all:
257 self._filters.append(match_all)
258

Member Data Documentation

◆ _context_tags

_TagsType lsst.dax.apdb.monitor.MonService._context_tags = None
staticprotected

Definition at line 213 of file monitor.py.

◆ _filters

list lsst.dax.apdb.monitor.MonService._filters = []
staticprotected

Definition at line 216 of file monitor.py.

◆ _handlers

list lsst.dax.apdb.monitor.MonService._handlers = []
staticprotected

Definition at line 210 of file monitor.py.

◆ _initialized

bool lsst.dax.apdb.monitor.MonService._initialized = False
staticprotected

Definition at line 219 of file monitor.py.


The documentation for this class was generated from the following file: