mirror of
https://github.com/bugsink/bugsink.git
synced 2026-01-10 23:30:13 -06:00
Truncate input-data that exceeds max_length
Avoiding any (1406, "Data too long for column ...") on MySQL. For the 'plainly provided' fields I followed the documented maximums which are also our DB maximums. For calculated_* I harmonized with what Sentry & GlitchTip both do (and which was already partially reflected in the code), i.e. 128 and 1024.
This commit is contained in:
20
events/migrations/0016_truncate_exception_type_128.py
Normal file
20
events/migrations/0016_truncate_exception_type_128.py
Normal file
@@ -0,0 +1,20 @@
|
||||
from django.db import migrations
|
||||
from django.db.models import F
|
||||
from django.db.models.functions import Substr, Length
|
||||
|
||||
|
||||
def truncate_exception_type_128(apps, schema_editor):
|
||||
Event = apps.get_model("events", "Event")
|
||||
Event.objects.annotate(
|
||||
l=Length('calculated_type')).filter(l__gte=128).update(calculated_type=Substr(F('calculated_type'), 1, 128))
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("events", "0004_b_squashed"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RunPython(truncate_exception_type_128),
|
||||
]
|
||||
@@ -0,0 +1,23 @@
|
||||
# Generated by Django 4.2.19 on 2025-02-08 19:53
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("events", "0016_truncate_exception_type_128"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name="event",
|
||||
name="calculated_type",
|
||||
field=models.CharField(blank=True, default="", max_length=128),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="event",
|
||||
name="calculated_value",
|
||||
field=models.TextField(blank=True, default="", max_length=1024),
|
||||
),
|
||||
]
|
||||
@@ -127,8 +127,8 @@ class Event(models.Model):
|
||||
debug_info = models.CharField(max_length=255, blank=True, null=False, default="")
|
||||
|
||||
# denormalized/cached fields:
|
||||
calculated_type = models.CharField(max_length=255, blank=True, null=False, default="")
|
||||
calculated_value = models.CharField(max_length=255, blank=True, null=False, default="")
|
||||
calculated_type = models.CharField(max_length=128, blank=True, null=False, default="")
|
||||
calculated_value = models.TextField(max_length=1024, blank=True, null=False, default="")
|
||||
# transaction = models.CharField(max_length=200, blank=True, null=False, default="") defined first-class above
|
||||
last_frame_filename = models.CharField(max_length=255, blank=True, null=False, default="")
|
||||
last_frame_module = models.CharField(max_length=255, blank=True, null=False, default="")
|
||||
@@ -201,6 +201,9 @@ class Event(models.Model):
|
||||
|
||||
irrelevance_for_retention = get_random_irrelevance(stored_event_count)
|
||||
|
||||
# A note on truncation (max_length): the fields we truncate here are directly from the SDK, so they "should have
|
||||
# been" truncated already. But we err on the side of caution: this is the kind of SDK error that we can, and
|
||||
# just want to, paper over (it's not worth dropping the event for).
|
||||
try:
|
||||
event = cls.objects.create(
|
||||
event_id=event_metadata["event_id"], # the metadata is the envelope's event_id, which takes precedence
|
||||
@@ -212,25 +215,25 @@ class Event(models.Model):
|
||||
data=json.dumps(parsed_data),
|
||||
|
||||
timestamp=parse_timestamp(parsed_data["timestamp"]),
|
||||
platform=parsed_data["platform"],
|
||||
platform=parsed_data["platform"][:64],
|
||||
|
||||
level=maybe_empty(parsed_data.get("level", "")),
|
||||
logger=maybe_empty(parsed_data.get("logger", "")),
|
||||
logger=maybe_empty(parsed_data.get("logger", ""))[:64],
|
||||
# transaction=maybe_empty(parsed_data.get("transaction", "")), part of denormalized_fields
|
||||
|
||||
server_name=maybe_empty(parsed_data.get("server_name", "")),
|
||||
release=maybe_empty(parsed_data.get("release", "")),
|
||||
dist=maybe_empty(parsed_data.get("dist", "")),
|
||||
server_name=maybe_empty(parsed_data.get("server_name", ""))[:255],
|
||||
release=maybe_empty(parsed_data.get("release", ""))[:250],
|
||||
dist=maybe_empty(parsed_data.get("dist", ""))[:64],
|
||||
|
||||
environment=maybe_empty(parsed_data.get("environment", "")),
|
||||
environment=maybe_empty(parsed_data.get("environment", ""))[:64],
|
||||
|
||||
sdk_name=maybe_empty(parsed_data.get("", {}).get("name", "")),
|
||||
sdk_version=maybe_empty(parsed_data.get("", {}).get("version", "")),
|
||||
sdk_name=maybe_empty(parsed_data.get("", {}).get("name", ""))[:255],
|
||||
sdk_version=maybe_empty(parsed_data.get("", {}).get("version", ""))[:255],
|
||||
|
||||
has_exception="exception" in parsed_data,
|
||||
has_logentry="logentry" in parsed_data,
|
||||
|
||||
debug_info=event_metadata["debug_info"],
|
||||
debug_info=event_metadata["debug_info"][:255],
|
||||
|
||||
digest_order=digest_order,
|
||||
irrelevance_for_retention=irrelevance_for_retention,
|
||||
|
||||
@@ -64,7 +64,7 @@ def get_exception_type_and_value_for_logmessage(data):
|
||||
)
|
||||
|
||||
if message:
|
||||
return "Log Message", message.splitlines()[0]
|
||||
return "Log Message", message.splitlines()[0][:1024]
|
||||
|
||||
return "Log Message", "<no log message>"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user