summaryrefslogtreecommitdiff
path: root/tracing.py
blob: efef8e219f2372f32622140ea43185b42c874ee6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# Copyright (C) 2011  Lars Wirzenius <liw@liw.fi>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.


'''Python debubbing log messages.

This module provides a couple of functions for logging debug messages.
It is sometimes practical to add a lot of debugging log messages to a
program, but having them enabled all the time results in very large
log files. Also, logging that much takes quite a bit of time.

This module provides a way to turn such debugging or tracing messages
on and off, based on the filename they occur in. For example:

    import tracing
    
    tracing.trace_add_pattern('foobar')
    tracing.trace_add_pattern('yeehaa')
    
    ...
    
    tracing.trace('start procedure')
    tracing.trace('arg1=%s' % arg1)
    tracing.trace('arg2=%s' % arg2)
    
Only calls that happen in files whose names contain 'foobar' or
'yeehaa' will actually be logged. Pattern matching is based on
substring checking only, no globbing or regexps, sorry.

'''


import logging
import os
import traceback


trace_patterns = []
trace_cache = set()


def trace_add_pattern(pattern):
    trace_patterns.append(pattern)
    
    
def trace_clear_patterns():
    del trace_patterns[:]
    trace_cache.clear()


def trace(msg, *args):
    if trace_patterns:
        frames = traceback.extract_stack(limit=2)
        filename, lineno, funcname, text = frames[0]
        log_it = filename in trace_cache
        if not log_it:
            for pattern in trace_patterns:
                if pattern in filename:
                    log_it = True
                    trace_cache.add(filename)
                    break
        if log_it:
            filename = os.path.basename(filename)
            msg = msg % args
            logging.debug('%s:%s:%s: %s' % (filename, lineno, funcname, msg))