Skip to main content

PyPI version CI codecov

Django Channels Prometheus

This project was created with the simplest problem in mind, know how many devices are connected to a websocket, and export that metric to a Prometheus endpoint. Currently the only feature this project has is counting the numbers of open connections to a given websocket inside Django Channels.

You can either choose to enable logging for multiple consumers or just one.

Currently there are plans for naming the websockets and outputting different stats, for different websockets.

At the moment all consumers will count towards the same metric.

It works by you add a decorator that redirects all calls to, connect and disconnect functions inside your consumer to proxy through a counter first, and then calls your function in your consumer. That's all it does, nothing fancy, but I really needed the functionallity and decided to publish my work.

Important

This project only support 1 worker at a time.

If you have installed versions before 1.0.0, you need to make changes to your consumers. This project has switched to a decorator approach, instead of mocking the consumer class.

Documentation

Firstly you need to have Django Channels installed, and configured correctly. The project is currently only tested with Daphne and Uvicorn, but other ASGI web servers can be added to tests if the community deems so and or helps with it.

Then install the package via pip:

pip install django-channels-prometheus

Inside your installed apps in settings.py add the package:

INSTALLED_APPS = [
    ...
    'channels_prometheus',
    ...
]

Inside your consumer you need to add either the 'ensure_prometheus_connect_async' decorator if you are using the async version, or 'ensure_prometheus_connect' if you are using the sync version.

See example:

import json

from channels.generic.websocket import AsyncWebsocketConsumer
from channels_prometheus.decorators import ensure_prometheus_connect_async

@ensure_prometheus_connect_async
class ChatConsumer(AsyncWebsocketConsumer):
    async def connect(self):
        self.room_name = self.scope["url_route"]["kwargs"]["room_name"]
        self.room_group_name = f"chat_{self.room_name}"

        # Join room group
        await self.channel_layer.group_add(self.room_group_name, self.channel_name)

        await self.accept()

    async def disconnect(self, close_code):
        # Leave room group
        await self.channel_layer.group_discard(self.room_group_name, self.channel_name)

    # Receive message from WebSocket
    async def receive(self, text_data):
        text_data_json = json.loads(text_data)
        message = text_data_json["message"]

        # Send message to room group
        await self.channel_layer.group_send(
            self.room_group_name, {"type": "chat.message", "message": message}
        )

    # Receive message from room group
    async def chat_message(self, event):
        message = event["message"]

        # Send message to WebSocket
        await self.send(text_data=json.dumps({"message": message}))

After that you will need to add the urls to the Prometheus endpoint to your projects urls like so:

from django.urls import path, include
from channels_prometheus import urls as channels_prometheus_urls
from . import views

urlpatterns = [
    path('', views.home),
    path('metrics/', include(channels_prometheus_urls))
]

Also make sure that you are pointing to the Djangos ASGI version inside your asgi.py:

import os

from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter
from channels.security.websocket import AllowedHostsOriginValidator
from django.core.asgi import get_asgi_application

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "tests.settings")
# Initialize Django ASGI application early to ensure the AppRegistry
# is populated before importing code that may import ORM models.
django_asgi_app = get_asgi_application()

from tests.routing import websocket_urlpatterns

application = ProtocolTypeRouter(
    {
        "http": django_asgi_app,
        "websocket": AllowedHostsOriginValidator(
            AuthMiddlewareStack(URLRouter(websocket_urlpatterns))
        ),
    }
)

When all of that is configured you will be able to find your endpoint metrics at the defined url route.

TODO

  • Create documentation
  • Seperate different consumers to their own metrics.
  • Known issue if the websockets are running on more than one worker, it will give inconsistent results.

Contributing

Contributions are always welcome!

Read through the contributing.md to know how to get started.

Please adhere to this project's code of conduct.

License

MIT

Metadata

Release files for django-channels-prometheus 1.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for django-channels-prometheus 1.0.0
File Size Uploaded
django_channels_prometheus-1.0.0.tar.gz 4.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for django-channels-prometheus 1.0.0
File Interpreter ABI Platform
django_channels_prometheus-1.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 11.0 kB

Release files / django_channels_prometheus-1.0.0.tar.gz

Download URL django_channels_prometheus-1.0.0.tar.gz
Size 4.8 kB
Tags Source
SHA-256 checksum
How to use checksums
2740d61ab4871d0bc56baadfc531218c6f4d055d3011cbe3ffee72aada32abb8
BLAKE2b-256 checksum
How to use checksums
ec1104948328d6c00a30bf99db095c3112cd49c5a33a8ee7f659ba527025c47d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/5.1.1 CPython/3.12.5

Release files / django_channels_prometheus-1.0.0-py3-none-any.whl

Download URL django_channels_prometheus-1.0.0-py3-none-any.whl
Size 6.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
f5598b09281bedaba54219af37d7e174a7302f15d459e07a980195dcdb32d293
BLAKE2b-256 checksum
How to use checksums
5cbf328af5aeb0cdbaa19416ffa802f618c01dc81e2e587c0b7e6ec1c2d208c3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/5.1.1 CPython/3.12.5

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 release files

0.0.2

2 release files

0.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page