/django_logstream/client/handlers/threaded.py

https://github.com/niwibe/django-logstream · Python · 69 lines · 55 code · 13 blank · 1 comment · 6 complexity · 9a7cf8ef3c7d50c66e3b54141397b7cf MD5 · raw file

  1. # -*- coding: utf-8 -*-
  2. from django.conf import settings
  3. from django_logstream.utils import Singleton
  4. from Queue import Queue
  5. from thread import start_new_thread
  6. from threading import Lock
  7. from logging import StreamHandler
  8. import zmq, copy
  9. from Crypto.Cipher import Blowfish
  10. from Crypto.Hash import SHA
  11. class ZeroMQHandler(StreamHandler):
  12. __metaclass__ = Singleton
  13. _queue = Queue()
  14. def __init__(self, alias, address = 'ipc:///tmp/logstream_receiver',
  15. auth={}, encrypt=False, *args, **kwargs):
  16. super(ZeroMQHandler, self).__init__(*args, **kwargs)
  17. self.alias = alias
  18. self.context = zmq.Context()
  19. self.socket = self.context.socket(zmq.PUSH)
  20. self.socket.connect(address)
  21. self.cipher_enabled = encrypt
  22. self.auth = auth
  23. start_new_thread(self._loop, ())
  24. def _encrypt_str(self, data):
  25. res = len(data) % 8
  26. if res != 0:
  27. data = data + "\0" * (8-res)
  28. return self.cipher.encrypt(data)
  29. def _encrypt(self, obj):
  30. newobj = copy.deepcopy(obj)
  31. newobj['alias'] = self._encrypt_str(obj['alias'].encode('utf-8'))
  32. newobj['record'] = self._encrypt_str(obj['record'].encode('utf-8'))
  33. return newobj
  34. def _loop(self):
  35. self.cipher = Blowfish.new(settings.SECRET_KEY)
  36. while True:
  37. data = self._queue.get(True)
  38. if self.cipher_enabled:
  39. data = self._encrypt(data)
  40. self.socket.send_pyobj(data)
  41. def _hash_message(self, obj):
  42. nobj = copy.deepcopy(obj)
  43. for key, value in obj.iteritems():
  44. if not isinstance(value, (str, unicode)):
  45. continue
  46. if isinstance(value, unicode):
  47. value = value.encode('utf-8')
  48. nobj[key + "_sha"] = SHA.new(value).hexdigest()
  49. return nobj
  50. def emit(self, record):
  51. send_obj = self._hash_message({
  52. 'alias': self.alias,
  53. 'record': self.format(record),
  54. 'encrypt': self.cipher_enabled,
  55. })
  56. self._queue.put_nowait(send_obj)