Пример #1
0
    def capture(client, exc_info=None, **kwargs):
        culprit = exc_value = exc_type = exc_module = frames = exc_traceback = None
        new_exc_info = False
        if not exc_info or exc_info is True:
            new_exc_info = True
            exc_info = sys.exc_info()

        if not exc_info:
            raise ValueError("No exception found")

        try:
            exc_type, exc_value, exc_traceback = exc_info

            frames = get_stack_info(
                iter_traceback_frames(exc_traceback),
                with_locals=client.config.collect_local_variables in ("errors", "all"),
                library_frame_context_lines=client.config.source_lines_error_library_frames,
                in_app_frame_context_lines=client.config.source_lines_error_app_frames,
                include_paths_re=client.include_paths_re,
                exclude_paths_re=client.exclude_paths_re,
                locals_processor_func=lambda local_var: varmap(
                    lambda k, val: shorten(
                        val,
                        list_length=client.config.local_var_list_max_length,
                        string_length=client.config.local_var_max_length,
                    ),
                    local_var,
                ),
            )

            culprit = get_culprit(frames, client.config.include_paths, client.config.exclude_paths)

            if hasattr(exc_type, "__module__"):
                exc_module = exc_type.__module__
                exc_type = exc_type.__name__
            else:
                exc_module = None
                exc_type = exc_type.__name__
        finally:
            if new_exc_info:
                try:
                    del exc_info
                    del exc_traceback
                except Exception as e:
                    logger.exception(e)
        if "message" in kwargs:
            message = kwargs["message"]
        else:
            message = "%s: %s" % (exc_type, to_unicode(exc_value)) if exc_value else str(exc_type)

        return {
            "id": "%032x" % random.getrandbits(128),
            "culprit": culprit,
            "exception": {
                "message": message,
                "type": keyword_field(str(exc_type)),
                "module": keyword_field(str(exc_module)),
                "stacktrace": frames,
            },
        }
Пример #2
0
 def capture(client,
             param_message=None,
             message=None,
             level=None,
             logger_name=None,
             **kwargs):
     if message:
         param_message = {'message': message}
     params = param_message.get('params')
     message = param_message[
         'message'] % params if params else param_message['message']
     data = kwargs.get('data', {})
     message_data = {
         'id': str(uuid.uuid4()),
         'log': {
             'level': keyword_field(level or 'error'),
             'logger_name': keyword_field(logger_name or '__root__'),
             'message': message,
             'param_message': keyword_field(param_message['message']),
         }
     }
     if isinstance(data.get('stacktrace'), dict):
         message_data['log']['stacktrace'] = data['stacktrace']['frames']
     if kwargs.get('exception'):
         message_data['culprit'] = kwargs['exception']['culprit']
         message_data['exception'] = kwargs['exception']['exception']
     return message_data
    def get_user_info(self, request):
        user_info = {}

        if not hasattr(request, 'user'):
            return user_info
        try:
            user = request.user
            if hasattr(user, 'is_authenticated'):
                if callable(user.is_authenticated):
                    user_info['is_authenticated'] = user.is_authenticated()
                else:
                    user_info['is_authenticated'] = bool(user.is_authenticated)
            if hasattr(user, 'id'):
                user_info['id'] = encoding.keyword_field(user.id)
            if hasattr(user, 'get_username'):
                user_info['username'] = encoding.keyword_field(
                    user.get_username())
            elif hasattr(user, 'username'):
                user_info['username'] = encoding.keyword_field(user.username)

            if hasattr(user, 'email'):
                user_info['email'] = user.email
        except DatabaseError:
            # If the connection is closed or similar, we'll just skip this
            return {}

        return user_info
