コード例 #1
0
    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(
                    encoding.force_text(user.get_username()))
            elif hasattr(user, "username"):
                user_info["username"] = encoding.keyword_field(
                    encoding.force_text(user.username))

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

        return user_info
コード例 #2
0
def set_user_context(username=None, email=None, user_id=None):
    data = {}
    if username is not None:
        data["username"] = encoding.keyword_field(username)
    if email is not None:
        data["email"] = encoding.keyword_field(email)
    if user_id is not None:
        data["id"] = encoding.keyword_field(user_id)
    set_context(data, "user")
コード例 #3
0
def test_transaction_keyword_truncation(zuqa_client):
    too_long = "x" * (KEYWORD_MAX_LENGTH + 1)
    expected = encoding.keyword_field(too_long)
    assert too_long != expected
    assert len(expected) == KEYWORD_MAX_LENGTH
    assert expected[-1] != "x"
    zuqa_client.begin_transaction(too_long)
    zuqa.tag(val=too_long)
    zuqa.set_user_context(username=too_long, email=too_long, user_id=too_long)
    with zuqa.capture_span(name=too_long, span_type=too_long):
        pass
    zuqa_client.end_transaction(too_long, too_long)
    zuqa_client.close()

    span = zuqa_client.events["span"][0]
    transaction = zuqa_client.events["transaction"][0]

    assert transaction["name"] == expected
    assert transaction["type"] == expected
    assert transaction["result"] == expected

    assert transaction["context"]["user"]["id"] == expected
    assert transaction["context"]["user"]["username"] == expected
    assert transaction["context"]["user"]["email"] == expected

    assert transaction["context"]["tags"]["val"] == expected

    assert span["type"] == expected
    assert span["name"] == expected
コード例 #4
0
 def get_system_info(self):
     system_data = {
         "hostname": keyword_field(self.config.hostname),
         "architecture": platform.machine(),
         "platform": platform.system().lower(),
     }
     system_data.update(cgroup.get_cgroup_container_metadata())
     pod_name = os.environ.get(
         "KUBERNETES_POD_NAME") or system_data["hostname"]
     changed = False
     if "kubernetes" in system_data:
         k8s = system_data["kubernetes"]
         k8s["pod"]["name"] = pod_name
     else:
         k8s = {"pod": {"name": pod_name}}
     # get kubernetes metadata from environment
     if "KUBERNETES_NODE_NAME" in os.environ:
         k8s["node"] = {"name": os.environ["KUBERNETES_NODE_NAME"]}
         changed = True
     if "KUBERNETES_NAMESPACE" in os.environ:
         k8s["namespace"] = os.environ["KUBERNETES_NAMESPACE"]
         changed = True
     if "KUBERNETES_POD_UID" in os.environ:
         # this takes precedence over any value from /proc/self/cgroup
         k8s["pod"]["uid"] = os.environ["KUBERNETES_POD_UID"]
         changed = True
     if changed:
         system_data["kubernetes"] = k8s
     return system_data
コード例 #5
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
コード例 #6
0
 def to_dict(self):
     self.context["tags"] = self.labels
     result = {
         "id": self.id,
         "trace_id": self.trace_parent.trace_id,
         "name": encoding.keyword_field(self.name or ""),
         "type": encoding.keyword_field(self.transaction_type),
         "duration": self.duration * 1000,  # milliseconds
         "result": encoding.keyword_field(str(self.result)),
         "timestamp": int(self.timestamp * 1000000),  # microseconds
         "sampled": self.is_sampled,
         "span_count": {"started": self._span_counter - self.dropped_spans, "dropped": self.dropped_spans},
     }
     if self.trace_parent:
         result["trace_id"] = self.trace_parent.trace_id
         # only set parent_id if this transaction isn't the root
         if self.trace_parent.span_id and self.trace_parent.span_id != self.id:
             result["parent_id"] = self.trace_parent.span_id
     if self.is_sampled:
         result["context"] = self.context
     return result
