serializers.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. from rest_framework import serializers
  2. from events.serializers import SentrySDKEventSerializer
  3. from glitchtip.serializers import FlexibleDateTimeField
  4. from .models import Span, TransactionEvent, TransactionGroup
  5. class TransactionGroupSerializer(serializers.ModelSerializer):
  6. avgDuration = serializers.DurationField(source="avg_duration", read_only=True)
  7. transactionCount = serializers.IntegerField(
  8. source="transaction_count", read_only=True
  9. )
  10. class Meta:
  11. model = TransactionGroup
  12. fields = [
  13. "id",
  14. "transaction",
  15. "project",
  16. "op",
  17. "method",
  18. "avgDuration",
  19. "transactionCount",
  20. ]
  21. class SpanSerializer(serializers.ModelSerializer):
  22. spanId = serializers.CharField(source="span_id", read_only=True)
  23. parentSpanId = serializers.CharField(source="parent_span_id", read_only=True)
  24. startTimestamp = serializers.DateTimeField(source="start_timestamp", read_only=True)
  25. class Meta:
  26. model = Span
  27. fields = [
  28. "spanId",
  29. "span_id",
  30. "parent_span_id",
  31. "parentSpanId",
  32. "op",
  33. "description",
  34. "startTimestamp",
  35. "start_timestamp",
  36. "timestamp",
  37. "tags",
  38. "data",
  39. ]
  40. extra_kwargs = {
  41. "start_timestamp": {"write_only": True},
  42. "span_id": {"write_only": True},
  43. "parent_span_id": {"write_only": True},
  44. }
  45. class TransactionEventSerializer(SentrySDKEventSerializer):
  46. type = serializers.CharField()
  47. contexts = serializers.JSONField()
  48. measurements = serializers.JSONField(required=False)
  49. spans = serializers.ListField(
  50. child=SpanSerializer(), required=False, allow_empty=True
  51. )
  52. start_timestamp = FlexibleDateTimeField()
  53. timestamp = FlexibleDateTimeField()
  54. transaction = serializers.CharField()
  55. def create(self, data):
  56. trace_id = data["contexts"]["trace"]["trace_id"]
  57. group, _ = TransactionGroup.objects.get_or_create(
  58. project=self.context.get("project"),
  59. transaction=data["transaction"],
  60. op=data["contexts"]["trace"]["op"],
  61. method=data.get("request", {}).get("method"),
  62. )
  63. transaction = TransactionEvent.objects.create(
  64. group=group,
  65. data={
  66. "request": data.get("request"),
  67. "sdk": data.get("sdk"),
  68. "platform": data.get("platform"),
  69. },
  70. trace_id=trace_id,
  71. event_id=data["event_id"],
  72. timestamp=data["timestamp"],
  73. start_timestamp=data["start_timestamp"],
  74. duration=data["timestamp"] - data["start_timestamp"],
  75. )
  76. first_span = SpanSerializer(
  77. data=data["contexts"]["trace"]
  78. | {
  79. "start_timestamp": data["start_timestamp"],
  80. "timestamp": data["timestamp"],
  81. }
  82. )
  83. first_span.is_valid()
  84. spans = data.get("spans", []) + [first_span.validated_data]
  85. Span.objects.bulk_create(
  86. [
  87. Span(
  88. transaction=transaction,
  89. **span,
  90. )
  91. for span in spans
  92. ]
  93. )
  94. return transaction
  95. class TransactionSerializer(serializers.ModelSerializer):
  96. eventId = serializers.UUIDField(source="pk")
  97. startTimestamp = serializers.DateTimeField(source="start_timestamp")
  98. transaction = serializers.SerializerMethodField()
  99. op = serializers.SerializerMethodField()
  100. method = serializers.SerializerMethodField()
  101. class Meta:
  102. model = TransactionEvent
  103. fields = (
  104. "eventId",
  105. "timestamp",
  106. "startTimestamp",
  107. "transaction",
  108. "op",
  109. "method",
  110. )
  111. def get_transaction(self, obj):
  112. return obj.group.transaction
  113. def get_op(self, obj):
  114. return obj.group.op
  115. def get_method(self, obj):
  116. return obj.group.transaction
  117. class TransactionDetailSerializer(TransactionSerializer):
  118. spans = SpanSerializer(source="span_set", many=True)
  119. class Meta(TransactionSerializer.Meta):
  120. fields = TransactionSerializer.Meta.fields + ("spans",)