Пример #4
0
 def capture(client,
             param_message=None,
             message=None,
             level=None,
             logger_name=None,
             **kwargs):
     if message:
         param_message = {"message": message}
     params = param_message.get("params")
     message = param_message[
         "message"] % params if params else param_message["message"]
     data = kwargs.get("data", {})
     message_data = {
         "id": "%032x" % random.getrandbits(128),
         "log": {
             "level": keyword_field(level or "error"),
             "logger_name": keyword_field(logger_name or "__root__"),
             "message": message,
             "param_message": keyword_field(param_message["message"]),
         },
     }
     if isinstance(data.get("stacktrace"), dict):
         message_data["log"]["stacktrace"] = data["stacktrace"]["frames"]
     if kwargs.get("exception"):
         message_data["culprit"] = kwargs["exception"]["culprit"]
         message_data["exception"] = kwargs["exception"]["exception"]
     return message_data
Пример #5
0
def get_url_dict(event: dict) -> dict:
    """
    Reconstruct URL from API Gateway
    """
    headers = event.get("headers", {})
    protocol = headers.get("X-Forwarded-Proto",
                           headers.get("x-forwarded-proto", "https"))
    host = headers.get("Host", headers.get("host", ""))
    stage = "/" + (nested_key(event, "requestContext", "stage") or "")
    path = event.get("path", event.get("rawPath", "").split(stage)[-1])
    port = headers.get("X-Forwarded-Port", headers.get("x-forwarded-port"))
    query = ""
    if "rawQueryString" in event:
        query = event["rawQueryString"]
    elif event.get("queryStringParameters"):
        query = "?"
        for k, v in compat.iteritems(event["queryStringParameters"]):
            query += "{}={}".format(k, v)
    url = protocol + "://" + host + stage + path + query

    url_dict = {
        "full": encoding.keyword_field(url),
        "protocol": protocol,
        "hostname": encoding.keyword_field(host),
        "pathname": encoding.keyword_field(stage + path),
    }

    if port:
        url_dict["port"] = port
    if query:
        url_dict["search"] = encoding.keyword_field(query)
    return url_dict
Пример #6
0
def sanitize_http_request_querystring(client, event):
    """
    Sanitizes http request query string
    :param client: an ElasticAPM client
    :param event: a transaction or error event
    :return: The modified event
    """
    try:
        query_string = force_text(event["context"]["request"]["url"]["search"],
                                  errors="replace")
    except (KeyError, TypeError):
        return event
    if "=" in query_string:
        sanitized_query_string = _sanitize_string(
            query_string,
            "&",
            "=",
            sanitize_field_names=client.config.sanitize_field_names)
        full_url = event["context"]["request"]["url"]["full"]
        # we need to pipe the sanitized string through encoding.keyword_field to ensure that the maximum
        # length of keyword fields is still ensured.
        event["context"]["request"]["url"]["search"] = keyword_field(
            sanitized_query_string)
        event["context"]["request"]["url"]["full"] = keyword_field(
            full_url.replace(query_string, sanitized_query_string))
    return event
Пример #7
0
 def get_service_info(self):
     if self._service_info:
         return self._service_info
     language_version = platform.python_version()
     if hasattr(sys, "pypy_version_info"):
         runtime_version = ".".join(map(str, sys.pypy_version_info[:3]))
     else:
         runtime_version = language_version
     result = {
         "name": keyword_field(self.config.service_name),
         "environment": keyword_field(self.config.environment),
         "version": keyword_field(self.config.service_version),
         "agent": {"name": "python", "version": elasticapm.VERSION},
         "language": {"name": "python", "version": keyword_field(platform.python_version())},
         "runtime": {
             "name": keyword_field(platform.python_implementation()),
             "version": keyword_field(runtime_version),
         },
     }
     if self.config.framework_name:
         result["framework"] = {
             "name": keyword_field(self.config.framework_name),
             "version": keyword_field(self.config.framework_version),
         }
     if self.config.service_node_name:
         result["node"] = {"configured_name": keyword_field(self.config.service_node_name)}
     self._service_info = result
     return result
Пример #8
0
 def to_dict(self):
     result = {
         "id": self.id,
         "transaction_id": self.transaction.id,
         "trace_id": self.transaction.trace_parent.trace_id,
         "parent_id": self.parent.id if self.parent else self.transaction.id,
         "name": encoding.keyword_field(self.name),
         "type": encoding.keyword_field(self.type),
         "timestamp": int(self.timestamp * 1000000),  # microseconds
         "duration": self.duration * 1000,  # milliseconds
         "context": self.context,
     }
     if self.frames:
         result["stacktrace"] = self.frames
     return result
