import uwsgi
import uwsgidecorators
import logging
import clog
import clog.global_state
import clog.handlers
import six.moves.cPickle as pickle


def _mule_msg(*args, **kwargs):
    mule = kwargs.pop('mule', 1)
    data = pickle.dumps({
        'service': 'uwsgi_mulefunc',
        'func': 'log_line',
        'args': args,
        'kwargs': kwargs,
    })
    uwsgi.mule_msg(data, mule)


class UwsgiHandler(logging.Handler):

    def __init__(self, stream, mule=1):
        logging.Handler.__init__(self)
        self.stream = stream
        self.mule = mule

    def emit(self, record):
        try:
            msg = self.format(record)
            _mule_msg(self.stream, msg, mule=self.mule)
        except Exception:
            raise
        except:
            self.handleError(record)


# TODO: Patch upstream uwsgi to return success on the pipe write so
# we can optionally default to sync log_line
def uwsgi_log_line(stream, line, mule=1):
    _mule_msg(stream, line, mule=mule)


def uwsgi_patch_global_state():
    map(
        lambda x: setattr(x, 'log_line', uwsgi_log_line),
        (clog, clog.global_state)
    )


# Couple setup tasks at import:
# 1. Register 'log_line' in all mules for dispatch handling on the mule side
# 2. Insert 'UwsgiHandler' into the clog.handlers module for seamless usage

uwsgidecorators.mule_functions['log_line'] = clog.global_state.log_line
setattr(clog.handlers, 'UwsgiHandler', UwsgiHandler)

@@ -354,16 +354,195 @@
  %7D)%0A    
+# Unfortunately this check has to come after the pickling%0A    # unless we just want to make a conservative guess%0A    if len(data) %3E max_recv_size:%0A        return False%0A    return 
 uwsgi.mu
@@ -972,139 +972,219 @@
 )%0A%0A%0A
-# TODO: Patch upstream uwsgi to return success on the pipe write so%0A# we can optionally default to sync log_line%0Adef
+def uwsgi_log_line(stream, line, mule=1):%0A    # Explicit 'False' check - see https://github.com/unbit/uwsgi/pull/1482%0A    # We don't want to double-emit on 'None' response if we have older
  uwsgi
-_log_line
+%0A    if _mule_msg
 (str
@@ -1203,25 +1203,46 @@
 ule=
-1):%0A    _mule_msg
+mule) == False:%0A        _orig_log_line
 (str
@@ -1250,27 +1250,16 @@
 am, line
-, mule=mule
 )%0A%0A%0Adef 
@@ -1584,130 +1584,417 @@
 age%0A
-%0Auwsgidecorators.mule_functions%5B'log_line'%5D = clog.global_state.log_line%0Asetattr(clog.handlers, 'UwsgiHandler', UwsgiHandler
+# 3. Store reference to the original global_state.log_line for fallback%0A# 4. Fetch mule_msg_recv_size to calculate send limit%0A%0Auwsgidecorators.mule_functions%5B'log_line'%5D = clog.global_state.log_line%0Asetattr(clog.handlers, 'UwsgiHandler', UwsgiHandler)%0A_orig_log_line = clog.global_state.log_line%0A# See https://github.com/unbit/uwsgi/pull/1487%0Amax_recv_size = getattr(uwsgi, 'mule_msg_recv_size', lambda: 65536)(
 )%0A

Add default fallback behavior