********************
Tracing Manager
********************

I. Introduction to the Tracing Manager
=======================================

The tracing manager is a core service which supplies a configurable
method for Python code within Dia to notify the user of runtime
events. The user can specify what level messages should be reported,
filter by device or module name, and redirect output to stdout,
stderr, and/or files.

II. Usage
===========

The developer needs to take several things into consideration when 
adding tracing calls.

First, each trace message is connected to a 
particular :class:`~core.tracing.Tracer` object. This object is 
generally named after the device, presentation, logger, or
service name if applicable.  Otherwise, it should be something
identifiable like the module or (in rare cases) the function name.

Second, the developer must decide the trace level for each message.

Finally, each message must be formatted as either a simple string 
or as a format string, with each parameter filled by following arguments, like this::

  self.__tracer.debug('We have a %s problem, %s!', 'big', 'sir')



1. Trace Levels
----------------

Developers can specify the importance of messages using various trace
levels.  The five different trace levels, from highest to lowest
importance, are:

**critical**
    Used for top-priority messages.  Something fundamentally
    broke, and something drastic is probably going to happen.

**error**
    Reserved for messages about broken functionality.

**warning**
    Used for noting minor transient problems, depreciated or incorrect 
    configurations, or other out-of-the-ordinary happenings.

**info**
    This level is used to note significant, normal events. Users might 
    be interested in this level.
    

**debug**
    Users are probably not interested in this trace level. It is used
    for recording technical details, and is usually quite verbose.
    

Each of these levels has a corresponding method on the
:class:`~core.tracing.Tracer` object.


2. Creating a Trace object
---------------------------

Each Python module which uses the tracing manager uses at least 
one :class:`~core.tracing.Tracer` object. To get a reference to 
a Tracer, use the ``tracing.get_tracer(name)`` function. By
convention, name should be the device, presentation, logger, or
service name if applicable.  Otherwise, it should be something
identifiable like the module or (in rare cases) the function name.

The standard way to initialize a Tracer for a device is like this: ::

  class SomeDevice(DeviceBase, threading.Thread):
    """
    This is an example of some device.
    """

    def __init__(self, name, core_services):
        self.__name = name
        self.__core = core_services

        from core.tracing import get_tracer
        self.__tracer = get_tracer(name)

Then, use the tracer like this: ::

  def apply_settings(self):
      SettingsBase.merge_settings(self)
      accepted, rejected, not_found = SettingsBaseverify_settings(self)
      if len(rejected) or len(not_found):
          self.__tracer.error("Settings rejected/not found: %s %s",
                               rejected, not_found)



 
