Statistics per consuming customer

There is a need to differentiate statistics from Jitsi depending on the entity using our service. E.g

Customer A - x audio calls, x conferences, x concurrent users, x jitter, etc etc
Customer B - x audio calls, x conferences, x concurrent users, x jitter, etc etc
Customer C - …

We are currently using the metrics/statistics coming out of our Kubernetes cluster but they are for all users in that namespace/cluster. Is there a way to differentiate?

You can use tenants for different customers and make sure the stats coming from the cluster are tagged with the tenant (not sure what is used there for sending these stats).

thanks @damencho

tenants as in separate namespaces in kubernetes (their own prosody, jvb, jicofo etc)? Or something else?

Tenants as Jitsi Meet and Jitsi Meet
How do you recognize Customer A and Customer B on your side.
We have created the tenants thing in jitsi-meet for this purpose.

Cheers! You should be named ”jitsiGPT” :blush:

Is there any documentation on how to use tenants where I can read more about this? I guess the follow up question is how the statistics are separated in this regard. How to differentiate between customer A and customer B

we will be using jwt auth for our customers, maybe this could be a way to differentiate which tenant they can use? Does the jwt hold this info today?

Yep, you can restrict access based on tenants.
Tenants are enabled by default when using jitsi-meet debian package. Not sure about docker, I think we turned it on by default at some point …

Understood, so basically add the following to the jwt instead of the base domain:

“sub”: “tenant1”,

What about statistics, are they also differentiated based on tenant? Can we filter out how many meetings tenant1 has had e.g last month?

No idea what are these statistics. What is creating them?

Thinking about these:

these are sent to Grafana and then we can change the view and period there

These are cumulative stats, these are not per meeting.

That would be fine to start with if we can differentiate between tenants

To get per meeting stats, would that be e.g matomo (on prem)? Possible to differ per tenant?

Is the JaaS analytics grouped per tenant?

Nope. you cannot as this is the whole bridge for all conferences on that bridge.

The Jaas stats are per tenant yes, but you as a jaas client has one tenant and you see stats for your tenant.

You can use this: prosody-plugins/event_sync at main · jitsi-contrib/prosody-plugins · GitHub
Or if you need and media statistics you can use GitHub - jitsi/rtcstats-server: Server for and you can be doing some post processing on the server parsing those and creating your own stats. Those stats has the whole meeting name, including the tenant.

Understood, thanks!

How does JaaS do the split of data between tenants? Do JaaS customers get their own Jitsi stack with their own jvbs, jicofo, prosody etc?

Thanks for the tip of advice, will look closer in to both of them :+1:t2:

This what you see there is callstats. This is their thing and I’m not sure how they do it, but I think it is based on a siteId we pass in the client - which is the tenant.

Based on great feedback from @damencho we will start looking at the event_sync module for Prosody

@emrah @shawn I believe you are the contributors/developers of mod_event_sync right?

What are the requirements of the API server? To accept JSON files? Any tip of advice before we start?

api_prefix = “http://your.api.server/api”

The use case is to collect stats such as number of active meetings or number of active users per month etc. and sort it out per tenant/domain.

The plugin does not really impose any requirements on the API endpoint. As long as the API is reachable and accepts requests for the required paths, and that it responds in a timely fashion, it’s all good.

Off the top of my head, here are a few things to consider:

  1. Endpoint auth – if your API endpoint is publicly accessible, then you’ll want to protect it with some form of auth so that a malicious actor cannot flood you with junk data. If you happen to use a header-based auth, then you can use the api_headers options and not have to modify the module.
  2. Domain resolution – when specifying the URL of your API, make sure the hostname is resolvable via DNS server and not reliant on /etc/hosts. The underlying net.http lua module used for resolving IP address does not use take into account /etc/hosts [1].
  3. Debugging and initial dev – before building your endpoint, you could first configure event_sync to post to something like That way, you can first confirm that the module is working and you can inspect the payload and endpoints being called.
    • To do this, visit and you’ll get a unique URL e.g.<SOME_UUID>. You can then configure event_sync with:
    api_prefix = "<SOME_UUID>"

IIRC, tenant-based rooms (e.g. client123/room123) would be represented in room_name payload as [client123]room123. So your API backend should be able to easily parse it and store the data accordingly.

Do have a play and double check. Also take into account how case is handled for room name and tenant. I suspect everything might be represented as lower case since it is extracted for room JID.
So if someone visits it might show up as [customerx]myroom. Maybe.

Good luck with your project.

Thanks alot @shawn for sharing, we will do some digging in to this. Might come back with some follow-up questions :wink:

Very simple API server for event_sync

1 Like