Skip to content

peermetrics/peermetrics

Repository files navigation

Peermetrics - WebRTC monitoring system

PRs WelcomeGitHub License

A self-hosted solution to monitor your WebRTC application, Peermetrics offers fully open source client SDKs, back-ends and dashboards so you can troubleshoot issues, optimize performance, and deliver better user experiences.

For scale, large workloads, production environments, or organizations preferring to focus on their core application rather than infrastructure management, WebRTC.ventures offers both managed service and custom implementations. Reach out to WebRTC.ventures.

Table of Contents

About

Starting with the javascript SDK you can integrate with all the major WebRTC libs (Livekit, Mediasoup, Janus, etc.) or your custom implementation.

This repo contains the services that are used to ingest and visualize those metrics:

  • api: the ingestion endpoint
  • web: the visualization service

Features

App dashboard

The app dashboard is the best way to get an overview of how your users are experiencing your app. On top of the usual metrics (browsers, OS, location, etc) you can see the most common issues overall so you know on what to focus.

image

image

Detailed participant details

Get detailed reports for each participant (how they connected, their devices) and automatically detected issues. image

Connection timelines

Drilldown into each participant's connection to get insights about how their connection behaved during the whole call. image

Demo

Try the live DEMO.

How it works

peer metrics contains all the components you need to monitor and improve your WebRTC app:

  • client SDKs: used for collecting metrics from client devices (right now we only support the JavaScript SDK).
  • ingestion endpoint: this is a server where the SDK sends the metrics collected (this is the api service).
  • visualization endpoint: used by the dev / customer team to visualize the metrics collected (this is the web service).

The reason for separating into api and web it's because the services have different scaling needs.

Tech stack

Both api and web have the same backend:

  • Language: Python 3.8
  • Framework: Django
  • DB: Postgres
  • Template rendering: Jinja2
  • Frontend: VueJS

How to run locally

1. Clone repo

Fastest way to get started is to pull this repo and use docker compose

git clone https://github.com/peermetrics/peermetrics
cd peermetrics

2. Start docker

Option A: Using Docker Hub images (may have migration issues)

You can start all containers using the pre-built images:

docker compose up

Option B: Using development setup (Recommended)

For a more reliable setup that builds from source and includes all migrations:

# First, clone the api and web repos in the same parent directory
git clone https://github.com/peermetrics/api
git clone https://github.com/peermetrics/web
cd peermetrics

# Then use the dev docker-compose file
docker compose -f docker-compose.dev.yaml up

The API service will automatically:

  • Run database migrations
  • Create the default admin user (username: admin, password: admin)
  • Start the application

Note: For production deployments, make sure to change the default admin password via environment variables (see Authentication section).

How to Deploy

Because peer metrics consists for two services, both need to be deployed independently.

This also offers the flexibility to scale them separately.

There are multiple ways to deploy peer metrics:

Docker

The recommended way for deploying is to use Docker.

There are 2 images on Docker Hub:

  • api: peermetrics/api
  • web: peermetrics/web

For inspiration on how to use the images with Docker Compose check the files:

To deploy both containers on the same server look at docker-compose.yaml

Google app engine

You also have the option to deploy the app as a Google App engine service.

Each service repo has a app_engine.yaml file that will help you deploy both services to App engine.

Check the files for web and api.

Environment Variables Reference

Both the api and web services are configured via environment variables. The tables below list every available variable, which service uses it, and whether it is required.

API Service

