xmllayout2 2.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,22 @@
1
+ # Auto detect text files and perform LF normalization
2
+ * text=auto
3
+
4
+ # Custom for Visual Studio
5
+ *.cs diff=csharp
6
+ *.sln merge=union
7
+ *.csproj merge=union
8
+ *.vbproj merge=union
9
+ *.fsproj merge=union
10
+ *.dbproj merge=union
11
+
12
+ # Standard to msysgit
13
+ *.doc diff=astextplain
14
+ *.DOC diff=astextplain
15
+ *.docx diff=astextplain
16
+ *.DOCX diff=astextplain
17
+ *.dot diff=astextplain
18
+ *.DOT diff=astextplain
19
+ *.pdf diff=astextplain
20
+ *.PDF diff=astextplain
21
+ *.rtf diff=astextplain
22
+ *.RTF diff=astextplain
@@ -0,0 +1,103 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+
5
+ # C extensions
6
+ *.so
7
+
8
+ # Distribution / packaging
9
+ .Python
10
+ env/
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ eggs/
15
+ lib/
16
+ lib64/
17
+ parts/
18
+ sdist/
19
+ var/
20
+ *.egg-info/
21
+ .installed.cfg
22
+ *.egg
23
+
24
+ # PyInstaller
25
+ # Usually these files are written by a python script from a template
26
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
27
+ *.manifest
28
+ *.spec
29
+
30
+ # Installer logs
31
+ pip-log.txt
32
+ pip-delete-this-directory.txt
33
+
34
+ # Unit test / coverage reports
35
+ htmlcov/
36
+ .tox/
37
+ .coverage
38
+ .cache
39
+ nosetests.xml
40
+ coverage.xml
41
+
42
+ # Translations
43
+ *.mo
44
+ *.pot
45
+
46
+ # Django stuff:
47
+ *.log
48
+
49
+ # Sphinx documentation
50
+ docs/_build/
51
+
52
+ # PyBuilder
53
+ target/
54
+
55
+ # =========================
56
+ # Operating System Files
57
+ # =========================
58
+
59
+ # OSX
60
+ # =========================
61
+
62
+ .DS_Store
63
+ .AppleDouble
64
+ .LSOverride
65
+
66
+ # Icon must end with two \r
67
+ Icon
68
+
69
+
70
+ # Thumbnails
71
+ ._*
72
+
73
+ # Files that might appear on external disk
74
+ .Spotlight-V100
75
+ .Trashes
76
+
77
+ # Directories potentially created on remote AFP share
78
+ .AppleDB
79
+ .AppleDesktop
80
+ Network Trash Folder
81
+ Temporary Items
82
+ .apdisk
83
+
84
+ # Windows
85
+ # =========================
86
+
87
+ # Windows image file caches
88
+ Thumbs.db
89
+ ehthumbs.db
90
+
91
+ # Folder config file
92
+ Desktop.ini
93
+
94
+ # Recycle Bin used on file shares
95
+ $RECYCLE.BIN/
96
+
97
+ # Windows Installer files
98
+ *.cab
99
+ *.msi
100
+ *.msm
101
+ *.msp
102
+
103
+ venv/
@@ -0,0 +1,23 @@
1
+ Copyright (c) 2014: Philip Jenvey, 2020-2025: Jonas Lindner
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without
5
+ modification, are permitted provided that the following conditions are met:
6
+
7
+ * Redistributions of source code must retain the above copyright notice, this
8
+ list of conditions and the following disclaimer.
9
+
10
+ * Redistributions in binary form must reproduce the above copyright notice,
11
+ this list of conditions and the following disclaimer in the documentation
12
+ and/or other materials provided with the distribution.
13
+
14
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
18
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
20
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
21
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
22
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,57 @@
1
+ Metadata-Version: 2.2
2
+ Name: xmllayout2
3
+ Version: 2.0.0
4
+ Summary: Formats Python log messages as log4j XMLLayout XML
5
+ Home-page: http://pypi.python.org/pypi/XMLLayout
6
+ Author: Jonas Lindner
7
+ Author-email: jonaslindner55@gmail.com
8
+ License: BSD
9
+ Keywords: logging log4j
10
+ Classifier: Development Status :: 5 - Production/Stable
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: License :: OSI Approved :: BSD License
13
+ Classifier: Programming Language :: Python
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: Implementation :: CPython
16
+ Classifier: Programming Language :: Python :: Implementation :: PyPy
17
+ Classifier: Programming Language :: Python :: Implementation :: Jython
18
+ Classifier: Topic :: System :: Logging
19
+ Description-Content-Type: text/markdown; charset=UTF-8
20
+ License-File: LICENSE
21
+ Provides-Extra: test
22
+ Requires-Dist: pytest>=6.2.2; extra == "test"
23
+ Dynamic: author
24
+ Dynamic: author-email
25
+ Dynamic: classifier
26
+ Dynamic: description
27
+ Dynamic: home-page
28
+ Dynamic: keywords
29
+ Dynamic: license
30
+ Dynamic: summary
31
+
32
+ XMLLayout2 provides a Python logging Formatter that formats log messages as XML,
33
+ according to `log4j's [XMLLayout specification](https://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/xml/XMLLayout.html)
34
+
35
+ XMLLayout formatted log messages can be viewed and filtered within the
36
+ [Chainsaw](https://logging.apache.org/chainsaw/2.x) application
37
+ (see the example section below), part of the Java based log4j project.
38
+
39
+ This package also includes a RawSocketHandler -- like
40
+ logging.handler.SocketHandler, but sends the raw log message over the socket
41
+ instead of a pickled version. RawSocketHandler can be configured to send log
42
+ messages to Chainsaw directly over a socket.
43
+
44
+ For example: to forward log messages to Chainsaw, if it were listening on
45
+ localhost port 4448::
46
+
47
+ import logging
48
+ import xmllayout2
49
+
50
+ handler = xmllayout2.RawSocketHandler('localhost', 4448)
51
+ handler.setFormatter(xmllayout2.XMLLayout())
52
+ logging.root.addHandler(handler)
53
+
54
+ This is a fork of Philip Jenveys original package xmllayout. Maintained for usage in commercial projects, with supporting a variety of Python versions.
55
+
56
+ Installation via pip:
57
+ pip install xmllayout2
@@ -0,0 +1,26 @@
1
+ XMLLayout2 provides a Python logging Formatter that formats log messages as XML,
2
+ according to `log4j's [XMLLayout specification](https://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/xml/XMLLayout.html)
3
+
4
+ XMLLayout formatted log messages can be viewed and filtered within the
5
+ [Chainsaw](https://logging.apache.org/chainsaw/2.x) application
6
+ (see the example section below), part of the Java based log4j project.
7
+
8
+ This package also includes a RawSocketHandler -- like
9
+ logging.handler.SocketHandler, but sends the raw log message over the socket
10
+ instead of a pickled version. RawSocketHandler can be configured to send log
11
+ messages to Chainsaw directly over a socket.
12
+
13
+ For example: to forward log messages to Chainsaw, if it were listening on
14
+ localhost port 4448::
15
+
16
+ import logging
17
+ import xmllayout2
18
+
19
+ handler = xmllayout2.RawSocketHandler('localhost', 4448)
20
+ handler.setFormatter(xmllayout2.XMLLayout())
21
+ logging.root.addHandler(handler)
22
+
23
+ This is a fork of Philip Jenveys original package xmllayout. Maintained for usage in commercial projects, with supporting a variety of Python versions.
24
+
25
+ Installation via pip:
26
+ pip install xmllayout2
@@ -0,0 +1,3 @@
1
+ [build-system]
2
+ requires = ["setuptools", "setuptools-scm"]
3
+ build-backend = "setuptools.build_meta"
@@ -0,0 +1,29 @@
1
+ [metadata]
2
+ name = "xmllayout2"
3
+ description = "Formats Python log messages as log4j XMLLayout XML"
4
+ version = "2.0.0"
5
+ author = Jonas Lindner
6
+ author_email = "jonaslindner55@gmail.com"
7
+ keywords = ['logging', 'log4j']
8
+ license = BSD 2-clause
9
+ license_file = LICENSE
10
+ long_description_content_type = text/markdown; charset=UTF-8
11
+ classifiers =
12
+ 'Development Status :: 5 - Production/Stable',
13
+ 'Intended Audience :: Developers',
14
+ 'License :: OSI Approved :: BSD License',
15
+ 'Programming Language :: Python',
16
+ 'Programming Language :: Python :: 3',
17
+ 'Programming Language :: Python :: Implementation :: CPython',
18
+ 'Programming Language :: Python :: Implementation :: PyPy',
19
+ 'Programming Language :: Python :: Implementation :: Jython',
20
+ 'Topic :: System :: Logging'
21
+
22
+ [options.extras_require]
23
+ test =
24
+ pytest >= 6.2.2
25
+
26
+ [egg_info]
27
+ tag_build =
28
+ tag_date = 0
29
+
@@ -0,0 +1,43 @@
1
+ from os import path
2
+ from setuptools import setup, find_packages
3
+ import io
4
+
5
+ version = '2.0.0'
6
+
7
+ # Just here for Python2
8
+ # compatibility
9
+ # If not needed:
10
+ # import setuptools
11
+ # if __name__ == "__main__":
12
+ # setuptools.setup()
13
+
14
+ here = path.abspath(path.dirname(__file__))
15
+ with io.open(path.join(here, 'README.md')) as f:
16
+ long_description = f.read()
17
+
18
+ setup(
19
+ name='xmllayout2',
20
+ version=version,
21
+ description="Formats Python log messages as log4j XMLLayout XML",
22
+ long_description=long_description,
23
+ classifiers=[
24
+ 'Development Status :: 5 - Production/Stable',
25
+ 'Intended Audience :: Developers',
26
+ 'License :: OSI Approved :: BSD License',
27
+ 'Programming Language :: Python',
28
+ 'Programming Language :: Python :: 3',
29
+ 'Programming Language :: Python :: Implementation :: CPython',
30
+ 'Programming Language :: Python :: Implementation :: PyPy',
31
+ 'Programming Language :: Python :: Implementation :: Jython',
32
+ 'Topic :: System :: Logging'
33
+ ],
34
+ keywords='logging log4j',
35
+ author='Jonas Lindner',
36
+ author_email='jonaslindner55@gmail.com',
37
+ url='http://pypi.python.org/pypi/XMLLayout',
38
+ license='BSD',
39
+ packages=find_packages(),
40
+ include_package_data=True,
41
+ zip_safe=False,
42
+ tests_require=['pytest'],
43
+ )
File without changes
@@ -0,0 +1,96 @@
1
+ """logging Formatters"""
2
+ try:
3
+ from cgi import escape # < Python3.7
4
+ except ImportError:
5
+ from html import escape
6
+ import logging
7
+
8
+ __all__ = ['XMLLayout']
9
+
10
+ # Level names differ slightly in log4j, see
11
+ # http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/Level.html
12
+ LOG4J_LEVELS = dict(WARNING='WARN', CRITICAL='FATAL')
13
+
14
+
15
+ class XMLLayout(logging.Formatter):
16
+
17
+ """Formats log Records as XML according to the `log4j XMLLayout
18
+ <http://logging.apache.org/log4j/docs/api/org/apache/log4j/xml/
19
+ XMLLayout.html>_`
20
+ """
21
+
22
+ def format(self, record):
23
+ """Format the log record as XMLLayout XML"""
24
+ levelname = LOG4J_LEVELS.get(record.levelname, record.levelname)
25
+ event = dict(name=escape(record.name),
26
+ threadName=escape(record.threadName),
27
+ levelname=escape(levelname),
28
+ created=int(record.created * 1000))
29
+
30
+ event['message'] = LOG4J_MESSAGE % escape_cdata(record.getMessage())
31
+
32
+ # FIXME: Support an NDC somehow
33
+ event['ndc'] = ''
34
+ # ndc = self.get_ndc(record)
35
+ # if ndc:
36
+ # event['ndc'] = LOG4J_NDC % escape_cdata(ndc)
37
+
38
+ event['throwable'] = ''
39
+ if record.exc_info:
40
+ if not record.exc_text:
41
+ record.exc_text = self.formatException(record.exc_info)
42
+ event['throwable'] = (LOG4J_THROWABLE %
43
+ escape_cdata(record.exc_text))
44
+
45
+ location_info = dict(pathname=escape(record.pathname),
46
+ lineno=record.lineno,
47
+ module=escape(record.module), funcName='')
48
+ if hasattr(record, 'funcName'):
49
+ # >= Python 2.5
50
+ location_info['funcName'] = escape(record.funcName)
51
+ event['locationInfo'] = LOG4J_LOCATIONINFO % location_info
52
+
53
+ return LOG4J_EVENT % event
54
+
55
+
56
+ def escape_cdata(cdata):
57
+ """Escape XML CDATA content"""
58
+ return cdata.replace(']]>', ']]]]><![CDATA[>')
59
+
60
+
61
+ # General logging information
62
+ LOG4J_EVENT = """\
63
+ <log4j:event logger="%(name)s"
64
+ timestamp="%(created)i"
65
+ level="%(levelname)s"
66
+ thread="%(threadName)s">
67
+ %(message)s%(ndc)s%(throwable)s%(locationInfo)s</log4j:event>
68
+ """
69
+
70
+
71
+ # The actual log message
72
+ LOG4J_MESSAGE = """\
73
+ <log4j:message><![CDATA[%s]]></log4j:message>
74
+ """
75
+
76
+
77
+ # log4j's 'Nested Diagnostic Context': additional, customizable information
78
+ # included with the log record
79
+ LOG4J_NDC = """\
80
+ <log4j:ndc><![CDATA[%s]]></log4j:ndc>
81
+ """
82
+
83
+
84
+ # Exception information, if exc_info was included with the record
85
+ LOG4J_THROWABLE = """\
86
+ <log4j:throwable><![CDATA[%s]]></log4j:throwable>
87
+ """
88
+
89
+
90
+ # Traceback information
91
+ LOG4J_LOCATIONINFO = """\
92
+ <log4j:locationInfo class="%(module)s"
93
+ method="%(funcName)s"
94
+ file="%(pathname)s"
95
+ line="%(lineno)d"/>
96
+ """
@@ -0,0 +1,33 @@
1
+ """logging Handlers"""
2
+ import logging.handlers
3
+ import sys
4
+
5
+ __all__ = ['RawSocketHandler']
6
+
7
+ PY3 = sys.version_info >= (3,)
8
+
9
+
10
+ class RawSocketHandler(logging.handlers.SocketHandler):
11
+ """Logging Handler that writes log records to a streaming socket.
12
+
13
+ Like ``logging.handlers.SocketHandler``, but writes the actual formatted
14
+ log record (not a pickled version).
15
+ """
16
+
17
+ def emit(self, record):
18
+ """Emit a record.
19
+
20
+ Formats the record and writes it to the socket in binary format. If
21
+ there is an error with the socket, silently drop the packet. If there
22
+ was a problem with the socket, re-establishes the socket.
23
+ """
24
+ try:
25
+ msg = self.format(record)
26
+ if PY3:
27
+ self.send(msg.encode())
28
+ else:
29
+ self.send(msg.encode('utf-8'))
30
+ except (KeyboardInterrupt, SystemExit):
31
+ raise
32
+ except Exception:
33
+ self.handleError(record)
File without changes
@@ -0,0 +1,119 @@
1
+ import logging
2
+ import sys
3
+ try:
4
+ from six import StringIO # < Python3.10
5
+ except ImportError:
6
+ from io import StringIO
7
+ try:
8
+ import xml.etree.ElementTree as ET
9
+ except ImportError:
10
+ import elementtree.ElementTree as ET
11
+
12
+ from xmllayout2 import XMLLayout
13
+
14
+ PY3 = sys.version_info >= (3,)
15
+
16
+ LOG4J_NS = 'http://jakarta.apache.org/log4j/'
17
+
18
+ log = logging.getLogger(__name__)
19
+ stream = StringIO()
20
+ handler = logging.StreamHandler(stream)
21
+ xmllayout = XMLLayout()
22
+ handler.setFormatter(xmllayout)
23
+ log.addHandler(handler)
24
+ log.setLevel(logging.DEBUG)
25
+
26
+
27
+ class ElvisException(Exception):
28
+ def __init__(self, info):
29
+ self.info = info
30
+
31
+ def __str__(self):
32
+ return "<ElvisException: %s (TCB because he's the king baby)>" % \
33
+ self.info
34
+
35
+
36
+ def test_xmllayout():
37
+ _test_output('')
38
+ _test_output('hello')
39
+ _test_output('hello world', level=logging.DEBUG)
40
+ _test_output('hello world!', level=logging.WARN, log4jlevel='WARN')
41
+ _test_output('hello, world!', level=logging.WARNING, log4jlevel='WARN')
42
+ _test_output('hello, world!!', level=logging.CRITICAL, log4jlevel='FATAL')
43
+ _test_output('<xml><something>&nbsp;Hi</something></xml>')
44
+ _test_output("""\
45
+ {'CONTENT_LENGTH': '0',
46
+ 'CONTENT_TYPE': '',
47
+ 'HTTP_ACCEPT': '*/*',
48
+ 'HTTP_ACCEPT_ENCODING': 'gzip, deflate',
49
+ 'HTTP_ACCEPT_LANGUAGE': 'en',
50
+ 'HTTP_CONNECTION': 'keep-alive',
51
+ 'HTTP_COOKIE': ''
52
+ 'HTTP_HOST': 'bob.local:5000',
53
+ 'HTTP_USER_AGENT': 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en) AppleWebKit/419.2.1 (KHTML, like Gecko) Safari/419.3',
54
+ 'PATH_INFO': '/hello',
55
+ 'QUERY_STRING': '',
56
+ 'REMOTE_ADDR': '192.168.1.111',
57
+ 'REQUEST_METHOD': 'GET',
58
+ 'SCRIPT_NAME': '',
59
+ 'SERVER_NAME': '0.0.0.0',
60
+ 'SERVER_PORT': '5000',
61
+ 'SERVER_PROTOCOL': 'HTTP/1.1',
62
+ 'paste.evalexception': <pylons.error.PylonsEvalException object at 0x8c75ccc>,
63
+ 'wsgi.errors': <open file '<stderr>', mode 'w' at 0x81280b0>,
64
+ 'wsgi.input': <socket._fileobject object at 0x8c7a48c length=0>,
65
+ 'wsgi.multiprocess': False,
66
+ 'wsgi.multithread': True,
67
+ 'wsgi.run_once': False,
68
+ 'wsgi.url_scheme': 'http',
69
+ 'wsgi.version': (1, 0),}
70
+ """) # noqa
71
+
72
+
73
+ def test_exceptions():
74
+ try:
75
+ raise ElvisException('dog')
76
+ except ElvisException:
77
+ exc_module = ''
78
+ if PY3:
79
+ exc_module = ElvisException.__module__ + '.'
80
+ exc_msg = ("raise ElvisException('dog')\n%sElvisException: "
81
+ "<ElvisException: dog (TCB because he's the king baby)>" %
82
+ exc_module)
83
+ _test_output('Elvis has left the building', exc_info=True,
84
+ exc_msg=exc_msg)
85
+
86
+
87
+ def test_exceptions_cdata():
88
+ exc_msg = 'Hello ]]> World!'
89
+ try:
90
+ raise ElvisException(exc_msg)
91
+ except ElvisException:
92
+ _test_output('Elvis has left the building', exc_info=True,
93
+ exc_msg=exc_msg)
94
+
95
+
96
+ def get_output():
97
+ output = stream.getvalue().rstrip()
98
+ stream.truncate(0)
99
+ return '<test xmlns:log4j="%s">%s</test>' % (LOG4J_NS, output)
100
+
101
+
102
+ def _test_output(message, level=logging.INFO, log4jlevel=None, exc_info=None,
103
+ exc_msg=None):
104
+ if log4jlevel is None:
105
+ log4jlevel = logging.getLevelName(level)
106
+ log.log(level, message, **dict(exc_info=exc_info))
107
+ output = get_output()
108
+ tree = ET.XML(output)
109
+
110
+ event = tree.find("{%s}event" % LOG4J_NS)
111
+ xml_level = event.get('level')
112
+ assert xml_level == log4jlevel, message
113
+ xml_message = tree.findtext("{%s}event/{%s}message" % (LOG4J_NS, LOG4J_NS))
114
+ assert message == xml_message, message
115
+
116
+ if exc_info:
117
+ xml_exc = tree.findtext("{%s}event/{%s}throwable" % (LOG4J_NS,
118
+ LOG4J_NS))
119
+ assert exc_msg in xml_exc, message
@@ -0,0 +1,57 @@
1
+ Metadata-Version: 2.2
2
+ Name: xmllayout2
3
+ Version: 2.0.0
4
+ Summary: Formats Python log messages as log4j XMLLayout XML
5
+ Home-page: http://pypi.python.org/pypi/XMLLayout
6
+ Author: Jonas Lindner
7
+ Author-email: jonaslindner55@gmail.com
8
+ License: BSD
9
+ Keywords: logging log4j
10
+ Classifier: Development Status :: 5 - Production/Stable
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: License :: OSI Approved :: BSD License
13
+ Classifier: Programming Language :: Python
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: Implementation :: CPython
16
+ Classifier: Programming Language :: Python :: Implementation :: PyPy
17
+ Classifier: Programming Language :: Python :: Implementation :: Jython
18
+ Classifier: Topic :: System :: Logging
19
+ Description-Content-Type: text/markdown; charset=UTF-8
20
+ License-File: LICENSE
21
+ Provides-Extra: test
22
+ Requires-Dist: pytest>=6.2.2; extra == "test"
23
+ Dynamic: author
24
+ Dynamic: author-email
25
+ Dynamic: classifier
26
+ Dynamic: description
27
+ Dynamic: home-page
28
+ Dynamic: keywords
29
+ Dynamic: license
30
+ Dynamic: summary
31
+
32
+ XMLLayout2 provides a Python logging Formatter that formats log messages as XML,
33
+ according to `log4j's [XMLLayout specification](https://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/xml/XMLLayout.html)
34
+
35
+ XMLLayout formatted log messages can be viewed and filtered within the
36
+ [Chainsaw](https://logging.apache.org/chainsaw/2.x) application
37
+ (see the example section below), part of the Java based log4j project.
38
+
39
+ This package also includes a RawSocketHandler -- like
40
+ logging.handler.SocketHandler, but sends the raw log message over the socket
41
+ instead of a pickled version. RawSocketHandler can be configured to send log
42
+ messages to Chainsaw directly over a socket.
43
+
44
+ For example: to forward log messages to Chainsaw, if it were listening on
45
+ localhost port 4448::
46
+
47
+ import logging
48
+ import xmllayout2
49
+
50
+ handler = xmllayout2.RawSocketHandler('localhost', 4448)
51
+ handler.setFormatter(xmllayout2.XMLLayout())
52
+ logging.root.addHandler(handler)
53
+
54
+ This is a fork of Philip Jenveys original package xmllayout. Maintained for usage in commercial projects, with supporting a variety of Python versions.
55
+
56
+ Installation via pip:
57
+ pip install xmllayout2
@@ -0,0 +1,18 @@
1
+ .gitattributes
2
+ .gitignore
3
+ LICENSE
4
+ README.md
5
+ pyproject.toml
6
+ setup.cfg
7
+ setup.py
8
+ xmllayout2/__init__.py
9
+ xmllayout2/formatters.py
10
+ xmllayout2/handlers.py
11
+ xmllayout2.egg-info/PKG-INFO
12
+ xmllayout2.egg-info/SOURCES.txt
13
+ xmllayout2.egg-info/dependency_links.txt
14
+ xmllayout2.egg-info/not-zip-safe
15
+ xmllayout2.egg-info/requires.txt
16
+ xmllayout2.egg-info/top_level.txt
17
+ xmllayout2/tests/__init__.py
18
+ xmllayout2/tests/test_formatters.py
@@ -0,0 +1,3 @@
1
+
2
+ [test]
3
+ pytest>=6.2.2
@@ -0,0 +1 @@
1
+ xmllayout2