Claude-code-plugins-plus-skills sentry-architecture-variants
git clone https://github.com/jeremylongshore/claude-code-plugins-plus-skills
T=$(mktemp -d) && git clone --depth=1 https://github.com/jeremylongshore/claude-code-plugins-plus-skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/plugins/saas-packs/sentry-pack/skills/sentry-architecture-variants" ~/.claude/skills/jeremylongshore-claude-code-plugins-plus-skills-sentry-architecture-variants && rm -rf "$T"
plugins/saas-packs/sentry-pack/skills/sentry-architecture-variants/SKILL.mdSentry Architecture Variants
Overview
Choose the right Sentry SDK, project layout, and tracing strategy for each application architecture. Every pattern below uses Sentry SDK v8 APIs —
@sentry/node, @sentry/browser, @sentry/react, @sentry/react-native,
@sentry/aws-serverless, and @sentry/google-cloud-serverless. The goal is
one coherent trace from the user's device through every backend hop, regardless
of how many runtimes or deployment targets sit in between.
Deep-dive references for each pattern: Monolith | Microservices | Serverless | Event-driven | Frontend SPA | Mobile | Hybrid | Errors
Prerequisites
- Node.js 18+ (or target platform runtime)
- Sentry organization with at least one project created at sentry.io
available as an environment variable (one per Sentry project)SENTRY_DSN- Application architecture documented — service inventory, deployment targets, team ownership mapped
- For distributed tracing: all inter-service transports identified (HTTP, gRPC, Kafka, SQS)
Instructions
Step 1 — Identify Your Architecture and Select SDK Packages
Map every runtime in your system to the correct Sentry SDK package and project layout.
| Architecture | SDK Package | Sentry Projects | Key Integration |
|---|---|---|---|
| Monolith | | 1 project, env tags | Module tags + ownership rules |
| Microservices | (per service) | 1 project per service | Distributed tracing via headers |
| Serverless (Lambda) | | 1 per function group | + auto-flush |
| Serverless (GCP) | | 1 per function group | |
| Event-driven (Kafka/SQS) | | 1 per consumer group | from message headers |
| Frontend SPA | or | 1 frontend project | |
| Mobile (React Native) | | 1 mobile project | Native crash reporting + JS errors |
| Hybrid | Mix of above | 1 per deployment target | Cross-platform trace correlation |
Install the SDK for your architecture:
# Monolith / Microservices / Event-driven npm install @sentry/node @sentry/profiling-node # Serverless — AWS Lambda npm install @sentry/aws-serverless # Serverless — Google Cloud Functions npm install @sentry/google-cloud-serverless # Frontend SPA (React) npm install @sentry/react # Mobile — React Native npx @sentry/wizard@latest -i reactNative
Step 2 — Initialize Sentry for Each Architecture Pattern
Monolith — Single Project, Module Tags
One DSN, one project. Separate concerns with module tags and team ownership rules.
// instrument.mjs — load via: node --import ./instrument.mjs app.js import * as Sentry from '@sentry/node'; Sentry.init({ dsn: process.env.SENTRY_DSN, environment: process.env.NODE_ENV, release: process.env.APP_VERSION, tracesSampleRate: 0.1, initialScope: { tags: { app: 'monolith' } }, }); // Tag errors by module so each team sees only their issues function captureModuleError(module: string, error: Error) { Sentry.withScope((scope) => { scope.setTag('module', module); scope.setTag('team', getTeamForModule(module)); Sentry.captureException(error); }); } // Module-based breadcrumbs for traceability Sentry.addBreadcrumb({ category: 'auth', message: 'Login attempt', level: 'info' }); captureModuleError('auth', new Error('Token expired')); // Dashboard ownership: tags.module:auth → #platform-team
Microservices — Project-per-Service, Distributed Tracing
Each service gets its own Sentry project. A shared config package keeps init consistent.
// packages/sentry-config/index.ts — shared across all services import * as Sentry from '@sentry/node'; export function initServiceSentry(serviceName: string) { Sentry.init({ dsn: process.env.SENTRY_DSN, environment: process.env.NODE_ENV, release: `${serviceName}@${process.env.APP_VERSION}`, serverName: serviceName, tracesSampleRate: 0.1, sendDefaultPii: false, initialScope: { tags: { service: serviceName, cluster: process.env.K8S_CLUSTER || 'default', namespace: process.env.K8S_NAMESPACE || 'default', }, }, }); } // Usage: initServiceSentry('api-gateway');
HTTP tracing works automatically — SDK v8 propagates
sentry-trace and baggage headers on all outbound HTTP requests. For service mesh (Istio/Linkerd), headers pass through transparently. For non-HTTP transports (gRPC, message queues), see event-driven pattern below and microservices deep-dive.
Serverless — Lambda and Cloud Functions
Serverless SDKs wrap your handler to auto-capture errors and flush events before the runtime freezes.
// AWS Lambda — handler.ts import * as Sentry from '@sentry/aws-serverless'; Sentry.init({ dsn: process.env.SENTRY_DSN, environment: process.env.STAGE, tracesSampleRate: 0.1, }); export const handler = Sentry.wrapHandler(async (event, context) => { Sentry.setTag('function', context.functionName); Sentry.setTag('region', process.env.AWS_REGION); // Track cold starts const isColdStart = !global.__sentryWarm; global.__sentryWarm = true; Sentry.setTag('cold_start', String(isColdStart)); const result = await processRequest(event); return { statusCode: 200, body: JSON.stringify(result) }; }); // wrapHandler auto-calls flush() — do NOT call it yourself (double-flush causes timeout)
// Google Cloud Functions — index.ts import * as Sentry from '@sentry/google-cloud-serverless'; Sentry.init({ dsn: process.env.SENTRY_DSN, tracesSampleRate: 0.1 }); export const httpHandler = Sentry.wrapHttpFunction(async (req, res) => { res.json(await processRequest(req.body)); }); export const eventHandler = Sentry.wrapCloudEventFunction(async (event) => { await processEvent(event.data); });
Event-Driven — Kafka, SQS, and Message Queues
Propagate trace context through message headers so consumer spans connect to producer traces.
import * as Sentry from '@sentry/node'; // Producer: embed trace context in message headers async function publishToKafka(topic: string, payload: object) { const activeSpan = Sentry.getActiveSpan(); const headers: Record<string, string> = {}; if (activeSpan) { headers['sentry-trace'] = Sentry.spanToTraceHeader(activeSpan); headers['baggage'] = Sentry.spanToBaggageHeader(activeSpan) || ''; } await Sentry.startSpan( { name: `kafka.produce.${topic}`, op: 'queue.publish' }, () => kafka.send({ topic, messages: [{ value: JSON.stringify(payload), headers }] }) ); } // Consumer: continue the producer's trace async function consumeFromKafka(message: KafkaMessage) { const headers = message.headers || {}; Sentry.continueTrace( { sentryTrace: headers['sentry-trace']?.toString(), // Buffer → string baggage: headers['baggage']?.toString(), }, () => { Sentry.startSpan( { name: `kafka.consume.${message.topic}`, op: 'queue.process' }, async (span) => { try { await processMessage(message); span.setStatus({ code: 1 }); } catch (error) { span.setStatus({ code: 2, message: 'consumer_error' }); Sentry.captureException(error); throw error; } } ); } ); }
For SQS consumers on Lambda, see event-driven deep-dive.
Frontend SPA — Browser and React
import * as Sentry from '@sentry/react'; Sentry.init({ dsn: process.env.REACT_APP_SENTRY_DSN, release: process.env.REACT_APP_VERSION, tracesSampleRate: 0.1, replaysOnErrorSampleRate: 1.0, integrations: [ Sentry.browserTracingIntegration(), Sentry.replayIntegration({ maskAllText: true, blockAllMedia: true }), ], // Must match your API domain or frontend-to-backend traces break tracePropagationTargets: ['localhost', /^https:\/\/api\.yourapp\.com/], });
Route-based transactions, error boundaries, and session replay configuration: see frontend SPA deep-dive.
Mobile — React Native
import * as Sentry from '@sentry/react-native'; Sentry.init({ dsn: process.env.SENTRY_DSN, tracesSampleRate: 0.2, integrations: [ Sentry.reactNativeTracingIntegration({ routingInstrumentation: Sentry.reactNavigationIntegration(), }), ], tracePropagationTargets: [/^https:\/\/api\.yourapp\.com/], enableNativeCrashHandling: true, attachScreenshot: true, attachViewHierarchy: true, }); export default Sentry.wrap(App); // Upload source maps + dSYMs in CI — see mobile deep-dive
Full navigation instrumentation and CI upload commands: see mobile deep-dive.
Step 3 — Wire Up Hybrid and Cross-Platform Tracing
For systems that span multiple architectures, connect traces end-to-end. The trace flow for a typical hybrid system:
creates a transaction on user click@sentry/react- Browser SDK adds
+sentry-trace
headers tobaggagefetch() - API gateway (
) auto-continues the trace@sentry/node - API gateway calls payment-service — headers propagate via HTTP
- payment-service publishes to Kafka — headers injected manually (see event-driven pattern)
- Worker (
) continues trace from Kafka headers@sentry/node
Result: single trace ID visible across all services in Sentry Trace View. Backend-to-frontend correlation requires
tracePropagationTargets in the browser SDK matching your API domains. Without this, the browser SDK will not attach trace headers and traces break at the browser-to-server boundary. See hybrid deep-dive.
Architecture decision matrix:
| Architecture | Projects | Tracing Strategy | SDK Flush | Key Gotcha |
|---|---|---|---|---|
| Monolith | 1 | Single-service spans | Automatic | Module tag cardinality — keep under 50 |
| Microservices | 1 per service | Distributed via HTTP headers | Automatic | Missing breaks sampling |
| Serverless | 1 per function group | Per-invocation, auto-flush | | Double-flush causes timeout |
| Event-driven | 1 per consumer group | from headers | Manual periodic | DLQ needs separate error capture |
| Frontend SPA | 1 | | Automatic (beacon) | required |
| Mobile | 1 | | Automatic | Source maps + dSYMs required |
| Hybrid | Mix of above | End-to-end header propagation | Per-component | One missing link breaks whole trace |
Output
After applying the appropriate pattern, you will have:
- Architecture-specific
configuration with correct SDK packageSentry.init() - Distributed tracing connected across all services (HTTP, gRPC, and message queues)
- Serverless handlers wrapped with automatic error capture and event flushing
- Event-driven consumers that continue producer traces via message headers
- Frontend SPA with route-based transactions, session replay, and backend trace correlation
- Mobile app with native crash reporting, screenshot capture, and navigation tracing
- Hybrid systems with end-to-end trace visibility from browser/mobile through every backend hop
Error Handling
| Error | Cause | Solution |
|---|---|---|
| Distributed traces broken | Missing header propagation | Verify AND headers in every inter-service call |
| Lambda events lost after timeout | Calling inside | Remove manual — auto-flushes |
| Kafka consumer traces disconnected | Headers not serialized as strings | Call on Kafka message headers before |
| SPA traces stop at API boundary | missing | Add API domain regex to browser SDK init |
| React Native traces unreadable | Missing source maps / dSYMs | Run and in CI |
| Multi-tenant data leakage | at global scope | Use per request — global tags persist across requests |
| Worker events silently dropped | No periodic flush | Add |
| High cardinality alert | Dynamic values in span names | Use parameterized names: not |
See also: Full error reference
Examples
Example 1 — Monolith with 5 teams: Request: "Set up Sentry for a monolith with auth, billing, inventory, shipping, and analytics modules." Result: Single Sentry project with
module and team tags. Each team filters issues via tags.module:billing. Ownership rules route alerts to the correct Slack channel.
Example 2 — Microservices with Kafka: Request: "Configure Sentry for 12 microservices communicating via REST and Kafka." Result: 12 Sentry projects with shared
initServiceSentry(). HTTP traces auto-propagate. Kafka producers inject sentry-trace/baggage into headers. Consumers call continueTrace(). Trace view: api-gateway -> order-service -> [kafka] -> fulfillment-worker.
Example 3 — Serverless API on Lambda: Request: "Add Sentry to 8 AWS Lambda functions behind API Gateway." Result: One Sentry project. Each handler wrapped with
Sentry.wrapHandler(). Cold starts tagged. No manual flush() calls.
Example 4 — React SPA + Node API: Request: "Full-stack Sentry for a React frontend calling a Node.js Express API." Result: Two projects (frontend + backend). React uses
@sentry/react with browserTracingIntegration() and replayIntegration(). tracePropagationTargets connects frontend to backend traces.
See also: Full examples
Resources
- Node.js SDK Guide
- AWS Lambda Guide
- Google Cloud Functions Guide
- React SDK Guide
- React Native SDK Guide
- Distributed Tracing
- Session Replay
- Performance Monitoring
Next Steps
- Run the
skill to optimizesentry-performance-tuning
andtracesSampleRate
for production traffic volumestracesSampler - Use
to set rate limits and event budgets per projectsentry-cost-tuning - Configure
to tie releases to deploys for regression detectionsentry-deploy-integration - Set up
to manage DSN routing across staging/productionsentry-multi-env-setup - Apply
for retry logic and circuit breakers around Sentry callssentry-reliability-patterns