Fork me on GitHub
Admin/Monitor API

Recent versions of Janus introduced a new feature: an Admin/Monitor API that can be used to ask Janus for more specific information related to sessions and handles. This is especially useful when you want to debug issues at the media level.

Note
Right now, this new API mostly allows you to retrieve information, but only act on part of it: for more interaction (e.g., to force a session removal), you can rely on the existing RESTful, WebSockets, RabbitMQ, MQTT and UnixSockets API for the purpose.

The API, for security reasons, is typically noy enabled by default in any of the transport plugins: that's definitely the case for the stock transport plugins, for instance, while additional, third party plugins may choose to expose the functionality without requiring any tweaking. As to the existing transport, you can enable the admin API by editing the [ admin ] section in the related transport configuration file (e.g., janus.transport.http.cfg for the REST interface, to use the admin API over HTTP). The configuration is pretty much the same as the one for the Janus API. In addition, you can configure restrictions in the form of a password/secret that clients need to provide or other transport-specific ones.

For what concerns the syntax, it's very similar to the RESTful, WebSockets, RabbitMQ, MQTT and UnixSockets API and so this page will briefly discuss the differences. At the moment, a few different methods are exposed:

Following the same spirit of the RESTful, WebSockets, RabbitMQ, MQTT and UnixSockets API these methods need to be invoked on the right path and/or providing the right session_id and handle_id identifiers. Specifically, list_sessions must be invoked without any session/handle information, as it's a global request. Here's an example of how such a request and its related response might look like:

POST /admin
{
        "janus" : "list_sessions",
        "transaction" : "<random alphanumeric string>",
        "admin_secret" : "<password specified in janus.cfg, if any>"
}
{
        "janus" : "success",
        "transaction" : "<same as the request>",
        "sessions" : [
                <session ID #1>,
                <session ID #2>,
                [..]
                <session ID #n>
        ]
}

On the other hand, since list_handles is related to a specific session, a session must be referenced correctly. Using the REST API, this can be done by appending the session identifier (e.g., one of the IDs returned by the previous call) to the API root:

POST /admin/12345678
{
        "janus" : "list_handles",
        "transaction" : "<random alphanumeric string>",
        "admin_secret" : "<password specified in janus.cfg, if any>"
}
{
        "janus" : "success",
        "transaction" : "<same as the request>",
        "session_id" : 12345678,
        "handles" : [
                <handle ID #1>,
                <handle ID #2>,
                [..]
                <handle ID #n>
        ]
}

Once a list of handles is available, detailed info on any of them can be obtained by means of a handle_info call. Since this is a handle-specific request, the correct handle identifier must be referenced, e.g., by appending the ID to the session it belongs to:

POST /admin/12345678/98765432
{
        "janus" : "handle_info",
        "transaction" : "<random alphanumeric string>",
        "admin_secret" : "<password specified in janus.cfg, if any>"
}
{
        "janus" : "success",
        "transaction" : "<same as the request>",
        "session_id" : 12345678,
        "handle_id" : 98765432,
        "info" : {
                "session_id" : 12345678,
                "session_last_activity": 7927759122,
                "session_transport": "janus.transport.websockets",
                "handle_id" : 98765432,
                "plugin": "janus.plugin.echotest",
                "plugin_specific": {
                        // plugin specific (e.g., EchoTest internals)
                },
                "flags": {
                        // flags
                },
                "sdps": {
                        "local": "v=0[..]",
                        "remote": "v=0[..]"
                },
                "streams": [
                        // streams, components, etc.
                ]
        }
}

The actual content of the last response is omitted for brevity, but you're welcome to experiment with it in order to check whether more information (of a different nature, maybe) may be useful to have. In particular, you may want to play with the plugin-specific details, as different plugins will return different information according to what they provide: for instance, the videoroom plugin might clarify whether a handle is being used for publishing media or for receiving it, and what are the involved IDs, the current status of the delivery, and so on. At the same time, the streams object will contain invaluable details related to the WebRTC PeerConnection associated with the handle, as in input/output statistics statistics (bytes, bytes per seconds, NACKs, etc.) or the SDP/ICE/DTLS states.

Finally, the syntax for the set_log_level and set_locking_debug commands is quite straightforward:

POST /admin
{
        "janus" : "set_log_level",
        "level" : <integer between 0 and 7, see debug.h>,
        "transaction" : "<random alphanumeric string>",
        "admin_secret" : "<password specified in janus.cfg, if any>"
}
POST /admin
{
        "janus" : "set_locking_debug",
        "debug" : <0 to disable, 1 to enable>,
        "transaction" : "<random alphanumeric string>",
        "admin_secret" : "<password specified in janus.cfg, if any>"
}

Both commands will return the updated level/debug setting if successful, and an error otherwise.

To conclude, all of the above mentioned examples have assumed an usage of HTTP to interact with the Admin API. The same considerations already made for the Janus API as to the usage of different transports (WebSockets, RabbitMQ, MQTT or others) apply here as well, particularly with respect to the explicit session_id and handle_id in the JSON payload. Besides, to use the Admin API over WebSockets you'll have to use janus-admin-protocol as the subprotocol, instead of the janus-protocol of the regular Janus API.