예제 #1
0
    def _start_worker_thread(self):
        if self._worker_thread_is_running():
            return

        self._worker_thread = LogProcessingWorker(
            host=self._host,
            port=self._port,
            transport=self._transport,
            ssl_enable=self._ssl_enable,
            cache={},
            event_ttl=self._event_ttl)
        self._worker_thread.start()
예제 #2
0
    def _start_worker_thread(self):
        if self._worker_thread_is_running():
            return

        self._worker_thread = LogProcessingWorker(
            host=self._host,
            port=self._port,
            transport=self._transport,
            ssl_enable=self._ssl_enable,
            ssl_verify=self._ssl_verify,
            keyfile=self._keyfile,
            certfile=self._certfile,
            ca_certs=self._ca_certs,
            database_path=self._database_path,
            cache=logstash_async.EVENT_CACHE,
            event_ttl=self._event_ttl)
        self._worker_thread.start()
예제 #3
0
    def _start_worker_thread(self):
        if self._worker_thread_is_running():
            return

        AsynchronousLogstashHandler._worker_thread = LogProcessingWorker(
            host=self._host,
            port=self._port,
            transport=self._transport,
            ssl_enable=self._ssl_enable,
            ssl_verify=self._ssl_verify,
            keyfile=self._keyfile,
            certfile=self._certfile,
            ca_certs=self._ca_certs)
        AsynchronousLogstashHandler._worker_thread.start()
예제 #4
0
class AsynchronousLogstashHandler(Handler):
    """Python logging handler for Logstash. Sends events over TCP by default.
    :param host: The host of the logstash server, required.
    :param port: The port of the logstash server, required.
    :param database_path: The path to the file containing queued events, required.
                          Use None to use a in-memory cache.
    :param transport: Callable or path to a compatible transport class.
    :param ssl_enable: Should SSL be enabled for the connection? Default is False.
    :param ssl_verify: Should the server's SSL certificate be verified?
    :param keyfile: The path to client side SSL key file (default is None).
    :param certfile: The path to client side SSL certificate file (default is None).
    :param ca_certs: The path to the file containing recognized CA certificates.
    :param enable: Flag to enable log processing (default is True, disabling
                   might be handy for local testing, etc.)
    :param event_ttl: Amount of time in seconds to wait before expiring log messages in
                      the database. (Given in seconds. Default is None, and disables this feature)
    """

    # ----------------------------------------------------------------------
    def __init__(self,
                 host,
                 port,
                 database_path,
                 transport='logstash_async.transport.TcpTransport',
                 ssl_enable=False,
                 ssl_verify=True,
                 keyfile=None,
                 certfile=None,
                 ca_certs=None,
                 enable=True,
                 event_ttl=None,
                 encoding='utf-8'):
        super(AsynchronousLogstashHandler, self).__init__()
        self._host = host
        self._port = port
        self._database_path = database_path
        self._transport_path = transport
        self._ssl_enable = ssl_enable
        self._ssl_verify = ssl_verify
        self._keyfile = keyfile
        self._certfile = certfile
        self._ca_certs = ca_certs
        self._enable = enable
        self._transport = None
        self._event_ttl = event_ttl
        self._encoding = encoding
        self._setup_transport()
        self._worker_thread = None

    # ----------------------------------------------------------------------
    def emit(self, record):
        if not self._enable:
            return  # we should not do anything, so just leave

        self._setup_transport()
        self._start_worker_thread()

        # basically same implementation as in logging.handlers.SocketHandler.emit()
        try:
            data = self._format_record(record)
            self._worker_thread.enqueue_event(data)
        except (KeyboardInterrupt, SystemExit):
            raise
        except Exception:
            self.handleError(record)

    # ----------------------------------------------------------------------
    def flush(self):
        if self._worker_thread_is_running():
            self._worker_thread.force_flush_queued_events()

    # ----------------------------------------------------------------------
    def _setup_transport(self):
        if self._transport is not None:
            return

        transport_args = dict(host=self._host,
                              port=self._port,
                              timeout=constants.SOCKET_TIMEOUT,
                              ssl_enable=self._ssl_enable,
                              ssl_verify=self._ssl_verify,
                              keyfile=self._keyfile,
                              certfile=self._certfile,
                              ca_certs=self._ca_certs)
        if isinstance(self._transport_path, string_types):
            transport_class = import_string(self._transport_path)
            self._transport = transport_class(**transport_args)
        elif callable(self._transport_path):
            self._transport = self._transport_path(**transport_args)
        elif hasattr(self._transport_path, 'send'):
            self._transport = self._transport_path
        else:
            raise RuntimeError(
                'Invalid transport path: must be an importable module path, '
                'a class or factory function or an instance.')

    # ----------------------------------------------------------------------
    def _start_worker_thread(self):
        if self._worker_thread_is_running():
            return

        self._worker_thread = LogProcessingWorker(
            host=self._host,
            port=self._port,
            transport=self._transport,
            ssl_enable=self._ssl_enable,
            ssl_verify=self._ssl_verify,
            keyfile=self._keyfile,
            certfile=self._certfile,
            ca_certs=self._ca_certs,
            database_path=self._database_path,
            cache=logstash_async.EVENT_CACHE,
            event_ttl=self._event_ttl)
        self._worker_thread.start()

    # ----------------------------------------------------------------------
    def _worker_thread_is_running(self):
        return self._worker_thread is not None and self._worker_thread.is_alive(
        )

    # ----------------------------------------------------------------------
    def _format_record(self, record):
        self._create_formatter_if_necessary()
        formatted = self.formatter.format(record)
        if isinstance(formatted, text_type):
            formatted = formatted.encode(self._encoding)
        return formatted + b'\n'

    # ----------------------------------------------------------------------
    def _create_formatter_if_necessary(self):
        if self.formatter is None:
            self.formatter = LogstashFormatter()

    # ----------------------------------------------------------------------
    def close(self):
        self.acquire()
        try:
            self.shutdown()
        finally:
            self.release()
        super(AsynchronousLogstashHandler, self).close()

    # ----------------------------------------------------------------------
    def shutdown(self):
        if self._worker_thread_is_running():
            self._trigger_worker_shutdown()
            self._wait_for_worker_thread()
            self._reset_worker_thread()
            self._close_transport()
        else:
            pass

    # ----------------------------------------------------------------------
    def _trigger_worker_shutdown(self):
        self._worker_thread.shutdown()

    # ----------------------------------------------------------------------
    def _wait_for_worker_thread(self):
        self._worker_thread.join()

    # ----------------------------------------------------------------------
    def _reset_worker_thread(self):
        self._worker_thread = None

    # ----------------------------------------------------------------------
    def _close_transport(self):
        try:
            if self._transport is not None:
                self._transport.close()
        except Exception as e:
            safe_log_via_print('error',
                               u'Error on closing transport: {}'.format(e))