Variable Required Default Description
Django Core
DEBUG No False Enable Django debug mode. Set to True for development only.
DJANGO_SETTINGS_MODULE Yes - Must be set to api.settings.
SECRET_KEY Yes - Django secret key for cryptographic signing. Use a long random string in production.
ALLOWED_HOSTS No * Comma-separated list of allowed hostnames.
URL_PREFIX No "" URL prefix when serving under a subpath (e.g. /peermetrics). Nginx must have matching locations.
Authentication
INIT_TOKEN_SECRET Yes - Secret used to sign JWT tokens returned by the /initialize endpoint. Used by the SDK to authenticate.
SESSION_TOKEN_SECRET Yes - Secret used to sign JWT tokens returned by the /sessions endpoint.
Admin User
DEFAULT_ADMIN_USERNAME No admin Username for the auto-created admin account on first startup.
DEFAULT_ADMIN_PASSWORD No admin Password for the auto-created admin account. Change in production. Must match the web service value.
DEFAULT_ADMIN_EMAIL No admin@admin.com Email for the auto-created admin account.
Web Domain
WEB_DOMAIN Yes - Domain where the web dashboard is hosted (e.g. localhost:8080). Used for CORS and generating links. Do not include the protocol.
Database
DATABASE_HOST Yes - PostgreSQL server hostname.
DATABASE_PORT Yes - PostgreSQL server port (typically 5432).
DATABASE_USER Yes - PostgreSQL username.
DATABASE_PASSWORD Yes - PostgreSQL password.
DATABASE_NAME Yes - PostgreSQL database name.
CONN_MAX_AGE Yes - Database connection lifetime in seconds (e.g. 600). Set to 0 to close connections after each request.
Redis
REDIS_HOST No - Redis connection URL (e.g. redis://127.0.0.1:6379). If not set, caching is disabled. For TLS use rediss://.
GeoIP / Map
USE_EXTERNAL_GEOIP_PROVIDER No False Set to True to enable GeoIP lookups for participant location data. Required for the map on the dashboard to show participant locations.
IPSTACK_URL No - Base URL for the ipstack API. Set to http://api.ipstack.com. Note: ipstack's free plan only supports HTTP, not HTTPS. Required when USE_EXTERNAL_GEOIP_PROVIDER is True.
IPSTACK_ACCESS_KEY No - Your ipstack API access key. Get one at ipstack.com/signup. Required when USE_EXTERNAL_GEOIP_PROVIDER is True.
Data Management
POST_CONFERENCE_CLEANUP No False If True, deletes raw stats events after a conference ends to save storage. Conference summaries are kept. See FAQ.
Google Cloud Tasks
USE_GOOGLE_TASK_QUEUE No False Set to True to use Google Cloud Tasks for background processing (App Engine deployments).
GOOGLE_TASK_QUEUE_NAME No - Name of the Cloud Tasks queue (e.g. queue-1). Required when USE_GOOGLE_TASK_QUEUE is True.
APP_ENGINE_LOCATION No - App Engine location (e.g. us-east1). Required when USE_GOOGLE_TASK_QUEUE is True.
TASK_QUEUE_DOMAIN No - Domain for task queue callbacks (e.g. https://api.example.com/). Required when USE_GOOGLE_TASK_QUEUE is True.
Google Cloud Logging
USE_GOOGLE_CLOUD_LOGGING No False Set to True to send logs to Google Cloud Logging. Only applies when deployed on GCP.

Web Service

Variable Required Default Description
DEBUG No False Enable Django debug mode. Set to True for development only.
DJANGO_SETTINGS_MODULE Yes - Must be set to web.settings.
SECRET_KEY Yes - Django secret key. Can be different from the API service key.
ALLOWED_HOSTS No * Comma-separated list of allowed hostnames.
URL_PREFIX No "" URL prefix when serving under a subpath (e.g. /peermetrics). Must match nginx configuration.
DEFAULT_ADMIN_PASSWORD No admin Used to detect if the user is logging in with the default password and prompt for a change. Must match the API service value.
API_ROOT Yes - Full URL to the API endpoint including /v1 (e.g. http://localhost:8081/v1). The web service uses this to fetch data from the API.
COOKIE_DOMAIN No - Domain for the session cookie. Only needed when API and web are on different subdomains.
DATABASE_HOST Yes - PostgreSQL server hostname (same database as the API service).
DATABASE_PORT Yes - PostgreSQL server port.
DATABASE_USER Yes - PostgreSQL username.
DATABASE_PASSWORD Yes - PostgreSQL password.
DATABASE_NAME Yes - PostgreSQL database name.
CONN_MAX_AGE Yes - Database connection lifetime in seconds.

Shared Infrastructure

Variable Required Default Description
POSTGRES_USER Yes - PostgreSQL superuser username (used by the postgres container).
POSTGRES_PASSWORD Yes - PostgreSQL superuser password (used by the postgres container).
POSTGRES_DB Yes - PostgreSQL database name to create on startup (used by the postgres container).

Development

To start developing peer metrics locally:

  1. Clone repos

Clone this repo:

git clone https://github.com/peermetrics/peermetrics && cd peermetrics

Then clone api and web:

git clone https://github.com/peermetrics/web
git clone https://github.com/peermetrics/api
  1. Start docker

To start development start Docker using the special dev file:

docker compose -f docker-compose.dev.yaml up

The API service will automatically run migrations and create the default admin user on first startup.

Note: For development with local code changes, you may need to run migrations manually if you modify models:

docker compose -f docker-compose.dev.yaml exec api python manage.py makemigrations app
docker compose -f docker-compose.dev.yaml exec api python manage.py migrate
  1. Start watcher

Start the watcher for the vue files:

cd web
npm install
npm run watch

How to integrate

To integrate peer metrics into your WebRTC app you need to follow these steps:

  1. Deploy the api / web images using Docker or any of the options found in How to deploy.
  2. Access the web service, create a new organization and app. There will be an API key associated with the new app.
  3. Integrate the Javascript SDK following the steps listed here.
  4. When initializing the JS SDK, use an additional attribute apiRoot to start using your custom API endpoint.

For example, if you deployed the api endpoint at api.example.com, the initializing object will become:

let peerMetrics = new PeerMetrics({
    apiRoot: 'https://api.example.com/v1',
    apiKey: '7090df95cd247f4aa735779636b202', // api key from the newly created app
    userId: '1234',
    userName: 'My user',
    conferenceId: 'conference-1',
    conferenceName: 'Conference from 4pm',
    appVersion: '1.0.1'
})

Note: very important that apiRoot is a valid URL and ends with /v1

  1. Follow the instructions in the SDK repo to start collecting metrics.

Authentication

Peermetrics includes an authentication system that helps ensure secure access to your monitoring dashboards while maintaining ease of use during initial setup.

Default Credentials

When you first start Peermetrics, a default admin account is automatically created:

  • Username: admin
  • Password: admin

You can log in to the web interface at http://localhost:8080/login using these credentials.

Changing Default Password

  1. Automatic Detection: When you log in with the default password (admin), you'll be automatically redirected to a password change page with a security warning.

  2. Password Change Prompt: You'll see a clear message indicating you're using the default password and should change it.

  3. Skip Option: During development, you can skip the password change, but you'll be prompted again on your next login.

  4. Password Requirements: New passwords must be at least 8 characters long and pass Django's password validation checks.

To change your password:

  • Log in with default credentials
  • You'll be redirected to the password change page
  • Enter your new password twice
  • Click "Change Password"

Alternatively, navigate to /change-password anytime while logged in.

  1. Backup Recovery: If you lose admin access:
    # Access the API container
    docker compose exec api sh
    
    # Create a new superuser or reset password
    python manage.py createsuperuser
    # or
    python manage.py changepassword admin

Customizing Admin Credentials

For production deployments, you should customize the default admin credentials using environment variables. This is especially important when deploying with Docker.

Environment Variables

Set these environment variables in your docker-compose.yaml or .env files:

For API Service (creates the admin user):

environment:
  DEFAULT_ADMIN_USERNAME: "admin"           # Default: admin
  DEFAULT_ADMIN_PASSWORD: "your_secure_password"  # Default: admin
  DEFAULT_ADMIN_EMAIL: "admin@yourcompany.com"    # Default: admin@admin.com

For Web Service (detects default password on login):

environment:
  DEFAULT_ADMIN_PASSWORD: "your_secure_password"  # Must match API service

Example: Production docker-compose.yaml

services:
  api:
    image: peermetrics/api:latest
    environment:
      DEFAULT_ADMIN_USERNAME: "superadmin"
      DEFAULT_ADMIN_PASSWORD: "MySecureP@ssw0rd123!"
      DEFAULT_ADMIN_EMAIL: "admin@mycompany.com"
      # ... other environment variables

  web:
    image: peermetrics/web:latest
    environment:
      DEFAULT_ADMIN_PASSWORD: "MySecureP@ssw0rd123!"  # Must match!
      # ... other environment variables

Important Notes:

  • The DEFAULT_ADMIN_PASSWORD must be the same in both web and API services for the default password detection to work correctly
  • The admin user is created only once during the first startup (idempotent operation)
  • If the admin user already exists, the initialization script will skip creation
  • Change these values before your first deployment to production

Rate Limiting

To protect against brute force attacks, the login endpoint includes rate limiting:

  • Limit: 5 login attempts per 5 minutes per IP address
  • Behavior: After exceeding the limit, users will see an error message: "Too many login attempts. Please try again in a few minutes."
  • Scope: Rate limiting applies per IP address, so multiple users behind the same NAT won't interfere with each other excessively

The rate limiting is implemented using django-ratelimit.

Other

DB Migrations

To run migration for the DB you need to use the api container:

docker compose run api python manage.py migrate

API Admin

In order to debug conferences, events, etc you can use the Admin section in the api container.

For that, you need to create a superuser:

# sh into the api container
docker compose run api sh
# run the createsuperuser command
python manage.py createsuperuser --username admin --email admin@admin.com
# it will ask for you to choose a password

You'll also need to collectstatic:

python manage.py collectstatic --clear --noinput

Dummy data

If you want to add some dummy data while developping, run this script (last number is the number of past days to populate):

docker compose -f docker-compose.dev.yaml run api python populate_db.py 5

CSS

For web you have the following commands:

  • compile CSS
npm run css
  • start CSS watcher
npm run css-watch

FAQ

Why PostgreSQL for data storage?

We believe PostgreSQL is more than suited for the job. It is a very powerful DB and you can get a lot out of it with just vertical scaling. We use PostgreSQL for our production environment and we've been really happy with it.

The big advantage with this option is that it a well-understood technology, widely supported, cheap to scale, etc.

If your team reaches a point where the limiting factor is PostgreSQL, we would love to offer support for other options.

What does the POST_CONFERENCE_CLEANUP flag do?

The GenericEvent model takes a big percentage of the data stored in the DB. Drilling down, a big percentage of that is made of stats events. At the end of the conference, we go through all of those events and create a summary, so the events are not really needed afterwards.

This flag will delete all the stats events for the just ended conference.

About

WebRTC monitoring made easy

Topics

Resources

License

Security policy

Stars

Watchers

Forks

Releases

No releases published

Contributors