Пример #9
0
def get_url_dict(url):
    parse_result = compat.urlparse.urlparse(url)

    url_dict = {
        "full": encoding.keyword_field(url),
        "protocol": parse_result.scheme + ":",
        "hostname": encoding.keyword_field(parse_result.hostname),
        "pathname": encoding.keyword_field(parse_result.path),
    }

    port = None if parse_result.port is None else str(parse_result.port)

    if port:
        url_dict["port"] = port
    if parse_result.query:
        url_dict["search"] = encoding.keyword_field("?" + parse_result.query)
    return url_dict
Пример #10
0
def get_url_dict(url):
    scheme, netloc, path, params, query, fragment = compat.urlparse.urlparse(
        url)
    if ':' in netloc:
        hostname, port = netloc.split(':')
    else:
        hostname, port = (netloc, None)
    url_dict = {
        'full': encoding.keyword_field(url),
        'protocol': scheme + ':',
        'hostname': encoding.keyword_field(hostname),
        'pathname': encoding.keyword_field(path),
    }
    if port:
        url_dict['port'] = port
    if query:
        url_dict['search'] = encoding.keyword_field('?' + query)
    return url_dict
Пример #11
0
 def to_dict(self) -> dict:
     if (
         self.composite
         and self.composite["compression_strategy"] == "same_kind"
         and nested_key(self.context, "destination", "service", "resource")
     ):
         name = "Calls to " + self.context["destination"]["service"]["resource"]
     else:
         name = self.name
     result = {
         "id": self.id,
         "transaction_id": self.transaction.id,
         "trace_id": self.transaction.trace_parent.trace_id,
         # use either the explicitly set parent_span_id, or the id of the parent, or finally the transaction id
         "parent_id": self.parent_span_id or (self.parent.id if self.parent else self.transaction.id),
         "name": encoding.keyword_field(name),
         "type": encoding.keyword_field(self.type),
         "subtype": encoding.keyword_field(self.subtype),
         "action": encoding.keyword_field(self.action),
         "timestamp": int(self.timestamp * 1000000),  # microseconds
         "duration": self.duration * 1000,  # milliseconds
         "outcome": self.outcome,
     }
     if self.transaction.sample_rate is not None:
         result["sample_rate"] = float(self.transaction.sample_rate)
     if self.sync is not None:
         result["sync"] = self.sync
     if self.labels:
         if self.context is None:
             self.context = {}
         self.context["tags"] = self.labels
     if self.context:
         self.autofill_resource_context()
         result["context"] = self.context
     if self.frames:
         result["stacktrace"] = self.frames
     if self.composite:
         result["composite"] = {
             "compression_strategy": self.composite["compression_strategy"],
             "sum": self.composite["sum"] * 1000,
             "count": self.composite["count"],
         }
     return result
Пример #12
0
    def tag(self, **tags):
        """
        Tag this span with one or multiple key/value tags. Both the values should be strings

            span_obj.tag(key1="value1", key2="value2")

        Note that keys will be dedotted, replacing dot (.), star (*) and double quote (") with an underscore (_)
        """
        for key in tags.keys():
            self.tags[TAG_RE.sub(
                "_", compat.text_type(key))] = encoding.keyword_field(
                    compat.text_type(tags[key]))
Пример #13
0
def tag(**tags):
    """
    Tags current transaction. Both key and value of the tag should be strings.
    """
    transaction = get_transaction()
    for name, value in tags.items():
        if not transaction:
            error_logger.warning(
                "Ignored tag %s. No transaction currently active.", name)
            return
        # replace invalid characters for Elasticsearch field names with underscores
        name = TAG_RE.sub("_", compat.text_type(name))
        transaction.tags[compat.text_type(name)] = encoding.keyword_field(
            compat.text_type(value))