예제 #5
0
class AsynchronousLogstashHandler(Handler):
    """Python logging handler for Logstash. Sends events over TCP by default.
    :param host: The host of the logstash server, required.
    :param port: The port of the logstash server, required.
    :param transport: Callable or path to a compatible transport class.
    :param enable: Flag to enable log processing (default is True, disabling
                   might be handy for local testing, etc.)
    :param event_ttl: Amount of time in seconds to wait before expiring log messages in
                      the database. (Given in seconds. Default is None, and disables this feature)
    """

    # ----------------------------------------------------------------------
    # pylint: disable=too-many-arguments
    def __init__(self, host, port,
                 ssl_enable=True,
                 enable=True, event_ttl=None, transport=None, encoding='utf-8', **kwargs):
        super().__init__()
        self._host = host
        self._port = port
        self._ssl_enable = ssl_enable
        self._enable = enable
        self._transport = transport
        self._event_ttl = event_ttl
        self._encoding = encoding
        self._worker_thread = None
        self._setup_transport(**kwargs)

    # ----------------------------------------------------------------------
    def emit(self, record):
        if not self._enable:
            return  # we should not do anything, so just leave

        self._setup_transport()
        self._start_worker_thread()

        try:
            data = self._format_record(record)
            self._worker_thread.enqueue_event(data)
        except Exception:
            self.handleError(record)

    # ----------------------------------------------------------------------
    def flush(self):
        if self._worker_thread_is_running():
            self._worker_thread.force_flush_queued_events()

    # ----------------------------------------------------------------------
    def _setup_transport(self, **kwargs):
        if self._transport is not None:
            return
        self._transport = HttpTransport(host=self._host,
            port=self._port,
            timeout=constants.SOCKET_TIMEOUT,
            ssl_enable=self._ssl_enable,
            **kwargs)

    # ----------------------------------------------------------------------
    def _start_worker_thread(self):
        if self._worker_thread_is_running():
            return

        self._worker_thread = LogProcessingWorker(
            host=self._host,
            port=self._port,
            transport=self._transport,
            ssl_enable=self._ssl_enable,
            cache={},
            event_ttl=self._event_ttl)
        self._worker_thread.start()

    # ----------------------------------------------------------------------
    def _worker_thread_is_running(self):
        return self._worker_thread is not None and self._worker_thread.is_alive()

    # ----------------------------------------------------------------------
    def _format_record(self, record):
        self._create_formatter_if_necessary()
        formatted = self.formatter.format(record)
        if isinstance(formatted, str):
            formatted = formatted.encode(self._encoding)  # pylint: disable=redefined-variable-type
        return formatted + b'\n'

    # ----------------------------------------------------------------------
    def _create_formatter_if_necessary(self):
        if self.formatter is None:
            self.formatter = LogstashFormatter()

    # ----------------------------------------------------------------------
    def close(self):
        self.acquire()
        try:
            self.shutdown()
        finally:
            self.release()
        super().close()

    # ----------------------------------------------------------------------
    def shutdown(self):
        if self._worker_thread_is_running():
            self._trigger_worker_shutdown()
            self._wait_for_worker_thread()
            self._reset_worker_thread()
            self._close_transport()
        else:
            pass

    # ----------------------------------------------------------------------
    def _trigger_worker_shutdown(self):
        self._worker_thread.shutdown()

    # ----------------------------------------------------------------------
    def _wait_for_worker_thread(self):
        self._worker_thread.join()

    # ----------------------------------------------------------------------
    def _reset_worker_thread(self):
        self._worker_thread = None

    # ----------------------------------------------------------------------
    def _close_transport(self):
        try:
            if self._transport is not None:
                self._transport.close()
        except Exception as exc:
            safe_log_via_print('error', u'Error on closing transport: {}'.format(exc))