コード例 #7
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
コード例 #8
0
 def to_dict(self):
     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(self.name),
         "type": encoding.keyword_field(self.type),
         "subtype": encoding.keyword_field(self.subtype),
         "action": encoding.keyword_field(self.action),
         "sync": self.sync,
         "timestamp": int(self.timestamp * 1000000),  # microseconds
         "duration": self.duration * 1000,  # milliseconds
     }
     if self.labels:
         if self.context is None:
             self.context = {}
         self.context["tags"] = self.labels
     if self.context:
         result["context"] = self.context
     if self.frames:
         result["stacktrace"] = self.frames
     return result
コード例 #9
0
    def tag(self, **tags):
        """
        This method is deprecated, please use "label()" instead.

        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 (_)

        :param tags: key/value pairs of tags
        :return: None
        """
        for key in tags.keys():
            self.labels[LABEL_RE.sub("_", compat.text_type(key))] = encoding.keyword_field(compat.text_type(tags[key]))
コード例 #10
0
def test_message_keyword_truncation(sending_zuqa_client):
    too_long = "x" * (KEYWORD_MAX_LENGTH + 1)
    expected = encoding.keyword_field(too_long)
    sending_zuqa_client.capture_message(param_message={
        "message": too_long,
        "params": []
    },
                                        logger_name=too_long,
                                        handled=False)
    sending_zuqa_client.close()
    error = sending_zuqa_client.httpserver.payloads[0][1]["error"]

    assert error["log"]["param_message"] == expected
    assert error["log"]["message"] == too_long  # message is not truncated

    assert error["log"]["logger_name"] == expected
コード例 #11
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": zuqa.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
コード例 #12
0
def test_error_keyword_truncation(sending_zuqa_client):
    too_long = "x" * (KEYWORD_MAX_LENGTH + 1)
    expected = encoding.keyword_field(too_long)

    # let's create a way too long Exception type with a way too long module name
    WayTooLongException = type(too_long.upper(), (Exception, ), {})
    WayTooLongException.__module__ = too_long
    try:
        raise WayTooLongException()
    except WayTooLongException:
        with mock.patch("zuqa.events.get_culprit") as mock_get_culprit:
            mock_get_culprit.return_value = too_long
            sending_zuqa_client.capture_exception(handled=False)
    sending_zuqa_client.close()
    error = sending_zuqa_client.httpserver.payloads[0][1]["error"]

    assert error["exception"]["type"] == expected.upper()
    assert error["exception"]["module"] == expected
    assert error["culprit"] == expected
コード例 #13
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 exc_info == (None, None, None):
            raise ValueError("No exception found: capture_exception requires an active exception.")

        try:
            exc_type, exc_value, exc_traceback = exc_info

            frames = get_stack_info(
                iter_traceback_frames(exc_traceback, config=client.config),
                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,
                        dict_length=client.config.local_var_dict_max_length,
                    ),
                    local_var,
                ),
            )

            culprit = kwargs.get("culprit", None) or 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)

        data = {
            "id": "%032x" % random.getrandbits(128),
            "culprit": keyword_field(culprit),
            "exception": {
                "message": message,
                "type": keyword_field(str(exc_type)),
                "module": keyword_field(str(exc_module)),
                "stacktrace": frames,
            },
        }
        if hasattr(exc_value, "_zuqa_span_id"):
            data["parent_id"] = exc_value._zuqa_span_id
            del exc_value._zuqa_span_id
        if compat.PY3:
            depth = kwargs.get("_exc_chain_depth", 0)
            if depth > EXCEPTION_CHAIN_MAX_DEPTH:
                return
            cause = exc_value.__cause__
            chained_context = exc_value.__context__

            # we follow the pattern of Python itself here and only capture the chained exception
            # if cause is not None and __suppress_context__ is False
            if chained_context and not (exc_value.__suppress_context__ and cause is None):
                if cause:
                    chained_exc_type = type(cause)
                    chained_exc_value = cause
                else:
                    chained_exc_type = type(chained_context)
                    chained_exc_value = chained_context
                chained_exc_info = chained_exc_type, chained_exc_value, chained_context.__traceback__

                chained_cause = Exception.capture(
                    client, exc_info=chained_exc_info, culprit="None", _exc_chain_depth=depth + 1
                )
                if chained_cause:
                    data["exception"]["cause"] = [chained_cause["exception"]]
        return data