.. _moving_parts: ================= Moving Parts ================= PyCounters architecture is built around three main concepts: * :ref:`events` reporting (start and end of functions, numerical values etc.) * :ref:`counters` for collecting the above events and analyzing them (on demand). * :ref:`reporters` for outputting the collected statistics. In short, PyCounters is built to allow adding event reporting with piratically no performance impact. Counters add some minimal overhead. Only on output does PyCounters do some calculation (every 5 minutes, depending on configuration). When using PyCounters, consider the following: * Triggering events is extremely lite weight. All events with no corresponding Counters are ignored. * Therefore you can add as many events as you want. * Counters can be registered and unregistered on demand. Only collect what you need. * Outputting is a relatively rare event - don't worry about the calculation it does. .. _events: -------------------- Events -------------------- .. py:currentmodule:: pycounters PyCounters defines two types of events: start and end events Start and end events are used to report the start and end of a function or any other block of code. These events are typically caught by timing counters but anything is possible. Start and end events should be reported through the :func:`report_start` , :func:`report_end` or the :func:`report_start_end` \ decorator. value events These events report a value to the counters. You typically use these to track averages of things but you can get creative. For example - reporting 1 on a cache hit and 0 on a cache miss to an AverageWindowCounter will give you the average rate of cache hits. Value events can be reported by using the :func:`report_value` function. .. note:: There is no special way in PyCounters to create new event it is enough, to create a counter listening to that event. .. _counters: -------------------- Counters -------------------- All the "smartness" of PyCounters is bundled withing a set of Counters. Counters are in charge of intercepting and interpreting events reported by different parts of the program. As mentioned before, you can register a Counter when you want to analyze specific events (by default events of identical name, if you need more control, use events parameter). You do so by using the :py:func:`register_counter` function: :: counter = AverageWindowCounter("some_name") register_counter(counter) You can also unregister the counter once you don't need it anymore: :: unregister_counter(counter=counter) or by name:: unregister_counter(name="some_name") .. note:: After unregistering the counter all events named "some_name" will be ignored (unless some other counter listens to them). .. note:: You can only register a single counter for any given name. .. _reporters: -------------------- Reporters -------------------- .. py:currentmodule:: pycounters.reporters Reporters are used to collect a report from the currently registered Counters. Reporters are not supposed to run often as that will have a performance impact. At the moment PyCounters can only output to python logs and JSON files. For example, to output to logs, create an instance of :obj:`LogReporter ` . You can then manually output reports (using :func:`output_report `) or turn on auto reporting (using :func:`start_auto_reporting ` .) :: reporter=pycounters.reporters.LogReporter(logging.getLogger("counters")) pycounters.register_reporter(reporter) #... some where later pycounters.output_report() .. _shortcuts: --------------------- Shortcuts --------------------- These are functions which both report events and auto add the most common Counter for them. See :ref:`shortcut_functions` for more details and :ref:`simple_examples` in the main documentation page for usage examples.