Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge pull request #56 from SciLifeLab/master

Added ack to the RabbitMQ handling
  • Loading branch information...
commit 4ac23efd44fffedf5f9fdc652b0a678a5dbe7959 2 parents d5aab55 + 4d200ca
@percyfal percyfal authored
View
2  logbook/base.py
@@ -848,7 +848,7 @@ class LoggerGroup(object):
def __init__(self, loggers=None, level=NOTSET, processor=None):
#: a list of all loggers on the logger group. Use the
#: :meth:`add_logger` and :meth:`remove_logger` methods to add
- #: or remove loggers from this list.
+ #: or remove loggers from this list.
self.loggers = []
if loggers is not None:
for logger in loggers:
View
25 logbook/more.py
@@ -19,6 +19,8 @@
from logbook._termcolors import colorize
from logbook.helpers import F
+from logbook.ticketing import TicketingHandler as DatabaseHandler
+from logbook.ticketing import BackendBase
_ws_re = re.compile(r'(\s+)(?u)')
TWITTER_FORMAT_STRING = \
@@ -27,6 +29,29 @@
NEW_TWEET_URL = 'https://api.twitter.com/1/statuses/update.json'
+class CouchDBBackend(BackendBase):
+ """Implements a backend that writes into a CouchDB database.
+ """
+ def setup_backend(self):
+ from couchdb import Server
+
+ uri = self.options.pop('uri', u'')
+ couch = Server(uri)
+ db_name = self.options.pop('db')
+ self.database = couch[db_name]
+
+ def record_ticket(self, record, data, hash, app_id):
+ """Records a log record as ticket.
+ """
+ db = self.database
+
+ ticket = record.to_dict()
+ ticket["time"] = ticket["time"].isoformat() + "Z"
+ ticket_id, _ = db.save(ticket)
+
+ db.save(ticket)
+
+
class TwitterFormatter(StringFormatter):
"""Works like the standard string formatter and is used by the
:class:`TwitterHandler` unless changed.
View
109 logbook/queues.py
@@ -15,6 +15,43 @@
from logbook.helpers import json
+class RabbitMQHandler(Handler):
+ """A handler that acts as a RabbitMQ publisher, which publishes each record
+ as json dump. Requires the kombu module.
+
+ The queue will be filled with JSON exported log records. To receive such
+ log records from a queue you can use the :class:`RabbitMQSubscriber`.
+
+
+ Example setup::
+
+ handler = RabbitMQHandler('amqp://guest:guest@localhost//', queue='my_log')
+ """
+ def __init__(self, uri=None, queue='logging', level=NOTSET,
+ filter=None, bubble=False, context=None):
+ Handler.__init__(self, level, filter, bubble)
+ try:
+ import kombu
+ except ImportError:
+ raise RuntimeError('The kombu library is required for '
+ 'the RabbitMQSubscriber.')
+ if uri:
+ connection = kombu.Connection(uri)
+
+ self.queue = connection.SimpleQueue(queue)
+
+ def export_record(self, record):
+ """Exports the record into a dictionary ready for JSON dumping.
+ """
+ return record.to_dict(json_safe=True)
+
+ def emit(self, record):
+ self.queue.put(self.export_record(record))
+
+ def close(self):
+ self.queue.close()
+
+
class ZeroMQHandler(Handler):
"""A handler that acts as a ZeroMQ publisher, which publishes each record
as json dump. Requires the pyzmq library.
@@ -133,6 +170,75 @@ def dispatch_in_background(self, setup=None):
return controller
+class RabbitMQSubscriber(SubscriberBase):
+ """A helper that acts as RabbitMQ subscriber and will dispatch received
+ log records to the active handler setup. There are multiple ways to
+ use this class.
+
+ It can be used to receive log records from a queue::
+
+ subscriber = RabbitMQSubscriber('amqp://guest:guest@localhost//')
+ record = subscriber.recv()
+
+ But it can also be used to receive and dispatch these in one go::
+
+ with target_handler:
+ subscriber = RabbitMQSubscriber('amqp://guest:guest@localhost//')
+ subscriber.dispatch_forever()
+
+ This will take all the log records from that queue and dispatch them
+ over to `target_handler`. If you want you can also do that in the
+ background::
+
+ subscriber = RabbitMQSubscriber('amqp://guest:guest@localhost//')
+ controller = subscriber.dispatch_in_background(target_handler)
+
+ The controller returned can be used to shut down the background
+ thread::
+
+ controller.stop()
+ """
+
+ def __init__(self, uri=None, queue='logging'):
+ try:
+ import kombu
+ except ImportError:
+ raise RuntimeError('The kombu library is required for '
+ 'the RabbitMQSubscriber.')
+ if uri:
+ connection = kombu.Connection(uri)
+
+ self.queue = connection.SimpleQueue(queue)
+
+ def __del__(self):
+ try:
+ self.close()
+ except AttributeError:
+ # subscriber partially created
+ pass
+
+ def close(self):
+ self.queue.close()
+
+ def recv(self, timeout=None):
+ """Receives a single record from the socket. Timeout of 0 means nonblocking,
+ `None` means blocking and otherwise it's a timeout in seconds after which
+ the function just returns with `None`.
+ """
+ if timeout == 0:
+ try:
+ rv = self.queue.get(block=False)
+ except Exception:
+ return
+ else:
+ rv = self.queue.get(timeout=timeout)
+
+ log_record = rv.payload
+ rv.ack()
+
+ return LogRecord.from_dict(log_record)
+
+
class ZeroMQSubscriber(SubscriberBase):
"""A helper that acts as ZeroMQ subscriber and will dispatch received
log records to the active handler setup. There are multiple ways to
@@ -214,7 +320,8 @@ def _fix_261_mplog():
module is not imported by logging and as such the test in
the util fails.
"""
- import logging, multiprocessing
+ import logging
+ import multiprocessing
logging.multiprocessing = multiprocessing
View
1  logbook/ticketing.py
@@ -361,7 +361,6 @@ def get_tickets(self, order_by='-last_occurrence_time', limit=50, offset=0):
.limit(limit).skip(offset)
return [self._FixedTicketClass(self, obj) for obj in query]
-
def solve_ticket(self, ticket_id):
"""Marks a ticket as solved."""
self.database.tickets.update({'_id': self._oid(ticket_id)},
Please sign in to comment.
Something went wrong with that request. Please try again.