For better performance monitoring and debugging, it's needed to be able to count number of some events (like some updates, queries to external sources, etc.) per specified time interval. Currently, there is such counting in some modules (e.g. DNSBL module counts number of requests made per day, UpdateManager stores some statistics to files for Munin), but it's needed in other places as well and it should be unified.
Therefore, a special module/class EventCountLogger
should be created.
It should keep a counter for each event ID. EventIDs are registered dynamically by other modules and then incremented by calling a logEvent
method. EventIDs are grouped into groups. Each group has defined a time interval and a filename. Each time interval, current values of couters in the group are dumped to the file are reset to 0.
Methods:
registerEvents(group, log_frequency, [event_ids])
group
- group of events, used as a name of file
log_frequency
- how often to log the counters to file (in seconds)
event_ids
- list of strings (all these events will be logged together to the given file)
- All files are stored in a directory set in configuration.
- Creates a group containing a counter (initialized to 0) for each id in
event_ids
- logEvent(event_id, count=1)
- Add
count
to the counter(s) of event_id
EventIDs do NOT have to be unique among groups - if one id is present in more groups, all corresponding counters are incremented.
This can be used e.g. to count one event both every minute and every day - call:
registerEvents("mygroup_1h", 3600, ["myevent1", "myevent2"])
registerEvents("mygroup_24h", 24*3600, ["myevent1", "myevent2"])
Then, just call logEvent("myevent1")
and numbers of such calls will be logged hourly in "mygroup_1h" file and daily in "mygroup_24h" file.
For time scheduling, I recommend to use APScheduler (which is already used by other parts of NERD).
Time intervals should be "aligned", so for example, if interval is 60 seconds, counters should be written at 00:00, 01:00, 02:00, etc. (basically, when unix_timestamp % interval == 0
).
It would also be nice (not necessary in first version), if counters can survive NERDd restart. That is, counters should be dumped whe NERDd stops; and when it starts and event groups are registered, it should look for existing counter files and their time of last modification, and if the interval hasn't elapsed yet, initialize counters from the file.
Format of the file:
#YYYY-MM-DDTHH:MM:SS
eventid count
eventid count
The module will be part of NERD "core" (i.e. in core
directory). An instance of EventCountLogger
will be created in nerdd.py
during startup and stored to g
("globals" module) so it's accessible throughout the application.