Files
trackbugs/app/Services/PayloadNormalizer.php
2026-03-19 19:32:46 +02:00

112 lines
3.2 KiB
PHP

<?php
namespace App\Services;
use Illuminate\Support\Carbon;
use Illuminate\Support\Str;
class PayloadNormalizer
{
/**
* Normalize a raw Sentry event payload into the canonical shape
* expected by the EventProcessor.
*/
public function normalize(array $raw): array
{
return [
'event_id' => $raw['event_id'] ?? Str::uuid()->toString(),
'level' => $this->normalizeLevel($raw['level'] ?? 'error'),
'message' => $this->extractMessage($raw),
'platform' => $raw['platform'] ?? null,
'timestamp' => $this->normalizeTimestamp($raw['timestamp'] ?? null),
'server_name' => $raw['server_name'] ?? null,
'release' => $raw['release'] ?? null,
'environment' => $raw['environment'] ?? null,
'exception' => $raw['exception'] ?? ['values' => []],
'breadcrumbs' => $raw['breadcrumbs'] ?? null,
'contexts' => $raw['contexts'] ?? null,
'tags' => $this->normalizeTags($raw['tags'] ?? null),
'extra' => $raw['extra'] ?? null,
'user_context' => $raw['user'] ?? null,
'request_context' => $raw['request'] ?? null,
'sdk' => $raw['sdk'] ?? null,
'fingerprint' => $raw['fingerprint'] ?? null,
];
}
private function normalizeLevel(string $level): string
{
$map = [
'fatal' => 'fatal',
'critical' => 'fatal',
'error' => 'error',
'warning' => 'warning',
'warn' => 'warning',
'info' => 'info',
'log' => 'info',
'debug' => 'debug',
];
return $map[strtolower($level)] ?? 'error';
}
private function extractMessage(array $raw): ?string
{
if (! empty($raw['message'])) {
return Str::limit($raw['message'], 2000);
}
if (! empty($raw['logentry']['message'])) {
return Str::limit($raw['logentry']['message'], 2000);
}
$exceptions = $raw['exception']['values'] ?? [];
$last = end($exceptions);
if ($last) {
$type = $last['type'] ?? 'Error';
$value = $last['value'] ?? '';
return Str::limit("{$type}: {$value}", 2000);
}
return null;
}
private function normalizeTimestamp(mixed $timestamp): Carbon
{
if ($timestamp === null) {
return Carbon::now();
}
if (is_numeric($timestamp)) {
return Carbon::createFromTimestamp((float) $timestamp);
}
return Carbon::parse($timestamp);
}
/**
* Tags can arrive as key-value pairs or as an array of {key, value} objects.
* Normalize to a plain associative array.
*/
private function normalizeTags(mixed $tags): ?array
{
if ($tags === null) {
return null;
}
if (array_is_list($tags)) {
$normalized = [];
foreach ($tags as $tag) {
if (isset($tag['key'], $tag['value'])) {
$normalized[$tag['key']] = $tag['value'];
}
}
return $normalized ?: null;
}
return $tags;
}
}