elasticapm/contrib/django/handlers.py (45 lines of code) (raw):
# BSD 3-Clause License
#
# Copyright (c) 2012, the Sentry Team, see AUTHORS for more details
# Copyright (c) 2019, Elasticsearch BV
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# * Neither the name of the copyright holder nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
from __future__ import absolute_import
import logging
import sys
import warnings
from django.conf import settings as django_settings
from elasticapm import get_client
from elasticapm.handlers.logging import LoggingHandler as BaseLoggingHandler
from elasticapm.utils.logging import get_logger
logger = get_logger("elasticapm.logging")
class LoggingHandler(BaseLoggingHandler):
def __init__(self, level=logging.NOTSET) -> None:
warnings.warn(
"The LoggingHandler is deprecated and will be removed in v7.0 of the agent. "
"Please use `log_ecs_reformatting` and ship the logs with Elastic "
"Agent or Filebeat instead. "
"https://www.elastic.co/guide/en/apm/agent/python/current/logs.html",
DeprecationWarning,
)
# skip initialization of BaseLoggingHandler
logging.Handler.__init__(self, level=level)
@property
def client(self):
return get_client()
def _emit(self, record, **kwargs):
from elasticapm.contrib.django.middleware import LogMiddleware
# Fetch the request from a threadlocal variable, if available
request = getattr(LogMiddleware.thread, "request", None)
request = getattr(record, "request", request)
return super(LoggingHandler, self)._emit(record, request=request, **kwargs)
def exception_handler(client, request=None, **kwargs):
def actually_do_stuff(request=None, **kwargs) -> None:
exc_info = sys.exc_info()
try:
if (django_settings.DEBUG and not client.config.debug) or getattr(exc_info[1], "skip_elasticapm", False):
return
client.capture("Exception", exc_info=exc_info, request=request, handled=False)
except Exception as exc:
try:
client.error_logger.exception("Unable to process log entry: %s" % (exc,))
except Exception as exc:
warnings.warn("Unable to process log entry: %s" % (exc,))
finally:
try:
del exc_info
except Exception as e:
client.error_logger.exception(e)
return actually_do_stuff(request, **kwargs)