def to_dict()

in elasticapm/traces.py [0:0]


    def to_dict(self) -> dict:
        # This copy() only covers top level `.pop()` calls, so if we ever start
        # modifying nested data, we'll need to do a deep copy.
        context = self.context.copy()
        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.total_seconds() * 1000 if self.duration else None,
            "result": encoding.keyword_field(str(self.result)),
            "timestamp": int(self.timestamp * 1_000_000),  # microseconds
            "outcome": self.outcome,
            "sampled": self.is_sampled,
            "span_count": {"started": self._span_counter, "dropped": self.dropped_spans},
        }
        if self._dropped_span_statistics:
            result["dropped_spans_stats"] = [
                {
                    "destination_service_resource": resource,
                    "service_target_type": target_type,
                    "service_target_name": target_name,
                    "outcome": outcome,
                    "duration": {"count": v["count"], "sum": {"us": int(v["duration.sum.us"])}},
                }
                for (resource, outcome, target_type, target_name), v in self._dropped_span_statistics.items()
            ]
        if self.sample_rate is not None:
            result["sample_rate"] = float(self.sample_rate)
        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.links:
            result["links"] = self.links
        # faas context belongs top-level on the transaction
        if "faas" in context:
            result["faas"] = context.pop("faas")
        # otel attributes and spankind need to be top-level
        if "otel_spankind" in context:
            result["otel"] = {"span_kind": context.pop("otel_spankind")}
        # Some transaction_store_tests use the Tracer without a Client -- the
        # extra check against `get_client()` is here to make those tests pass
        if elasticapm.get_client() and elasticapm.get_client().check_server_version(gte=(7, 16)):
            if "otel_attributes" in context:
                if "otel" not in result:
                    result["otel"] = {"attributes": context.pop("otel_attributes")}
                else:
                    result["otel"]["attributes"] = context.pop("otel_attributes")
        else:
            # Attributes map to labels for older versions
            attributes = context.pop("otel_attributes", {})
            for key, value in attributes.items():
                result["context"]["tags"][key] = value
        if self.is_sampled:
            result["context"] = context
        return result