diff --git a/packages/core/src/integrations/sentry/components/EventDetails.tsx b/packages/core/src/integrations/sentry/components/EventDetails.tsx index a2f7f970..d4461b2d 100644 --- a/packages/core/src/integrations/sentry/components/EventDetails.tsx +++ b/packages/core/src/integrations/sentry/components/EventDetails.tsx @@ -57,7 +57,7 @@ export default function EventDetails() { return ( <>
- +

{renderEventTitle(event)}

{!!traceCtx && (
diff --git a/packages/core/src/integrations/sentry/components/EventList.tsx b/packages/core/src/integrations/sentry/components/EventList.tsx index 11a3adb8..00b8ceac 100644 --- a/packages/core/src/integrations/sentry/components/EventList.tsx +++ b/packages/core/src/integrations/sentry/components/EventList.tsx @@ -25,7 +25,7 @@ export default function EventList() { key={e.event_id} to={e.event_id} > - +
{(e.event_id || '').substring(0, 8)} diff --git a/packages/core/src/integrations/sentry/components/PlatformIcon.tsx b/packages/core/src/integrations/sentry/components/PlatformIcon.tsx index aa37f0c9..84fc5fd9 100644 --- a/packages/core/src/integrations/sentry/components/PlatformIcon.tsx +++ b/packages/core/src/integrations/sentry/components/PlatformIcon.tsx @@ -3,20 +3,29 @@ import { ReactComponent as JavaScriptIcon } from 'platformicons/svg/javascript.s import { ReactComponent as NodeIcon } from 'platformicons/svg/nodejs.svg'; import { ReactComponent as PhpIcon } from 'platformicons/svg/php.svg'; import { ReactComponent as PythonIcon } from 'platformicons/svg/python.svg'; +import { ReactComponent as RubyIcon } from 'platformicons/svg/ruby.svg'; + +import { SentryEvent } from '../types'; import { ComponentPropsWithoutRef } from 'react'; -type Platform = 'python' | 'javascript' | 'node' | string; +type Platform = 'python' | 'javascript' | 'node' | 'ruby' | string; export default function PlatformIcon({ platform, + event, size = 42, ...props }: ComponentPropsWithoutRef<'svg'> & { size?: number; platform?: Platform; + event?: SentryEvent; }) { - switch (platform) { + console.log('SDK:', platform, event?.platform); + const name = platform || event?.platform || 'unknown'; + switch (name) { + case 'ruby': + return ; case 'python': return ; case 'javascript': diff --git a/packages/core/src/integrations/sentry/components/SdkList.tsx b/packages/core/src/integrations/sentry/components/SdkList.tsx index 78b07a25..461ff965 100644 --- a/packages/core/src/integrations/sentry/components/SdkList.tsx +++ b/packages/core/src/integrations/sentry/components/SdkList.tsx @@ -3,7 +3,10 @@ import PlatformIcon from './PlatformIcon'; import TimeSince from './TimeSince'; function sdkToPlatform(name: string) { - if (name.indexOf('sentry.javascript') === 0) return 'javascript'; + if (name.indexOf('javascript') === 0) return 'javascript'; + if (name.indexOf('python') === 0) return 'python'; + if (name.indexOf('php') === 0) return 'php'; + if (name.indexOf('ruby') === 0) return 'ruby'; return 'unknown'; } diff --git a/packages/core/src/integrations/sentry/data/sentryDataCache.test.ts b/packages/core/src/integrations/sentry/data/sentryDataCache.test.ts new file mode 100644 index 00000000..f13156d8 --- /dev/null +++ b/packages/core/src/integrations/sentry/data/sentryDataCache.test.ts @@ -0,0 +1,15 @@ +import { describe, expect, test } from 'vitest'; +import { processEnvelope } from '../index'; +import sentryDataCache from './sentryDataCache'; + +import fs from 'fs'; + +describe('SentryDataCache', () => { + // We need to refactor this to make it actually testable + test('Process Envelope', () => { + const envelope = fs.readFileSync('./_fixtures/envelope1.txt', 'utf-8'); + const processedEnvelope = processEnvelope({ data: envelope, contentType: 'test' }); + sentryDataCache.pushEnvelope(processedEnvelope.event); + expect(true).not.toBe(undefined); + }); +}); diff --git a/packages/core/src/integrations/sentry/data/sentryDataCache.ts b/packages/core/src/integrations/sentry/data/sentryDataCache.ts index fce9c53a..d01353ba 100644 --- a/packages/core/src/integrations/sentry/data/sentryDataCache.ts +++ b/packages/core/src/integrations/sentry/data/sentryDataCache.ts @@ -14,6 +14,14 @@ type TraceSubscription = ['trace', (trace: Trace) => void]; type Subscription = OnlineSubscription | EventSubscription | TraceSubscription; +function sdkToPlatform(name: string) { + if (name.indexOf('javascript') !== -1) return 'javascript'; + if (name.indexOf('python') !== -1) return 'python'; + if (name.indexOf('php') !== -1) return 'php'; + if (name.indexOf('ruby') !== -1) return 'ruby'; + return 'unknown'; +} + class SentryDataCache { protected events: SentryEvent[] = []; protected sdks: Sdk[] = []; @@ -30,22 +38,51 @@ class SentryDataCache { initial.forEach(e => this.pushEvent(e)); } + inferSdkFromEvent(event: SentryEvent) { + const sdk: Sdk = { + name: 'unknown', + version: 'unknown', + lastSeen: new Date().getTime(), + }; + + if (event.sdk) { + sdk.name = event.sdk.name || sdk.name; + sdk.version = event.sdk.version || sdk.version; + } else if (event.platform) { + sdk.name = event.platform; + } + + return sdk; + } + pushEnvelope(envelope: Envelope) { const [header, items] = envelope; + let sdk: Sdk; if (header.sdk && header.sdk.name && header.sdk.version) { - const existingSdk = this.sdks.find(s => s.name === header.sdk!.name && s.version === header.sdk!.version); - if (!existingSdk) { - this.sdks.push({ - name: header.sdk.name, - version: header.sdk.version, - lastSeen: new Date(header.sent_at as string).getTime(), - }); - } else { - existingSdk.lastSeen = new Date(header.sent_at as string).getTime(); - } + sdk = { + name: header.sdk.name, + version: header.sdk.version, + lastSeen: new Date(header.sent_at as string).getTime(), + }; + } else { + sdk = this.inferSdkFromEvent(items[0][1] as SentryEvent); } + + const existingSdk = this.sdks.find(s => s.name === sdk!.name && s.version === sdk!.version); + if (!existingSdk) { + this.sdks.push({ + name: sdk.name, + version: sdk.version, + lastSeen: new Date(header.sent_at as string).getTime(), + }); + } else { + existingSdk.lastSeen = new Date(header.sent_at as string).getTime(); + } + items.forEach(([itemHeader, itemData]) => { if (itemHeader.type === 'event' || itemHeader.type === 'transaction') { + console.log(sdkToPlatform(sdk.name)); + (itemData as SentryEvent).platform = sdkToPlatform(sdk.name); this.pushEvent(itemData as SentryEvent); } }); diff --git a/packages/core/src/integrations/sentry/types.ts b/packages/core/src/integrations/sentry/types.ts index d17702d8..66ba004b 100644 --- a/packages/core/src/integrations/sentry/types.ts +++ b/packages/core/src/integrations/sentry/types.ts @@ -59,6 +59,7 @@ type CommonEventAttrs = { contexts?: Contexts; tags?: Tags; extra?: { [key: string]: string | number }; + sdk?: Sdk; }; export type Context = {