Source:
ocean/docs/sentry-performance-monitoring.md| ✏️ Edit on GitHub
Sentry Performance Monitoring Guide
This guide covers the enhanced Sentry performance monitoring implementation in the Ocean application, focusing on tracking critical user journeys and business operations.
Overview
Our Sentry integration tracks performance metrics for:
- Authentication flows (login, signup, OTP verification)
- GraphQL operations (queries and mutations)
- Core data operations (organizations, members, billing)
- Stripe subscription management
- Webhook processing
Frontend Performance Monitoring
1. Performance Monitoring Utilities
The core utilities are in /src/lib/performance-monitoring.ts:
import { PerformanceMonitor } from '@/lib/performance-monitoring'
// Start a transaction
const transactionId = PerformanceMonitor.startOperation('auth.login', {
description: 'User login via passwordless',
data: { method: 'passwordless' },
})
// End the transaction
PerformanceMonitor.endOperation(transactionId, {
status: 'success',
data: { userId: user.id },
})
2. Authentication Monitoring
All authentication operations are automatically tracked:
- Login: Tracks passwordless login duration and success/failure
- Signup: Monitors new user registration performance
- OTP Verification: Measures OTP code verification time
- Session Refresh: Tracks JWT token refresh operations
3. GraphQL Operation Tracking
GraphQL queries and mutations are automatically instrumented:
// Automatically tracked in useGraphQLQuery and useGraphQLMutation hooks
const { data } = useGraphQLQuery('myQuery', QUERY, variables)
Each GraphQL operation tracks:
- Operation name and type (query/mutation)
- Variables count and content
- Success/error status
- Network latency
- Cache hit/miss status
4. Data Operation Monitoring
Core data operations are tracked with semantic names:
data.fetch: Loading lists (organizations, members)data.create: Creating new resourcesdata.update: Updating existing resourcesdata.delete: Deleting resources
5. Stripe Operations
Subscription management operations are monitored:
stripe.checkout: Creating checkout sessionsstripe.subscription.update: Subscription changes (upgrade/downgrade/cancel)stripe.webhook: Webhook event processing
Backend Performance Monitoring (Edge Functions)
1. Webhook Processing
The Stripe webhook handler tracks:
- Event processing duration by event type
- Success/failure rates
- Organization update performance
2. Observability Configuration
Edge Functions use the shared observability module:
import { initSentry, Logger, trackOperation } from '../_shared/observability.ts'
// Initialize at function start
initSentry('function-name')
// Track operations
await trackOperation('operation_name', async () => {
// Your operation code
})
Performance Thresholds and Alerts
Automatic Alerts
Operations exceeding these thresholds trigger warnings:
- 3 seconds: Slow operation warning
- 10 seconds: Critical performance issue
Custom Metrics
The system tracks:
- Operation duration histograms
- Success/failure counters
- Error rates by operation type
Cost Optimization
Sampling Rates
To control costs, we use intelligent sampling:
- Production: 10% transaction sampling
- Development: 100% transaction sampling
- Session Replays: 1% normally, 100% on error
Filtering
Noise reduction filters exclude:
- Browser extension errors
- Network connectivity issues
- Expected validation errors
- Health check endpoints
Environment Variables
Frontend
VITE_SENTRY_DSN: Frontend Sentry DSNSENTRY_ORG: Organization for source mapsSENTRY_PROJECT: Project for source mapsSENTRY_AUTH_TOKEN: Auth token for builds
Edge Functions
EDGE_FUNCTION_SENTRY_DSNorSENTRY_DSN: Backend Sentry DSNENVIRONMENT: Current environment (development/staging/production)
Usage Examples
Track a Custom Operation
import { PerformanceMonitor } from '@/lib/performance-monitoring'
// Option 1: Manual tracking
const transactionId = PerformanceMonitor.startOperation('report.generate', {
description: 'Generating monthly report',
data: { reportType: 'monthly', format: 'pdf' },
})
try {
const report = await generateReport()
PerformanceMonitor.endOperation(transactionId, {
status: 'success',
data: { pageCount: report.pages },
})
} catch (error) {
PerformanceMonitor.endOperation(transactionId, {
status: 'error',
error,
})
}
// Option 2: Async wrapper
const report = await PerformanceMonitor.trackAsyncOperation(
'report.generate',
() => generateReport(),
{
description: 'Generating monthly report',
data: { reportType: 'monthly' },
}
)
Track Nested Operations
const parentId = PerformanceMonitor.startOperation('data.fetch')
// Create child spans
const childSpan = PerformanceMonitor.createSpan('database_query', 'db.query', {
table: 'organizations',
})
// Perform operation
const data = await queryDatabase()
// End child span
childSpan?.end()
// End parent
PerformanceMonitor.endOperation(parentId, { status: 'success' })
Best Practices
- Semantic Naming: Use the predefined operation types for consistency
- Include Context: Add relevant data (IDs, counts, status) to operations
- Error Handling: Always capture errors with proper context
- Avoid PII: Never include personal information in tracking data
- Batch Operations: Track batch operations with item counts
Monitoring Dashboard
Access performance data in Sentry:
- Navigate to Performance → Transactions
- Filter by operation type or name
- Analyze P50, P75, P95 latencies
- Identify slow operations and bottlenecks
- Set up custom alerts for critical paths
Future Enhancements
Planned improvements include:
- Real User Monitoring (RUM) integration
- Custom performance budgets
- Automated performance regression detection
- Enhanced GraphQL field-level tracking
- Database query performance tracking