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.

100 lines
3.0 KiB

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