Include _generated now so I get all the latest fancy stuff
[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 _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         self._implement_property_set(DEBUG, {'Enabled': self._set_enabled})
59         logging.getLogger(root).addHandler(self)
60         sys.stderr = StdErrWrapper(self, sys.stderr)
61
62     def _set_enabled(self, value):
63         self.enabled = value
64
65     def GetMessages(self):
66         return self._messages
67
68     def add_message(self, timestamp, name, level, msg):
69         if len(self._messages) >= DEBUG_MESSAGE_LIMIT:
70             self._messages.pop()
71         self._messages.append((timestamp, name, level, msg))
72         if self.enabled:
73             self.NewDebugMessage(timestamp, name, level, msg)
74
75     # Handle logging module messages
76
77     def emit(self, record):
78         name = self.get_record_name(record)
79         level = self.get_record_level(record)
80         self.add_message(record.created, name, level, record.msg)
81
82     def get_record_level(self, record):
83         return LEVELS[record.levelno]
84
85     def get_record_name(self, record):
86         name = record.name
87         if name.contains("."):
88             domain, category = record.name.split('.', 1)
89             name = domain + "/" + category
90         return name
91
92 # Wrapper around stderr so the exceptions are logged
93
94 class StdErrWrapper(object):
95
96     def __init__(self, interface, stderr):
97         self._buffer = ""
98         self._interface = interface
99         self._stderr = stderr
100
101     def __getattr__(self, attr):
102         return getattr(self._stderr, attr)
103
104     def write(self, string):
105         self._stderr.write(string)
106         if '\n' not in string:
107             self._buffer += string
108             return
109
110         lines = string.split('\n')
111         lines[0] = self._buffer + lines[0]
112         self._buffer = lines[-1]
113         del lines[-1]
114
115         timestamp = time.time()
116         for line in lines:
117             self._interface.add_message(timestamp, "stderr", DEBUG_LEVEL_ERROR, line)