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.

88 lines
2.8 KiB

  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', '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 format(self, record):
  35. message = super(LogzioHandler, self).format(record)
  36. try:
  37. return json.loads(message)
  38. except (TypeError, ValueError):
  39. return message
  40. def format_exception(self, exc_info):
  41. return '\n'.join(traceback.format_exception(*exc_info))
  42. def format_message(self, message):
  43. now = datetime.datetime.utcnow()
  44. timestamp = now.strftime("%Y-%m-%dT%H:%M:%S") + ".%03d" % (now.microsecond / 1000) + "Z"
  45. return_json = {
  46. "logger": message.name,
  47. "line_number": message.lineno,
  48. "path_name": message.pathname,
  49. "log_level": message.levelname,
  50. "type": self.logzio_type,
  51. "message": message.getMessage(),
  52. "@timestamp": timestamp
  53. }
  54. if message.exc_info:
  55. return_json["exception"] = self.format_exception(message.exc_info)
  56. else:
  57. formatted_message = self.format(message)
  58. return_json.update(self.extra_fields(message))
  59. if isinstance(formatted_message, dict):
  60. return_json.update(formatted_message)
  61. else:
  62. return_json["message"] = formatted_message
  63. return return_json
  64. def emit(self, record):
  65. self.logzio_sender.append(self.format_message(record))