Tracer API

Tracer provides a small interface that you can use in your application. It consist from Query class which is able to ask Tracer for various informations and provide you a results. And from data structues from which results consists.

Surely you could access internal classes and methods on your own, but there is a risk that they will change in the future. In API could be a little changes too, but they will be documented


class tracer.Query(tracer=<class 'tracer.resources.tracer.Tracer'>)[source]

Provide API for Tracer querying operations. They are executed kind of lazily, so running the operation will return just an wrapper class with get() method.


from tracer.query import Query
q = Query()


Some querying methods can require root permissions


Return list of applications which use some outdated files


List of Package that only should be traced


Pretend that specified packages have been updated just now. Benefit of this is absolutely no need for openning the package history database


Tracer also provides API for user-defined hooks. They can be defined as a simple functions decorated by @hooks.match("app_name"). Tracer will search for them in directories ~/.config/tracer/hooks/ and /etc/tracer/hooks/. Such hook will be called when tracer determines, that linked application needs restarting.


Decorator for tracer hooks.


from tracer import hooks

def hook_app():
    print("Hey, application foo was found")


You can match multiple applications by calling @hooks.match with list of them.


If you want to run tracer’s hooks and print no other output, use tracer --hooks-only

Exit codes

In some use-cases you may want to examine Tracer’s results through exit codes (also known as status codes). See their meanings:

1-99 Error exit codes
0 No affected applications
101 Found some affected applications
102 Found some affected daemons
103 Session restart needed
104 Reboot needed

Data structures

Follows list of classes which quering results may consist from. Not all their properties are covered within API. If your use case requires some which are not listed below, please let me know to cover them in API too.


class tracer.Package(name, modified=None)[source]

Represents linux package

modified = None

UNIX timestamp of the modification

name = None

Name of the package


class tracer.Application(attributes_dict)[source]

Represent the application defined in applications.xml

  • name (str) – The name of the application
  • type (str) – See Applications.TYPES for possible values
  • helper (str) – Describes how to restart the applications
  • note (bool) – Provides additional informations to the helper
  • ignore (bool) – If True, the application won’t be printed
  • processes_factory (Processes) – Class providing list of running processes

Return the list of helpers which describes how to restart the application. When no helper_format was described, empty list will be returned. If helper_format contains process specific arguments such a {PID}, etc. list will contain helper for every application instance. In other cases, there will be just one helper in the list.


Return collection of processes with same name as application. I.e. running instances of the application

class tracer.Process(pid=None)[source]

Represent the process instance uniquely identifiable through PID

For all class properties and methods, please see

Below listed are only reimplemented ones.

For performance reasons, instances are cached based on PID, and multiple instantiations of a Process object with the same PID will return the same object. To clear the cache, invoke Process.reset_cache(). Additionally, as with ProcessWrapper, process information is cached at object creation. To force a refresh, invoke the rebuild_cache() method on the object.


The collection of process’s children. Each of them casted from psutil.Process to tracer Process.


The absolute path to process executable. Cleaned from arbitrary strings which appears on the end.


The parent process casted from psutil.Process to tracer Process

static safe_isfile(file_path, timeout=0.5)[source]

Process arguments could be referring to files on remote filesystems and os.path.isfile will hang forever if the shared FS is offline. Instead, use a subprocess that we can time out if we can’t reach some file.


The user who owns the process. If user was deleted in the meantime, None is returned instead.