Switching from deleting caches to version checking the cache
[theonering] / src / tp / debug.py
1 # telepathy-python - Base classes defining the interfaces of the Telepathy framework
2 #
3 # Copyright (C) 2009 Collabora Limited
4 #
5 # This library is free software; you can redistribute it and/or
6 # modify it under the terms of the GNU Lesser General Public
7 # License as published by the Free Software Foundation; either
8 # version 2.1 of the License, or (at your option) any later version.
9 #
10 # This library is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 # Lesser General Public License for more details.
14 #
15 # You should have received a copy of the GNU Lesser General Public
16 # License along with this library; if not, write to the Free Software
17 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
19 from telepathy.interfaces import DEBUG
20 from telepathy.constants import (DEBUG_LEVEL_ERROR,
21                                  DEBUG_LEVEL_CRITICAL,
22                                  DEBUG_LEVEL_WARNING,
23                                  DEBUG_LEVEL_INFO,
24                                  DEBUG_LEVEL_DEBUG)
25
26 from telepathy._generated.Debug import Debug as _Debug
27 from properties import DBusProperties
28
29 import dbus.service
30 import logging
31 import sys
32 import time
33
34 LEVELS = {
35         logging.ERROR:   DEBUG_LEVEL_ERROR,
36         logging.FATAL:   DEBUG_LEVEL_CRITICAL,
37         logging.WARNING: DEBUG_LEVEL_WARNING,
38         logging.INFO:    DEBUG_LEVEL_INFO,
39         logging.DEBUG:   DEBUG_LEVEL_DEBUG,
40         logging.NOTSET:  DEBUG_LEVEL_DEBUG
41 }
42
43 DEBUG_MESSAGE_LIMIT = 800
44
45 class Debug(_Debug, DBusProperties, logging.Handler):
46
47     def __init__(self, conn_manager, root=''):
48         self.enabled = False
49         self._interfaces = set()
50         self._messages = []
51         object_path = '/org/freedesktop/Telepathy/debug'
52
53         _Debug.__init__(self, conn_manager._name, object_path)
54         DBusProperties.__init__(self)
55         logging.Handler.__init__(self)
56
57         self._implement_property_get(DEBUG, {'Enabled': lambda: self.enabled})
58         logging.getLogger(root).addHandler(self)
59         sys.stderr = StdErrWrapper(self, sys.stderr)
60
61     def GetMessages(self):
62         return self._messages
63
64     def add_message(self, timestamp, name, level, msg):
65         if len(self._messages) >= DEBUG_MESSAGE_LIMIT:
66             self._messages.pop()
67         self._messages.append((timestamp, name, level, msg))
68         if self.enabled:
69             self.NewDebugMessage(timestamp, name, level, msg)
70
71     # Handle logging module messages
72
73     def emit(self, record):
74         name = self.get_record_name(record)
75         level = self.get_record_level(record)
76         self.add_message(record.created, name, level, record.msg)
77
78     def get_record_level(self, record):
79         return LEVELS[record.levelno]
80
81     def get_record_name(self, record):
82         name = record.name
83         if name.contains("."):
84             domain, category = record.name.split('.', 1)
85             name = domain + "/" + category
86         return name
87
88 # Wrapper around stderr so the exceptions are logged
89
90 class StdErrWrapper(object):
91
92     def __init__(self, interface, stderr):
93         self._buffer = ""
94         self._interface = interface
95         self._stderr = stderr
96
97     def __getattr__(self, attr):
98         return getattr(self._stderr, attr)
99
100     def write(self, string):
101         self._stderr.write(string)
102         if '\n' not in string:
103             self._buffer += string
104             return
105
106         lines = string.split('\n')
107         lines[0] = self._buffer + lines[0]
108         self._buffer = lines[-1]
109         del lines[-1]
110
111         timestamp = time.time()
112         for line in lines:
113             self._interface.add_message(timestamp, "stderr", DEBUG_LEVEL_ERROR, line)