diff --git a/src/supervisor/datatypes.py b/src/supervisor/datatypes.py
index c2a3753..0c1b677 100644
--- a/src/supervisor/datatypes.py
+++ b/src/supervisor/datatypes.py
@@ -354,6 +354,9 @@ def existing_directory(v):
     raise ValueError('%s is not an existing directory' % v)
 
 def existing_dirpath(v):
+    if v.find('://') != -1:
+        return v
+
     import os
     nv = v % {'here':here}
     nv = os.path.expanduser(nv)
diff --git a/src/supervisor/loggers.py b/src/supervisor/loggers.py
index 7042a7e..e85208b 100644
--- a/src/supervisor/loggers.py
+++ b/src/supervisor/loggers.py
@@ -27,6 +27,15 @@ import sys
 import time
 import traceback
 
+try:
+    import re
+    from scribe import scribe
+    from thrift.transport import TTransport, TSocket
+    from thrift.protocol import TBinaryProtocol
+    scribe_imported = True
+except ImportError:
+    scribe_imported = False
+
 class LevelsByName:
     CRIT = 50   # messages that probably require immediate user attention
     ERRO = 40   # messages that indicate a potentially ignorable error condition
@@ -118,6 +127,86 @@ class FileHandler(Handler):
             if why[0] != errno.ENOENT:
                 raise
 
+class ScribeHandler(Handler):
+    def __init__(self, filename):
+        self.filename = filename
+
+        if not scribe_imported:
+            raise ImportError('scribe could not be imported. scribe support is disabled')
+
+        p = re.match('(?P<scheme>[a-z]+)://(?P<netloc>.*)/(?P<category>.*)$', filename)
+        if not p:
+            raise ValueError('%s is not a valid scribe URI')
+        else:
+            p = p.groupdict()
+
+        if p['netloc'].find(':') != -1:
+            self.host, self.port = p['netloc'].rsplit(':', 1)
+            self.port = int(self.port)
+        else:
+            self.host = p['netloc']
+            self.port = 1463
+        self.category = p['category']
+
+        self.buffer = []
+        self.reconnect_count = 0
+
+        self.open()
+
+    def open(self):
+        try:
+            self.socket = TSocket.TSocket(host=self.host, port=self.port)
+            self.transport = TTransport.TFramedTransport(self.socket)
+            self.protocol = TBinaryProtocol.TBinaryProtocol(trans=self.transport, strictRead=False, strictWrite=False)
+            self.client = scribe.Client(iprot=self.protocol, oprot=self.protocol)
+
+            self.transport.open()
+        except:
+            sys.stderr.write('ScribeHandler("%s").open(): %s\n' % (self.filename, sys.exc_info()[1]))
+            sys.stderr.flush()
+
+    def flush(self):
+        try:
+            result = self.client.Log(messages=self.buffer)
+        except:
+            sys.stderr.write('ScribeHandler("%s").flush(): %s\n' % (self.filename, sys.exc_info()[1]))
+            sys.stderr.flush()
+            if self.reconnect_count > 5:
+                sys.stderr.write('ScribeHandler("%s").flush(): Too many reconnects! Sleeping for 30 seconds before retrying\n' % self.filename)
+                time.sleep(30)
+                self.reconnect_count = 0
+            self.reconnect()
+            return
+
+        if result == scribe.ResultCode.OK:
+            self.buffer = []
+            return
+
+        if result == scribe.ResultCode.TRY_LATER:
+            return
+
+        self.handleError('Unknown error code from scribe: %s' % repr(result))
+
+    def close(self):
+        if self.buffer:
+            self.handleError('Warning: Closing scribe transport with %i messages in send buffer!' % len(self.buffer))
+
+        self.transport.close()
+
+    def reconnect(self):
+        try:
+            self.close()
+            self.open()
+        except:
+            sys.stderr.write('ScribeHandler("%s").reconnect(): %s\n' % (self.filename, sys.exc_info()[1]))
+            sys.stderr.flush()
+
+    def emit(self, record):
+        msg = self.fmt % record.asdict()
+        msg = scribe.LogEntry(category=self.category, message=msg)
+        self.buffer.append(msg)
+        self.flush()
+
 class StreamHandler(Handler):
     def __init__(self, strm=None):
         self.stream = strm
@@ -319,10 +408,13 @@ def getLogger(filename, level, fmt, rotating=False, maxbytes=0, backups=0,
         logger.getvalue = io.getvalue
 
     else:
-        if rotating is False:
-            handlers.append(FileHandler(filename))
+        if filename.startswith('scribe://'):
+            handlers.append(ScribeHandler(filename))
         else:
-            handlers.append(RotatingFileHandler(filename,'a',maxbytes,backups))
+            if rotating is False:
+                handlers.append(FileHandler(filename))
+            else:
+                handlers.append(RotatingFileHandler(filename,'a',maxbytes,backups))
 
     if stdout:
         handlers.append(StreamHandler(sys.stdout))
