downgraded to php 8.3 so it works on host
This commit is contained in:
@@ -0,0 +1,939 @@
|
||||
# Analytics Platform - HOWTO Guide
|
||||
|
||||
## Table of Contents
|
||||
1. [What is This Project?](#what-is-this-project)
|
||||
2. [Features Overview](#features-overview)
|
||||
3. [Architecture](#architecture)
|
||||
4. [Installation](#installation)
|
||||
5. [Configuration](#configuration)
|
||||
6. [Required Background Tasks](#required-background-tasks)
|
||||
7. [Tracking Setup](#tracking-setup)
|
||||
8. [How It Works](#how-it-works)
|
||||
9. [Database Structure](#database-structure)
|
||||
10. [Artisan Commands](#artisan-commands)
|
||||
11. [API Documentation](#api-documentation)
|
||||
12. [Maintenance](#maintenance)
|
||||
|
||||
---
|
||||
|
||||
## What is This Project?
|
||||
|
||||
This is a **self-hosted web analytics platform** built with Laravel 11. It provides privacy-focused website analytics similar to Google Analytics or Plausible, allowing you to track visitor behavior, conversions, and engagement on your websites without relying on third-party services.
|
||||
|
||||
### Key Capabilities
|
||||
- Real-time visitor tracking
|
||||
- Goal and conversion tracking
|
||||
- Custom event tracking
|
||||
- Funnel analysis
|
||||
- Automated alerts and notifications
|
||||
- Custom dashboards
|
||||
- Export analytics data
|
||||
- API access for integrations
|
||||
|
||||
---
|
||||
|
||||
## Features Overview
|
||||
|
||||
### 1. **Visitor Tracking**
|
||||
- Automatic page view tracking
|
||||
- Session management (30-minute timeout)
|
||||
- Device, browser, and OS detection
|
||||
- Geolocation (country, region, city)
|
||||
- Bot filtering
|
||||
- UTM parameter tracking (campaign, source, medium, etc.)
|
||||
- Time on page measurement
|
||||
|
||||
### 2. **Analytics Reports**
|
||||
- **Audience**: Geographic distribution, technology breakdown, languages
|
||||
- **Acquisition**: Traffic sources, referrers, campaigns
|
||||
- **Behavior**: Popular pages, landing pages, exit pages
|
||||
- **Events**: Custom event tracking with categories and labels
|
||||
- **Conversions**: Goal completions with revenue tracking
|
||||
|
||||
### 3. **Goals (4 Types)**
|
||||
- **URL Destination**: Track when users visit specific pages
|
||||
- **Event Match**: Track custom events
|
||||
- **Duration**: Sessions longer than X seconds
|
||||
- **Pages Per Session**: Sessions with X or more pages
|
||||
|
||||
### 4. **Advanced Features**
|
||||
- **Funnels**: Multi-step conversion tracking
|
||||
- **Segments**: Custom visitor segments for filtered reporting
|
||||
- **Alerts**: Automated notifications when metrics exceed thresholds
|
||||
- **Annotations**: Add notes to specific dates for context
|
||||
- **Custom Dashboards**: Drag-and-drop widget management
|
||||
|
||||
### 5. **Data Management**
|
||||
- Automatic daily aggregation for performance
|
||||
- Configurable data retention (default: 365 days)
|
||||
- CSV export
|
||||
- API access with token authentication
|
||||
|
||||
---
|
||||
|
||||
## Architecture
|
||||
|
||||
### Technology Stack
|
||||
- **Backend**: Laravel 11, PHP 8.2+
|
||||
- **Frontend**: Blade templates, Alpine.js, Tailwind CSS
|
||||
- **Database**: SQLite (default), MySQL/PostgreSQL compatible
|
||||
- **Queue System**: Database-backed (Redis/SQS optional)
|
||||
- **Build Tool**: Vite
|
||||
|
||||
### Data Flow
|
||||
|
||||
```
|
||||
Client Website (tracking script)
|
||||
↓ POST /api/collect
|
||||
CollectController (validates & queues)
|
||||
↓ Queue Job
|
||||
ProcessTrackingPayload (processes data)
|
||||
↓ Stores in DB
|
||||
Raw Tables (visitors, sessions, page_views, events)
|
||||
↓ Daily aggregation (02:00 AM)
|
||||
Aggregated Tables (daily_aggregates, page_daily_aggregates)
|
||||
↓ Used by
|
||||
Dashboard & Reports (hybrid: aggregates + real-time)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Installation
|
||||
|
||||
### Development Setup
|
||||
|
||||
```bash
|
||||
# Clone the repository
|
||||
cd /path/to/analytics
|
||||
|
||||
# Install dependencies and setup
|
||||
composer setup
|
||||
|
||||
# This runs:
|
||||
# - composer install
|
||||
# - Creates .env from .env.example
|
||||
# - php artisan key:generate
|
||||
# - php artisan migrate --force
|
||||
# - npm install
|
||||
# - npm run build
|
||||
|
||||
# Start development environment (runs 4 processes)
|
||||
composer run dev
|
||||
```
|
||||
|
||||
This starts:
|
||||
- Web server: `http://localhost:8000`
|
||||
- Queue worker (processes tracking data)
|
||||
- Log viewer (Pail)
|
||||
- Vite dev server (hot module reload)
|
||||
|
||||
### Production Setup
|
||||
|
||||
```bash
|
||||
# Install dependencies
|
||||
composer install --no-dev --optimize-autoloader
|
||||
|
||||
# Generate application key
|
||||
php artisan key:generate
|
||||
|
||||
# Run database migrations
|
||||
php artisan migrate --force
|
||||
|
||||
# Build frontend assets
|
||||
npm ci
|
||||
npm run build
|
||||
|
||||
# Set proper permissions
|
||||
chmod -R 755 storage bootstrap/cache
|
||||
chown -R www-data:www-data storage bootstrap/cache
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Configuration
|
||||
|
||||
### Environment Variables
|
||||
|
||||
Copy `.env.example` to `.env` and configure:
|
||||
|
||||
```env
|
||||
# Application
|
||||
APP_NAME="Analytics Platform"
|
||||
APP_ENV=production
|
||||
APP_DEBUG=false
|
||||
APP_URL=https://yourdomain.com
|
||||
|
||||
# Database
|
||||
DB_CONNECTION=mysql
|
||||
DB_HOST=127.0.0.1
|
||||
DB_PORT=3306
|
||||
DB_DATABASE=analytics
|
||||
DB_USERNAME=your_user
|
||||
DB_PASSWORD=your_password
|
||||
|
||||
# Queue (use 'redis' for better performance)
|
||||
QUEUE_CONNECTION=database
|
||||
|
||||
# Mail (for alerts and notifications)
|
||||
MAIL_MAILER=smtp
|
||||
MAIL_HOST=smtp.mailtrap.io
|
||||
MAIL_PORT=2525
|
||||
MAIL_USERNAME=null
|
||||
MAIL_PASSWORD=null
|
||||
MAIL_FROM_ADDRESS=noreply@yourdomain.com
|
||||
MAIL_FROM_NAME="${APP_NAME}"
|
||||
|
||||
# Cache (use 'redis' for better performance)
|
||||
CACHE_STORE=database
|
||||
|
||||
# Session
|
||||
SESSION_DRIVER=database
|
||||
SESSION_LIFETIME=120
|
||||
```
|
||||
|
||||
### Web Server Configuration
|
||||
|
||||
#### For Standard Setup (public/ folder)
|
||||
Point your web server document root to the `public/` directory.
|
||||
|
||||
#### For Shared Hosting (engine/ + public_html/)
|
||||
|
||||
If your hosting has separate folders:
|
||||
- `engine/` - Laravel application files
|
||||
- `public_html/` - Public web root
|
||||
|
||||
**Modify `public_html/index.php`:**
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
use Illuminate\Foundation\Application;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
define('LARAVEL_START', microtime(true));
|
||||
|
||||
// Point to engine directory
|
||||
if (file_exists($maintenance = __DIR__.'/../engine/storage/framework/maintenance.php')) {
|
||||
require $maintenance;
|
||||
}
|
||||
|
||||
require __DIR__.'/../engine/vendor/autoload.php';
|
||||
|
||||
$app = require_once __DIR__.'/../engine/bootstrap/app.php';
|
||||
|
||||
// Tell Laravel the public path is public_html
|
||||
$app->usePublicPath(__DIR__);
|
||||
|
||||
$app->handleRequest(Request::capture());
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Required Background Tasks
|
||||
|
||||
### 1. Queue Worker (CRITICAL)
|
||||
|
||||
**Purpose**: Processes tracking data from websites
|
||||
|
||||
Without this, tracking events are queued but never persisted to the database.
|
||||
|
||||
```bash
|
||||
# Start queue worker
|
||||
php artisan queue:work database --tries=3 --timeout=60
|
||||
```
|
||||
|
||||
**Production Setup**: Use a process supervisor
|
||||
|
||||
**Using Supervisor** (recommended):
|
||||
|
||||
```ini
|
||||
# /etc/supervisor/conf.d/analytics-queue.conf
|
||||
[program:analytics-queue]
|
||||
process_name=%(program_name)s_%(process_num)02d
|
||||
command=php /path/to/analytics/artisan queue:work database --tries=3 --timeout=60
|
||||
autostart=true
|
||||
autorestart=true
|
||||
stopasgroup=true
|
||||
killasgroup=true
|
||||
user=www-data
|
||||
numprocs=1
|
||||
redirect_stderr=true
|
||||
stdout_logfile=/path/to/analytics/storage/logs/queue-worker.log
|
||||
stopwaitsecs=3600
|
||||
```
|
||||
|
||||
Then run:
|
||||
```bash
|
||||
sudo supervisorctl reread
|
||||
sudo supervisorctl update
|
||||
sudo supervisorctl start analytics-queue:*
|
||||
```
|
||||
|
||||
**Using systemd**:
|
||||
|
||||
```ini
|
||||
# /etc/systemd/system/analytics-queue.service
|
||||
[Unit]
|
||||
Description=Analytics Queue Worker
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=www-data
|
||||
WorkingDirectory=/path/to/analytics
|
||||
ExecStart=/usr/bin/php /path/to/analytics/artisan queue:work database --tries=3 --timeout=60
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
Enable and start:
|
||||
```bash
|
||||
sudo systemctl enable analytics-queue
|
||||
sudo systemctl start analytics-queue
|
||||
```
|
||||
|
||||
### 2. Task Scheduler (CRITICAL)
|
||||
|
||||
**Purpose**: Runs scheduled tasks (aggregation, purging, alerts)
|
||||
|
||||
Add to crontab:
|
||||
|
||||
```bash
|
||||
# Edit crontab
|
||||
crontab -e
|
||||
|
||||
# Add this line
|
||||
* * * * * cd /path/to/analytics && php artisan schedule:run >> /dev/null 2>&1
|
||||
```
|
||||
|
||||
This executes:
|
||||
- **Daily at 02:00 AM**: `analytics:aggregate` - Rolls up data into daily aggregates
|
||||
- **Daily at 03:00 AM**: `analytics:purge --force` - Deletes old raw data
|
||||
- **Every hour**: `analytics:check-alerts` - Evaluates alerts and sends notifications
|
||||
|
||||
Without the scheduler:
|
||||
- Reports will be slower (no aggregated data)
|
||||
- Old data will accumulate and bloat the database
|
||||
- Alerts will never trigger
|
||||
|
||||
---
|
||||
|
||||
## Tracking Setup
|
||||
|
||||
### 1. Create a Website
|
||||
|
||||
1. Register/login to the analytics platform
|
||||
2. Navigate to **Websites** → **Add Website**
|
||||
3. Enter website name and domain
|
||||
4. Copy the tracking ID (e.g., `abc123def456`)
|
||||
|
||||
### 2. Install Tracking Script
|
||||
|
||||
Add this script to your website's HTML (before `</head>`):
|
||||
|
||||
**Option 1: JavaScript Snippet**
|
||||
|
||||
```html
|
||||
<script async src="https://analytics.yourdomain.com/api/t/YOUR_TRACKING_ID.js"></script>
|
||||
```
|
||||
|
||||
**Option 2: Self-hosted Script**
|
||||
|
||||
```html
|
||||
<script>
|
||||
!function(t,e,a){/* tracking script */}(window,document,"https://analytics.yourdomain.com","YOUR_TRACKING_ID");
|
||||
</script>
|
||||
```
|
||||
|
||||
**Option 3: No-JavaScript Fallback**
|
||||
|
||||
```html
|
||||
<noscript>
|
||||
<img src="https://analytics.yourdomain.com/api/collect/pixel/YOUR_TRACKING_ID"
|
||||
alt=""
|
||||
style="position:absolute;left:-9999px;" />
|
||||
</noscript>
|
||||
```
|
||||
|
||||
### 3. Track Custom Events
|
||||
|
||||
```javascript
|
||||
// Track a custom event
|
||||
ta('event', 'button_click', {
|
||||
category: 'engagement',
|
||||
label: 'signup_button',
|
||||
value: 1
|
||||
});
|
||||
|
||||
// Track a purchase
|
||||
ta('event', 'purchase', {
|
||||
category: 'ecommerce',
|
||||
value: 99.99
|
||||
});
|
||||
```
|
||||
|
||||
### 4. SPA Support
|
||||
|
||||
For single-page applications (React, Vue, etc.), the tracker automatically detects route changes via `pushState` and `popstate`. You can also manually track page views:
|
||||
|
||||
```javascript
|
||||
// Manual page view tracking
|
||||
ta('pageview');
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## How It Works
|
||||
|
||||
### Tracking Process
|
||||
|
||||
1. **Client-side**: Tracking script loads on visitor's browser
|
||||
2. **Collection**: Script sends tracking data to `/api/collect`
|
||||
3. **Validation**: `CollectController` validates tracking ID and domain
|
||||
4. **Queueing**: Tracking payload is queued as `ProcessTrackingPayload` job
|
||||
5. **Processing**: Queue worker picks up job and:
|
||||
- Creates/updates **Visitor** record (with geolocation)
|
||||
- Creates/retrieves **AnalyticsSession** (30-min timeout)
|
||||
- Records **PageView** or **Event**
|
||||
- Evaluates active **Goals** and records conversions
|
||||
- Updates session metrics (duration, bounce status)
|
||||
6. **Aggregation**: Daily at 02:00 AM, raw data is rolled up into aggregates
|
||||
7. **Reporting**: Dashboard queries combine aggregated + real-time data
|
||||
|
||||
### Session Logic
|
||||
|
||||
- **Session Start**: First page view from a visitor
|
||||
- **Session Timeout**: 30 minutes of inactivity
|
||||
- **Session Duration**: Time between first and last page view
|
||||
- **Bounce**: Session with only 1 page view
|
||||
- **Exit Page**: Last page viewed in session
|
||||
|
||||
### Goal Evaluation
|
||||
|
||||
Goals are evaluated in real-time during tracking:
|
||||
|
||||
1. **URL Destination**: Matches current page URL
|
||||
- Exact: URL must match exactly
|
||||
- Starts with: URL must start with pattern
|
||||
- Contains: URL must contain pattern
|
||||
- Regex: URL must match regex pattern
|
||||
|
||||
2. **Event Match**: Matches event name (and optionally category)
|
||||
|
||||
3. **Duration**: Session duration exceeds threshold
|
||||
|
||||
4. **Pages Per Session**: Page count exceeds threshold
|
||||
|
||||
### Data Aggregation
|
||||
|
||||
Raw tracking data is aggregated daily to improve query performance:
|
||||
|
||||
**Daily Aggregates** (per website, per day):
|
||||
- Total visitors (unique)
|
||||
- Total sessions
|
||||
- Total page views
|
||||
- Bounce count
|
||||
- Total session duration
|
||||
|
||||
**Page Daily Aggregates** (per website, per page, per day):
|
||||
- Page views
|
||||
- Unique page views
|
||||
- Total time on page
|
||||
- Bounce count
|
||||
|
||||
**Query Strategy**:
|
||||
- Historical dates: Query aggregated tables
|
||||
- Today: Query raw tables
|
||||
- Results are merged for complete picture
|
||||
|
||||
---
|
||||
|
||||
## Database Structure
|
||||
|
||||
### Core Tables
|
||||
|
||||
| Table | Description |
|
||||
|-------|-------------|
|
||||
| `users` | User accounts |
|
||||
| `websites` | Tracked websites with settings |
|
||||
| `visitors` | Unique visitors with device/location info |
|
||||
| `analytics_sessions` | User sessions with UTM data |
|
||||
| `page_views` | Individual page visits |
|
||||
| `events` | Custom events with metadata |
|
||||
| `goals` | Conversion goal definitions |
|
||||
| `goal_conversions` | Goal completion records |
|
||||
| `funnels` | Funnel definitions |
|
||||
| `segments` | Custom visitor segments |
|
||||
| `alerts` | Alert rule definitions |
|
||||
| `alert_notifications` | Triggered alert records |
|
||||
| `annotations` | Date annotations |
|
||||
| `dashboard_widgets` | Custom dashboard layouts |
|
||||
| `daily_aggregates` | Pre-computed daily metrics |
|
||||
| `page_daily_aggregates` | Per-page daily metrics |
|
||||
|
||||
### Data Retention
|
||||
|
||||
- **Raw Data**: Retained for 365 days (configurable per website)
|
||||
- **Aggregated Data**: Retained indefinitely
|
||||
- **Purge Schedule**: Daily at 03:00 AM via `analytics:purge`
|
||||
|
||||
---
|
||||
|
||||
## Artisan Commands
|
||||
|
||||
### Analytics Commands
|
||||
|
||||
#### 1. Aggregate Data
|
||||
```bash
|
||||
php artisan analytics:aggregate [options]
|
||||
|
||||
Options:
|
||||
--date=YYYY-MM-DD Aggregate specific date (default: yesterday)
|
||||
--website=ID Aggregate specific website (default: all)
|
||||
|
||||
# Examples
|
||||
php artisan analytics:aggregate
|
||||
php artisan analytics:aggregate --date=2026-03-20
|
||||
php artisan analytics:aggregate --website=1
|
||||
```
|
||||
|
||||
**Important**: Cannot aggregate today's data (prevents incomplete aggregations)
|
||||
|
||||
#### 2. Purge Old Data
|
||||
```bash
|
||||
php artisan analytics:purge [options]
|
||||
|
||||
Options:
|
||||
--website=ID Purge specific website (default: all)
|
||||
--force Skip confirmation prompt
|
||||
|
||||
# Examples
|
||||
php artisan analytics:purge --force
|
||||
php artisan analytics:purge --website=1
|
||||
```
|
||||
|
||||
Deletes raw data older than retention period (default: 365 days).
|
||||
|
||||
#### 3. Check Alerts
|
||||
```bash
|
||||
php artisan analytics:check-alerts
|
||||
```
|
||||
|
||||
Evaluates all active alerts and triggers notifications.
|
||||
|
||||
### Queue Commands
|
||||
|
||||
```bash
|
||||
# Process queue jobs
|
||||
php artisan queue:work database --tries=3
|
||||
|
||||
# List failed jobs
|
||||
php artisan queue:failed
|
||||
|
||||
# Retry failed job
|
||||
php artisan queue:retry {job-id}
|
||||
|
||||
# Retry all failed jobs
|
||||
php artisan queue:retry all
|
||||
|
||||
# Flush failed jobs
|
||||
php artisan queue:flush
|
||||
```
|
||||
|
||||
### Cache Commands
|
||||
|
||||
```bash
|
||||
# Clear application cache
|
||||
php artisan cache:clear
|
||||
|
||||
# Clear config cache
|
||||
php artisan config:clear
|
||||
|
||||
# Clear route cache
|
||||
php artisan route:clear
|
||||
|
||||
# Clear view cache
|
||||
php artisan view:clear
|
||||
|
||||
# Cache config for production
|
||||
php artisan config:cache
|
||||
php artisan route:cache
|
||||
php artisan view:cache
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## API Documentation
|
||||
|
||||
### Authentication
|
||||
|
||||
Generate API token in dashboard: **Profile** → **API Tokens** → **Create Token**
|
||||
|
||||
Include in requests:
|
||||
```bash
|
||||
Authorization: Bearer YOUR_API_TOKEN
|
||||
```
|
||||
|
||||
### Endpoints
|
||||
|
||||
#### GET /api/v1/websites
|
||||
List all websites
|
||||
|
||||
```bash
|
||||
curl -H "Authorization: Bearer YOUR_TOKEN" \
|
||||
https://analytics.yourdomain.com/api/v1/websites
|
||||
```
|
||||
|
||||
#### GET /api/v1/websites/{id}/stats
|
||||
Get website statistics
|
||||
|
||||
```bash
|
||||
curl -H "Authorization: Bearer YOUR_TOKEN" \
|
||||
"https://analytics.yourdomain.com/api/v1/websites/1/stats?from=2026-03-01&to=2026-03-22"
|
||||
```
|
||||
|
||||
Query Parameters:
|
||||
- `from` (required): Start date (YYYY-MM-DD)
|
||||
- `to` (required): End date (YYYY-MM-DD)
|
||||
|
||||
#### GET /api/v1/websites/{id}/pages
|
||||
Get page analytics
|
||||
|
||||
```bash
|
||||
curl -H "Authorization: Bearer YOUR_TOKEN" \
|
||||
"https://analytics.yourdomain.com/api/v1/websites/1/pages?from=2026-03-01&to=2026-03-22&limit=20"
|
||||
```
|
||||
|
||||
#### GET /api/v1/websites/{id}/referrers
|
||||
Get referrer data
|
||||
|
||||
#### GET /api/v1/websites/{id}/events
|
||||
Get event data
|
||||
|
||||
#### GET /api/v1/websites/{id}/visitors
|
||||
Get visitor data
|
||||
|
||||
---
|
||||
|
||||
## Maintenance
|
||||
|
||||
### Daily Tasks (Automated)
|
||||
|
||||
These run automatically via cron (see [Task Scheduler](#2-task-scheduler-critical)):
|
||||
|
||||
- **02:00 AM**: Data aggregation
|
||||
- **03:00 AM**: Old data purging
|
||||
- **Every hour**: Alert evaluation
|
||||
|
||||
### Weekly Tasks (Manual)
|
||||
|
||||
#### Check Queue Status
|
||||
```bash
|
||||
# Check if queue worker is running
|
||||
ps aux | grep "queue:work"
|
||||
|
||||
# Check failed jobs
|
||||
php artisan queue:failed
|
||||
|
||||
# Retry failed jobs
|
||||
php artisan queue:retry all
|
||||
```
|
||||
|
||||
#### Monitor Disk Space
|
||||
```bash
|
||||
# Check database size
|
||||
du -h database/database.sqlite
|
||||
|
||||
# Check storage usage
|
||||
du -sh storage/
|
||||
```
|
||||
|
||||
#### Review Logs
|
||||
```bash
|
||||
# Check application logs
|
||||
tail -f storage/logs/laravel.log
|
||||
|
||||
# Check queue worker logs (if using supervisor)
|
||||
tail -f storage/logs/queue-worker.log
|
||||
```
|
||||
|
||||
### Monthly Tasks
|
||||
|
||||
#### Database Optimization
|
||||
|
||||
**SQLite**:
|
||||
```bash
|
||||
sqlite3 database/database.sqlite "VACUUM;"
|
||||
```
|
||||
|
||||
**MySQL**:
|
||||
```sql
|
||||
OPTIMIZE TABLE visitors, analytics_sessions, page_views, events, daily_aggregates, page_daily_aggregates;
|
||||
```
|
||||
|
||||
#### Review Data Retention
|
||||
|
||||
Check if retention settings are appropriate:
|
||||
1. Navigate to **Website Settings**
|
||||
2. Review **Data Retention** setting (default: 365 days)
|
||||
3. Adjust based on compliance requirements
|
||||
|
||||
### Backup Strategy
|
||||
|
||||
#### Database Backup
|
||||
|
||||
**SQLite**:
|
||||
```bash
|
||||
# Copy database file
|
||||
cp database/database.sqlite backups/database-$(date +%Y%m%d).sqlite
|
||||
|
||||
# Compress
|
||||
gzip backups/database-$(date +%Y%m%d).sqlite
|
||||
```
|
||||
|
||||
**MySQL**:
|
||||
```bash
|
||||
mysqldump -u user -p analytics > backups/analytics-$(date +%Y%m%d).sql
|
||||
gzip backups/analytics-$(date +%Y%m%d).sql
|
||||
```
|
||||
|
||||
#### Application Backup
|
||||
```bash
|
||||
# Backup entire application
|
||||
tar -czf analytics-backup-$(date +%Y%m%d).tar.gz \
|
||||
--exclude=node_modules \
|
||||
--exclude=vendor \
|
||||
--exclude=storage/logs \
|
||||
/path/to/analytics
|
||||
```
|
||||
|
||||
### Troubleshooting
|
||||
|
||||
#### Tracking Not Working
|
||||
|
||||
1. **Check queue worker is running**:
|
||||
```bash
|
||||
ps aux | grep "queue:work"
|
||||
```
|
||||
|
||||
2. **Check failed jobs**:
|
||||
```bash
|
||||
php artisan queue:failed
|
||||
```
|
||||
|
||||
3. **Check tracking domain matches**:
|
||||
- Ensure website domain in dashboard matches actual domain
|
||||
- Domain validation is case-insensitive but must match
|
||||
|
||||
4. **Check browser console**:
|
||||
- Look for CORS errors
|
||||
- Verify tracking script loads
|
||||
|
||||
5. **Check logs**:
|
||||
```bash
|
||||
tail -f storage/logs/laravel.log
|
||||
```
|
||||
|
||||
#### Dashboard Shows No Data
|
||||
|
||||
1. **Check if aggregation ran**:
|
||||
```bash
|
||||
php artisan analytics:aggregate --date=yesterday
|
||||
```
|
||||
|
||||
2. **Check date range** - today's data may not appear if only querying aggregates
|
||||
|
||||
3. **Verify tracking is working** - check raw tables:
|
||||
```sql
|
||||
SELECT COUNT(*) FROM page_views WHERE created_at > datetime('now', '-1 hour');
|
||||
```
|
||||
|
||||
#### Alerts Not Triggering
|
||||
|
||||
1. **Check cron is running**:
|
||||
```bash
|
||||
grep CRON /var/log/syslog
|
||||
```
|
||||
|
||||
2. **Manually run alert check**:
|
||||
```bash
|
||||
php artisan analytics:check-alerts
|
||||
```
|
||||
|
||||
3. **Check mail configuration**:
|
||||
```bash
|
||||
php artisan tinker
|
||||
>>> Mail::raw('Test', function($msg) { $msg->to('test@example.com')->subject('Test'); });
|
||||
```
|
||||
|
||||
#### High Disk Usage
|
||||
|
||||
1. **Run aggregation** (if not running):
|
||||
```bash
|
||||
php artisan analytics:aggregate
|
||||
```
|
||||
|
||||
2. **Purge old data**:
|
||||
```bash
|
||||
php artisan analytics:purge --force
|
||||
```
|
||||
|
||||
3. **Adjust retention settings** in website configuration
|
||||
|
||||
---
|
||||
|
||||
## Performance Optimization
|
||||
|
||||
### 1. Use Redis for Queue & Cache
|
||||
|
||||
```env
|
||||
QUEUE_CONNECTION=redis
|
||||
CACHE_STORE=redis
|
||||
SESSION_DRIVER=redis
|
||||
|
||||
REDIS_HOST=127.0.0.1
|
||||
REDIS_PASSWORD=null
|
||||
REDIS_PORT=6379
|
||||
```
|
||||
|
||||
### 2. Database Indexing
|
||||
|
||||
Ensure migrations have run (indexes are included):
|
||||
```bash
|
||||
php artisan migrate
|
||||
```
|
||||
|
||||
### 3. Cache Configuration
|
||||
|
||||
In production:
|
||||
```bash
|
||||
php artisan config:cache
|
||||
php artisan route:cache
|
||||
php artisan view:cache
|
||||
```
|
||||
|
||||
### 4. Enable OPcache
|
||||
|
||||
Add to `php.ini`:
|
||||
```ini
|
||||
opcache.enable=1
|
||||
opcache.memory_consumption=256
|
||||
opcache.interned_strings_buffer=16
|
||||
opcache.max_accelerated_files=10000
|
||||
opcache.revalidate_freq=2
|
||||
```
|
||||
|
||||
### 5. Queue Workers
|
||||
|
||||
Run multiple queue workers for high traffic:
|
||||
```bash
|
||||
# Run 3 workers
|
||||
php artisan queue:work database --tries=3 &
|
||||
php artisan queue:work database --tries=3 &
|
||||
php artisan queue:work database --tries=3 &
|
||||
```
|
||||
|
||||
Or use supervisor with `numprocs=3`.
|
||||
|
||||
---
|
||||
|
||||
## Security Considerations
|
||||
|
||||
### 1. Environment File
|
||||
- Never commit `.env` to version control
|
||||
- Use strong `APP_KEY` (generated automatically)
|
||||
- Set `APP_DEBUG=false` in production
|
||||
|
||||
### 2. Database Credentials
|
||||
- Use strong passwords
|
||||
- Restrict database user permissions
|
||||
- Use separate database user for application
|
||||
|
||||
### 3. HTTPS
|
||||
- Always use HTTPS in production
|
||||
- Update `APP_URL` to use `https://`
|
||||
- Tracking script requires HTTPS for secure cookies
|
||||
|
||||
### 4. CORS
|
||||
- CORS is enabled for `/api/collect` and `/api/t/{id}.js`
|
||||
- Only these endpoints are publicly accessible
|
||||
- Dashboard requires authentication
|
||||
|
||||
### 5. Rate Limiting
|
||||
- Tracking endpoints have rate limiting
|
||||
- API endpoints have Sanctum rate limiting
|
||||
- Adjust in `app/Http/Middleware` if needed
|
||||
|
||||
---
|
||||
|
||||
## Support & Resources
|
||||
|
||||
### Documentation
|
||||
- Laravel 11: https://laravel.com/docs/11.x
|
||||
- Alpine.js: https://alpinejs.dev
|
||||
- Tailwind CSS: https://tailwindcss.com
|
||||
|
||||
### Logs
|
||||
- Application: `storage/logs/laravel.log`
|
||||
- Queue Worker: Check supervisor/systemd logs
|
||||
|
||||
### Common Paths
|
||||
- **Application**: `/path/to/analytics`
|
||||
- **Public**: `/path/to/analytics/public`
|
||||
- **Storage**: `/path/to/analytics/storage`
|
||||
- **Database**: `/path/to/analytics/database/database.sqlite`
|
||||
- **Logs**: `/path/to/analytics/storage/logs/`
|
||||
|
||||
---
|
||||
|
||||
## Quick Reference
|
||||
|
||||
### Essential Commands
|
||||
|
||||
```bash
|
||||
# Development
|
||||
composer run dev # Start dev environment
|
||||
|
||||
# Queue
|
||||
php artisan queue:work database # Start queue worker
|
||||
php artisan queue:failed # List failed jobs
|
||||
php artisan queue:retry all # Retry failed jobs
|
||||
|
||||
# Analytics
|
||||
php artisan analytics:aggregate # Aggregate yesterday's data
|
||||
php artisan analytics:purge --force # Purge old data
|
||||
php artisan analytics:check-alerts # Check alerts
|
||||
|
||||
# Cache
|
||||
php artisan cache:clear # Clear cache
|
||||
php artisan config:cache # Cache config (production)
|
||||
|
||||
# Maintenance
|
||||
php artisan down # Enable maintenance mode
|
||||
php artisan up # Disable maintenance mode
|
||||
```
|
||||
|
||||
### Cron Entry
|
||||
|
||||
```cron
|
||||
* * * * * cd /path/to/analytics && php artisan schedule:run >> /dev/null 2>&1
|
||||
```
|
||||
|
||||
### Supervisor Config
|
||||
|
||||
```ini
|
||||
[program:analytics-queue]
|
||||
command=php /path/to/analytics/artisan queue:work database --tries=3
|
||||
autostart=true
|
||||
autorestart=true
|
||||
user=www-data
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**Last Updated**: 2026-03-22
|
||||
**Laravel Version**: 11.50.0
|
||||
**PHP Version**: 8.2+ (Compatible with 8.3)
|
||||
Reference in New Issue
Block a user