> ## Documentation Index
> Fetch the complete documentation index at: https://dashtray.mintlify.app/llms.txt
> Use this file to discover all available pages before exploring further.

# Monitoring setup

# Monitoring and Analytics Setup

Complete guide for setting up monitoring, error tracking, and analytics for Dashtray.

## Overview

This guide covers:

1. Error tracking with Sentry
2. Uptime monitoring
3. Performance monitoring
4. Usage analytics
5. Alert configuration

## 1. Error Tracking (Sentry)

### 1.1 Create Sentry Account

1. Sign up at [sentry.io](https://sentry.io)
2. Create a new organization: "Dashtray"
3. Create a new project:
   * Platform: SvelteKit
   * Name: "dashtray-production"

### 1.2 Install Sentry SDK

```bash  theme={null}
pnpm add @sentry/sveltekit
```

### 1.3 Configure Sentry

Create `src/hooks.client.ts`:

```typescript  theme={null}
import * as Sentry from '@sentry/sveltekit';

Sentry.init({
  dsn: 'https://your-dsn@sentry.io/your-project-id',
  environment: import.meta.env.MODE,

  // Performance monitoring
  tracesSampleRate: 0.1, // 10% of transactions

  // Session replay (optional)
  replaysSessionSampleRate: 0.1,
  replaysOnErrorSampleRate: 1.0,

  // Filter sensitive data
  beforeSend(event) {
    // Remove sensitive data
    if (event.request) {
      delete event.request.cookies;
      delete event.request.headers;
    }
    return event;
  },

  // Ignore certain errors
  ignoreErrors: [
    'ResizeObserver loop limit exceeded',
    'Non-Error promise rejection captured'
  ]
});
```

Create `src/hooks.server.ts`:

```typescript  theme={null}
import * as Sentry from '@sentry/sveltekit';

Sentry.init({
  dsn: 'https://your-dsn@sentry.io/your-project-id',
  environment: import.meta.env.MODE,
  tracesSampleRate: 0.1
});

export const handleError = Sentry.handleErrorWithSentry();
```

### 1.4 Add Sentry to Convex

In Convex functions, log errors to Sentry:

```typescript  theme={null}
// src/convex/lib/errorTracking.ts
export async function logError(
  error: Error,
  context: {
    userId?: string;
    projectId?: string;
    action?: string;
  }
) {
  // Log to console
  console.error('Error:', error.message, context);

  // In production, send to Sentry via HTTP
  if (process.env.NODE_ENV === 'production') {
    try {
      await fetch('https://sentry.io/api/your-project/store/', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'X-Sentry-Auth': `Sentry sentry_key=your-key`
        },
        body: JSON.stringify({
          message: error.message,
          level: 'error',
          extra: context
        })
      });
    } catch (e) {
      // Fail silently
    }
  }
}
```

### 1.5 Configure Alerts

In Sentry dashboard:

1. Go to Alerts → Create Alert
2. Configure alert rules:
   * **High error rate**: > 10 errors in 5 minutes
   * **New error**: First occurrence of an error
   * **Regression**: Error that was resolved returns
3. Set notification channels:
   * Email
   * Slack
   * PagerDuty (for critical alerts)

### 1.6 Set Up Releases

Track deployments in Sentry:

```bash  theme={null}
# Install Sentry CLI
pnpm add -D @sentry/cli

# Create release
npx sentry-cli releases new $(git rev-parse HEAD)
npx sentry-cli releases set-commits $(git rev-parse HEAD) --auto
npx sentry-cli releases finalize $(git rev-parse HEAD)
```

Add to CI/CD pipeline:

```yaml  theme={null}
# .github/workflows/deploy.yml
- name: Create Sentry release
  run: |
    npx sentry-cli releases new ${{ github.sha }}
    npx sentry-cli releases set-commits ${{ github.sha }} --auto
    npx sentry-cli releases finalize ${{ github.sha }}
  env:
    SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
    SENTRY_ORG: dashtray
    SENTRY_PROJECT: dashtray-production
```

## 2. Uptime Monitoring

### 2.1 UptimeRobot (Free)

1. Sign up at [uptimerobot.com](https://uptimerobot.com)
2. Create monitors:

**Main Site**:

* Type: HTTPS
* URL: `https://dashtray.com`
* Interval: 5 minutes
* Alert contacts: Email, Slack

**API Health Check**:

* Type: HTTPS
* URL: `https://dashtray.com/api/health`
* Interval: 5 minutes
* Alert contacts: Email, Slack

**Convex Backend**:

* Type: HTTPS
* URL: `https://your-deployment.convex.site/api/health`
* Interval: 5 minutes
* Alert contacts: Email, Slack

### 2.2 Create Health Check Endpoint

```typescript  theme={null}
// src/routes/api/health/+server.ts
import { json } from '@sveltejs/kit';
import type { RequestHandler } from './$types';

export const GET: RequestHandler = async () => {
  try {
    // Check Convex connection
    // Check database
    // Check critical services

    return json({
      status: 'healthy',
      timestamp: new Date().toISOString(),
      version: process.env.VERSION || 'unknown'
    });
  } catch (error) {
    return json(
      {
        status: 'unhealthy',
        error: error instanceof Error ? error.message : 'Unknown error'
      },
      { status: 503 }
    );
  }
};
```

### 2.3 Configure Alerts

In UptimeRobot:

1. Go to Alert Contacts
2. Add contacts:
   * Email: [ops@dashtray.com](mailto:ops@dashtray.com)
   * Slack webhook
   * SMS (for critical alerts)
3. Set alert thresholds:
   * Alert after: 2 failed checks
   * Alert frequency: Every 5 minutes until resolved

## 3. Performance Monitoring

### 3.1 Convex Dashboard

1. Go to [Convex Dashboard](https://dashboard.convex.dev)
2. Select your production deployment
3. Monitor:
   * Function execution times
   * Database query performance
   * Cron job status
   * Error rates

### 3.2 Set Up Convex Alerts

In Convex dashboard:

1. Go to Settings → Alerts
2. Configure alerts:
   * Function duration > 5s
   * Database query time > 1s
   * Error rate > 1%
   * Cron job failures

### 3.3 Cloudflare Analytics

1. Go to Cloudflare Pages dashboard
2. View analytics:
   * Page views
   * Unique visitors
   * Bandwidth usage
   * Response times
   * Error rates (4xx, 5xx)

### 3.4 Web Vitals Monitoring

Add Web Vitals tracking:

```typescript  theme={null}
// src/lib/analytics/webVitals.ts
import { onCLS, onFID, onLCP, onFCP, onTTFB } from 'web-vitals';

function sendToAnalytics(metric: any) {
  // Send to your analytics service
  if (import.meta.env.PROD) {
    fetch('/api/analytics/vitals', {
      method: 'POST',
      body: JSON.stringify(metric),
      headers: { 'Content-Type': 'application/json' }
    });
  }
}

export function initWebVitals() {
  onCLS(sendToAnalytics);
  onFID(sendToAnalytics);
  onLCP(sendToAnalytics);
  onFCP(sendToAnalytics);
  onTTFB(sendToAnalytics);
}
```

Use in `src/routes/+layout.svelte`:

```svelte  theme={null}
<script lang="ts">
  import { onMount } from 'svelte';
  import { initWebVitals } from '$lib/analytics/webVitals';

  onMount(() => {
    initWebVitals();
  });
</script>
```

## 4. Usage Analytics

### 4.1 Plausible Analytics (Privacy-Friendly)

1. Sign up at [plausible.io](https://plausible.io)
2. Add your domain: `dashtray.com`
3. Get tracking script

Add to `src/app.html`:

```html  theme={null}
<script defer data-domain="dashtray.com" src="https://plausible.io/js/script.js"></script>
```

### 4.2 Track Custom Events

```typescript  theme={null}
// src/lib/analytics/plausible.ts
export function trackEvent(eventName: string, props?: Record<string, any>) {
  if (typeof window !== 'undefined' && (window as any).plausible) {
    (window as any).plausible(eventName, { props });
  }
}
```

Track important events:

```typescript  theme={null}
// User signs up
trackEvent('signup', { method: 'email' });

// User connects integration
trackEvent('integration_connected', { service: 'stripe' });

// User upgrades
trackEvent('subscription_upgrade', { tier: 'pro' });

// User creates dashboard
trackEvent('dashboard_created', { type: 'custom' });
```

### 4.3 Convex Usage Tracking

Track usage in Convex:

```typescript  theme={null}
// src/convex/analytics.ts
import { mutation } from './_generated/server';
import { v } from 'convex/values';

export const trackEvent = mutation({
  args: {
    event: v.string(),
    properties: v.optional(v.any())
  },
  handler: async (ctx, args) => {
    const userId = await getCurrentUserId(ctx);

    await ctx.db.insert('analyticsEvents', {
      userId,
      event: args.event,
      properties: args.properties,
      timestamp: Date.now()
    });
  }
});
```

## 5. Business Metrics Dashboard

### 5.1 Key Metrics to Track

**User Metrics**:

* Total users
* Active users (DAU, WAU, MAU)
* New signups per day
* Churn rate
* User retention

**Revenue Metrics**:

* MRR (Monthly Recurring Revenue)
* ARR (Annual Recurring Revenue)
* ARPU (Average Revenue Per User)
* Conversion rate (Free → Paid)
* Churn rate

**Product Metrics**:

* Integrations connected per user
* Dashboards created per user
* Alerts created per user
* API usage (Scale+ users)
* Feature adoption rates

**Technical Metrics**:

* Error rate
* Response time (p50, p95, p99)
* Uptime percentage
* Database query performance
* Function execution time

### 5.2 Create Analytics Dashboard

Use Convex queries to aggregate metrics:

```typescript  theme={null}
// src/convex/analytics.ts
export const getMetrics = query({
  handler: async (ctx) => {
    const now = Date.now();
    const thirtyDaysAgo = now - 30 * 24 * 60 * 60 * 1000;

    // Total users
    const totalUsers = await ctx.db.query('users').collect();

    // Active users (last 30 days)
    const activeUsers = totalUsers.filter(
      user => user.lastActiveAt && user.lastActiveAt > thirtyDaysAgo
    );

    // New signups (last 30 days)
    const newSignups = totalUsers.filter(
      user => user.createdAt > thirtyDaysAgo
    );

    // Total projects
    const projects = await ctx.db.query('projects').collect();

    // Active subscriptions
    const activeSubscriptions = projects.filter(
      p => p.subscriptionStatus === 'active' && p.subscriptionTier !== 'free'
    );

    // Calculate MRR
    const mrr = activeSubscriptions.reduce((sum, project) => {
      const tierPrices = { pro: 69, scale: 199, agency: 599 };
      return sum + (tierPrices[project.subscriptionTier] || 0);
    }, 0);

    return {
      users: {
        total: totalUsers.length,
        active: activeUsers.length,
        new: newSignups.length
      },
      revenue: {
        mrr,
        arr: mrr * 12,
        activeSubscriptions: activeSubscriptions.length
      },
      projects: {
        total: projects.length,
        free: projects.filter(p => p.subscriptionTier === 'free').length,
        paid: activeSubscriptions.length
      }
    };
  }
});
```

### 5.3 Visualize Metrics

Create an internal admin dashboard:

```svelte  theme={null}
<!-- src/routes/(admin)/admin/metrics/+page.svelte -->
<script lang="ts">
  import { useQuery } from 'convex-svelte';
  import { api } from '$convex/_generated/api';

  const metrics = useQuery(api.analytics.getMetrics);
</script>

{#if $metrics}
  <div class="grid grid-cols-3 gap-4">
    <div class="card">
      <h3>Total Users</h3>
      <p class="text-4xl">{$metrics.users.total}</p>
      <p class="text-sm text-gray-600">
        {$metrics.users.new} new this month
      </p>
    </div>

    <div class="card">
      <h3>MRR</h3>
      <p class="text-4xl">${$metrics.revenue.mrr.toLocaleString()}</p>
      <p class="text-sm text-gray-600">
        {$metrics.revenue.activeSubscriptions} active subscriptions
      </p>
    </div>

    <div class="card">
      <h3>Projects</h3>
      <p class="text-4xl">{$metrics.projects.total}</p>
      <p class="text-sm text-gray-600">
        {$metrics.projects.paid} paid
      </p>
    </div>
  </div>
{/if}
```

## 6. Log Aggregation

### 6.1 Convex Logs

View logs in real-time:

```bash  theme={null}
# Tail production logs
npx convex logs --prod --tail

# Filter by function
npx convex logs --prod --function=projects:create

# Filter by level
npx convex logs --prod --level=error
```

### 6.2 Structured Logging

Use structured logging in Convex:

```typescript  theme={null}
// src/convex/lib/logger.ts
export function log(
  level: 'info' | 'warn' | 'error',
  message: string,
  context?: Record<string, any>
) {
  const logEntry = {
    level,
    message,
    timestamp: new Date().toISOString(),
    ...context
  };

  console.log(JSON.stringify(logEntry));
}

// Usage
log('info', 'User signed up', { userId: 'user_123', method: 'email' });
log('error', 'Failed to sync metrics', { connectionId: 'conn_456', error: 'API timeout' });
```

## 7. Alert Configuration

### 7.1 Critical Alerts (PagerDuty)

For critical issues that require immediate attention:

1. Sign up at [pagerduty.com](https://pagerduty.com)
2. Create service: "Dashtray Production"
3. Set up escalation policy
4. Integrate with Sentry and UptimeRobot

**Critical alerts**:

* Site down (> 5 minutes)
* Error rate > 5%
* Payment processing failures
* Database connection failures

### 7.2 Warning Alerts (Slack)

For issues that need attention but aren't critical:

1. Create Slack channel: `#dashtray-alerts`
2. Add incoming webhook
3. Configure integrations to post to Slack

**Warning alerts**:

* Error rate > 1%
* Response time > 2s
* Webhook failures
* Sync failures
* Low disk space

### 7.3 Info Alerts (Email)

For informational notifications:

**Info alerts**:

* Daily metrics summary
* Weekly usage report
* Monthly revenue report
* New user signups (digest)

## 8. Status Page

### 8.1 Create Status Page

Use [statuspage.io](https://statuspage.io) or self-host:

1. Create status page: `status.dashtray.com`
2. Add components:
   * Website
   * API
   * Integrations
   * Payments
3. Configure automated updates from UptimeRobot

### 8.2 Incident Management

When incidents occur:

1. **Detect**: Monitoring alerts
2. **Acknowledge**: Team member acknowledges
3. **Investigate**: Diagnose the issue
4. **Update status page**: Keep users informed
5. **Resolve**: Fix the issue
6. **Post-mortem**: Document and learn

## 9. Monitoring Checklist

### Daily

* [ ] Check error rates in Sentry
* [ ] Review Convex logs for errors
* [ ] Check uptime status
* [ ] Monitor response times
* [ ] Review user feedback

### Weekly

* [ ] Review performance trends
* [ ] Check for slow queries
* [ ] Review security alerts
* [ ] Analyze usage patterns
* [ ] Check for dependency updates

### Monthly

* [ ] Review all metrics
* [ ] Analyze user growth
* [ ] Review revenue metrics
* [ ] Check infrastructure costs
* [ ] Plan optimizations

## 10. Dashboards

### 10.1 Operations Dashboard

Create a dashboard with:

* Current error rate
* Response times (p50, p95, p99)
* Active users
* Recent errors
* System health

### 10.2 Business Dashboard

Create a dashboard with:

* MRR/ARR
* User growth
* Conversion rates
* Churn rate
* Feature adoption

### 10.3 Technical Dashboard

Create a dashboard with:

* Function execution times
* Database query performance
* API usage
* Webhook success rates
* Integration health

## Need Help?

* Sentry Docs: [docs.sentry.io](https://docs.sentry.io)
* UptimeRobot Docs: [uptimerobot.com/help](https://uptimerobot.com/help)
* Convex Monitoring: [docs.convex.dev/production/monitoring](https://docs.convex.dev/production/monitoring)
* Cloudflare Analytics: [developers.cloudflare.com/analytics](https://developers.cloudflare.com/analytics)


Built with [Mintlify](https://mintlify.com).