summary refs log tree commit diff
diff options
context:
space:
mode:
authorRichard van der Hoff <richard@matrix.org>2017-10-09 17:44:42 +0100
committerRichard van der Hoff <richard@matrix.org>2017-10-09 17:44:42 +0100
commit3cc852d339ad1cdcb0a435c76b44182bdb81dfe9 (patch)
treeceee2a0b620236f61e78818b4e4a9960cb0c91e4
parentMerge pull request #2508 from matrix-org/rav/federation_queue_logcontexts (diff)
downloadsynapse-3cc852d339ad1cdcb0a435c76b44182bdb81dfe9.tar.xz
Fancy logformatter to format exceptions better
This is a bit of an experimental change at this point; the idea is to see if it
helps us track down where our stack overflows are coming from by logging the
stack when the exception was caught and turned into a Failure. (We'll also need
https://github.com/richvdh/twisted/commit/edf27044200e74680ea67c525768e36dc9d9af2b).

If we deploy this, we'll be able to enable it via the log config yaml.
-rw-r--r--synapse/util/logformatter.py43
1 files changed, 43 insertions, 0 deletions
diff --git a/synapse/util/logformatter.py b/synapse/util/logformatter.py
new file mode 100644
index 0000000000..60504162e9
--- /dev/null
+++ b/synapse/util/logformatter.py
@@ -0,0 +1,43 @@
+# -*- coding: utf-8 -*-
+# Copyright 2017 New Vector Ltd
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+import StringIO
+import logging
+import traceback
+
+
+class LogFormatter(logging.Formatter):
+    """Log formatter which gives more detail for exceptions
+
+    This is the same as the standard log formatter, except that when logging
+    exceptions [typically via log.foo("msg", exc_info=1)], it prints the
+    sequence that led up to the point at which the exception was caught.
+    (Normally only stack frames between the point the exception was raised and
+    where it was caught are logged).
+    """
+    def __init__(self, *args, **kwargs):
+        super(LogFormatter, self).__init__(*args, **kwargs)
+
+    def formatException(self, ei):
+        sio = StringIO.StringIO()
+        sio.write("Capture point (most recent call last):\n")
+        traceback.print_stack(ei[2].tb_frame.f_back, None, sio)
+        traceback.print_exception(ei[0], ei[1], ei[2], None, sio)
+        s = sio.getvalue()
+        sio.close()
+        if s[-1:] == "\n":
+            s = s[:-1]
+        return s