summaryrefslogtreecommitdiff
path: root/cloudinit
diff options
context:
space:
mode:
authorJoshua Harlow <harlowja@yahoo-inc.com>2012-09-19 21:19:43 -0400
committerScott Moser <smoser@ubuntu.com>2012-09-19 21:19:43 -0400
commit94b9647e4df742982cac8a2c2925fb4894281dbf (patch)
treea10d98b98272020401c06d8cbc4be9b0bd256f8e /cloudinit
parent3912209cdb075b7af8f87c1e41170fd8614ca520 (diff)
parent5eef154928c75499c545c8c242bcf11d9ccf70d1 (diff)
downloadvyos-cloud-init-94b9647e4df742982cac8a2c2925fb4894281dbf.tar.gz
vyos-cloud-init-94b9647e4df742982cac8a2c2925fb4894281dbf.zip
if a logged message fails, fallback to logging to stdout
This most commonly occurs if a user-data script does '/sbin/poweroff' where syslog was being used. Once poweroff is invoked, syslog gets killed and logging would start to show stack traces. This generally tries to continue working instead, but log to stderr.
Diffstat (limited to 'cloudinit')
-rw-r--r--cloudinit/patcher.py56
1 files changed, 56 insertions, 0 deletions
diff --git a/cloudinit/patcher.py b/cloudinit/patcher.py
new file mode 100644
index 00000000..8921a79a
--- /dev/null
+++ b/cloudinit/patcher.py
@@ -0,0 +1,56 @@
+# vi: ts=4 expandtab
+#
+# Copyright (C) 2012 Canonical Ltd.
+# Copyright (C) 2012 Yahoo! Inc.
+#
+# Author: Scott Moser <scott.moser@canonical.com>
+# Author: Joshua Harlow <harlowja@yahoo-inc.com>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 3, as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+import imp
+import logging
+import sys
+
+# Default fallback format
+FALL_FORMAT = 'FALLBACK: %(asctime)s - %(filename)s[%(levelname)s]: %(message)s'
+
+
+class QuietStreamHandler(logging.StreamHandler):
+ def handleError(self, record):
+ pass
+
+
+def _patch_logging():
+ # Replace 'handleError' with one that will be more
+ # tolerant of errors in that it can avoid
+ # re-notifying on exceptions and when errors
+ # do occur, it can at least try to write to
+ # sys.stderr using a fallback logger
+ fallback_handler = QuietStreamHandler(sys.stderr)
+ fallback_handler.setFormatter(logging.Formatter(FALL_FORMAT))
+ def handleError(self, record):
+ try:
+ fallback_handler.handle(record)
+ fallback_handler.flush()
+ except IOError:
+ pass
+ setattr(logging.Handler, 'handleError', handleError)
+
+
+def patch():
+ imp.acquire_lock()
+ try:
+ _patch_logging()
+ finally:
+ imp.release_lock()