comparison src/plugins/plugin_misc_xmllog.py @ 2440:51d346e283fd

plugin XML Log: Monkey patch is done on the whole XmlStream class, making it available as soon as the stream start + long received message are sent once fully parsed (not cut anymore)
author Goffi <goffi@goffi.org>
date Sat, 18 Nov 2017 18:49:57 +0100
parents 33c8c4973743
children
comparison
equal deleted inserted replaced
2439:6908fe4c6eca 2440:51d346e283fd
19 19
20 from sat.core.i18n import _ 20 from sat.core.i18n import _
21 from sat.core.constants import Const as C 21 from sat.core.constants import Const as C
22 from sat.core.log import getLogger 22 from sat.core.log import getLogger
23 log = getLogger(__name__) 23 log = getLogger(__name__)
24 from twisted.words.protocols.jabber.xmlstream import XmlStream
25 from twisted.words.xish import domish 24 from twisted.words.xish import domish
25 from twisted.words.xish import xmlstream
26 26
27 PLUGIN_INFO = { 27 PLUGIN_INFO = {
28 C.PI_NAME: "Raw XML log Plugin", 28 C.PI_NAME: "Raw XML log Plugin",
29 C.PI_IMPORT_NAME: "XmlLog", 29 C.PI_IMPORT_NAME: "XmlLog",
30 C.PI_TYPE: "Misc", 30 C.PI_TYPE: "Misc",
31 C.PI_PROTOCOLS: [], 31 C.PI_PROTOCOLS: [],
32 C.PI_DEPENDENCIES: [], 32 C.PI_DEPENDENCIES: [],
33 C.PI_MAIN: "XmlLog", 33 C.PI_MAIN: "XmlLog",
34 C.PI_HANDLER: "no", 34 C.PI_HANDLER: "no",
35 C.PI_DESCRIPTION: _("""Send raw XML logs to bridge""") 35 C.PI_DESCRIPTION: _(u"""Send raw XML logs to bridge""")
36 } 36 }
37 37
38 host = None
38 39
39 class LoggingXmlStream(XmlStream): 40 def send(self, obj):
40 """This class send the raw XML to the Bridge, for logging purpose""" 41 global host
42 if isinstance(obj, basestring):
43 log = unicode(obj)
44 elif isinstance(obj, domish.Element):
45 log = obj.toXml()
46 else:
47 log.error(_(u'INTERNAL ERROR: Unmanaged XML type'))
48 host.bridge.xmlLog("OUT", log, self._profile)
49 return self._original_send(obj)
41 50
42 def send(self, obj):
43 if isinstance(obj, basestring):
44 log = unicode(obj)
45 elif isinstance(obj, domish.Element):
46 log = obj.toXml()
47 else:
48 log.error(_('INTERNAL ERROR: Unmanaged XML type'))
49 self._host.bridge.xmlLog("OUT", log, self._profile)
50 return XmlStream.send(self, obj)
51 51
52 def dataReceived(self, data): 52 def onElement(self, element):
53 # FIXME: we use "replace" here because a big stanza can be cut in the middle of a unicode char 53 global host
54 # this plugin should probably moved to a better place, where stanzas are fully received 54 host.bridge.xmlLog("IN", element.toXml(), self._profile)
55 self._host.bridge.xmlLog("IN", data.decode('utf-8', 'replace'), self._profile) 55 return self._original_onElement(element)
56 return XmlStream.dataReceived(self, data)
57 56
58 57
59 class XmlLog(object): 58 class XmlLog(object):
60 59
61 params = """ 60 params = """
66 </category> 65 </category>
67 </general> 66 </general>
68 </params> 67 </params>
69 """ % {"label_xmllog": _("Activate XML log")} 68 """ % {"label_xmllog": _("Activate XML log")}
70 69
71 def __init__(self, host): 70 def __init__(self, host_):
72 log.info(_("Plugin XML Log initialization")) 71 log.info(_("Plugin XML Log initialization"))
73 self.host = host 72 global host
73 host = host_
74 74
75 #parameters 75 #parameters
76 host.memory.updateParams(self.params) 76 host.memory.updateParams(self.params)
77 77
78 #bridge 78 #bridge
79 host.bridge.addSignal("xmlLog", ".plugin", signature='sss') # args: direction("IN" or "OUT"), xml_data, profile 79 host.bridge.addSignal("xmlLog", ".plugin", signature='sss') # args: direction("IN" or "OUT"), xml_data, profile
80 80
81 do_log = self.host.memory.getParamA("Xml log", "Debug") 81 self.do_log = host.memory.getParamA("Xml log", "Debug")
82 if do_log: 82 if self.do_log:
83 log.info(_("XML log activated")) 83 XmlStream = xmlstream.XmlStream
84 host.trigger.add("XML Initialized", self.logXml) 84 XmlStream._original_send = XmlStream.send
85 XmlStream._original_onElement = XmlStream.onElement
86 XmlStream.send = send
87 XmlStream.onElement = onElement
88 XmlStream._profile = ''
89 host.trigger.add("XML Initialized", self.setProfile)
90 log.info(_(u"XML log activated"))
85 91
86 def logXml(self, xmlstream, profile): 92 def setProfile(self, xmlstream, profile):
87 xmlstream.__class__ = LoggingXmlStream
88 xmlstream._profile = profile 93 xmlstream._profile = profile
89 xmlstream._host = self.host
90 return True 94 return True