Logging handler to send logs to your OpenSearch cluster with bulk SSL. Forked from https://github.com/logzio/logzio-python-handler
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

90 lines
2.8 KiB

7 years ago
  1. import datetime
  2. import json
  3. import logging
  4. import logging.handlers
  5. import traceback
  6. import sys
  7. from .sender import LogzioSender
  8. class LogzioHandler(logging.Handler):
  9. def __init__(self, token, logzio_type="python", logs_drain_timeout=3,
  10. url="https://listener.logz.io:8071", debug=False):
  11. if token is "":
  12. raise Exception("Logz.io Token must be provided")
  13. self.logzio_type = logzio_type
  14. self.logzio_sender = LogzioSender(token=token, url=url, logs_drain_timeout=logs_drain_timeout, debug=debug)
  15. logging.Handler.__init__(self)
  16. def extra_fields(self, message):
  17. not_allowed_keys = (
  18. 'args', 'asctime', 'created', 'exc_info', 'stack_info', 'exc_text', 'filename',
  19. 'funcName', 'levelname', 'levelno', 'lineno', 'module',
  20. 'msecs', 'msecs', 'message', 'msg', 'name', 'pathname', 'process',
  21. 'processName', 'relativeCreated', 'thread', 'threadName')
  22. if sys.version_info < (3, 0):
  23. var_type = (basestring, bool, dict, float, int, long, list, type(None))
  24. else:
  25. var_type = (str, bool, dict, float, int, list, type(None))
  26. extra_fields = {}
  27. for key, value in message.__dict__.items():
  28. if key not in not_allowed_keys:
  29. if isinstance(value, var_type):
  30. extra_fields[key] = value
  31. else:
  32. extra_fields[key] = repr(value)
  33. return extra_fields
  34. def flush(self):
  35. self.logzio_sender.flush()
  36. def format(self, record):
  37. message = super(LogzioHandler, self).format(record)
  38. try:
  39. return json.loads(message)
  40. except (TypeError, ValueError):
  41. return message
  42. def format_exception(self, exc_info):
  43. return '\n'.join(traceback.format_exception(*exc_info))
  44. def format_message(self, message):
  45. now = datetime.datetime.utcnow()
  46. timestamp = now.strftime("%Y-%m-%dT%H:%M:%S") + ".%03d" % (now.microsecond / 1000) + "Z"
  47. return_json = {
  48. "logger": message.name,
  49. "line_number": message.lineno,
  50. "path_name": message.pathname,
  51. "log_level": message.levelname,
  52. "type": self.logzio_type,
  53. "message": message.getMessage(),
  54. "@timestamp": timestamp
  55. }
  56. if message.exc_info:
  57. return_json["exception"] = self.format_exception(message.exc_info)
  58. else:
  59. formatted_message = self.format(message)
  60. return_json.update(self.extra_fields(message))
  61. if isinstance(formatted_message, dict):
  62. return_json.update(formatted_message)
  63. else:
  64. return_json["message"] = formatted_message
  65. return return_json
  66. def emit(self, record):
  67. self.logzio_sender.append(self.format_message(record))