Manage Qlik Sense user sessions in style
Managing user sessions in client-managed Qlik Sense can be tricky or even outright difficult in large Sense environments. Ctrl-Q includes powerful tools that makes this work easier!
Ever since starting to work with client-managed Qlik Sense many years ago the topic of user sessions has been somewhat of a mystery to me.
Or maybe not a mystery, but something rather opaque that is hard to get insights into. The sessions are always there in the background when working with Sense, but they are also difficult to manage in a good way.
Fast forward a decade and it was time to address this... drum roll...
Ctrl-Q 3.16 adds commands for viewing and deleting Qlik Sense proxy sessions.
The commands are designed to manage both individual sessions as well as doing bulk management of all sessions meeting certain criteria.
This has been possible to do also in the past using various good PowerShell toolkits (Qlik-Cli-Windows, qlik-cli-utils and others), but I wanted something that was easier to use - yet powerful - and could be used on the command line on both Windows and macOS.
Ctrl-Q was the perfect vehicle to do this.
What's the use case?
Good and relevant question, of course.
The most common use case will probably be to figure out how many - and exactly which - users are connected right now, via a specific (or several) virtual proxies.
Let's say you need to restart a Sense server, either as an emergency restart or as part of a planned maintenance window.
How many users will be impacted by the restart?
Per virtual proxy and across all virtual proxies linked to the proxy service that will be restarted?
Exactly which users will be impacted?
Maybe some of the connected users should be notified (again) about the coming restart?
Another use case can be to investigate connectivity problems.
Let's say a user cannot log into Sense. Does the user get past authentication and actually get a proxy session? Or does the problem happen before creation and assignment of the session?
Ctrl-Q can be very useful in both scenarios.
What's in a session?
In this text we're looking at proxy sessions, which is something slightly different than the engine sessions that keep track of who is doing what in the Qlik Sense associative engine.
A proxy session is created when a user connects to Sense via the proxy service.
For example, a user starts a web browser on her computer and logs into Sense - a proxy session is created once the authentication is done. If a second browser tab is opened it will use the already existing session.
If instead an incognito/private tab is opened and the user logs into Sense, that will create a new session.
A good overview of how sessions work in different scenarios is found here.
So what kind of info about connected users can we get by looking at the proxy sessions?
- User ID and user directory of the connected user.
- Which virtual proxy and proxy service a user is connected via.
- Session attributes set during the authentication or in JWTs used to authenticate. Examples include email address, security groups, full name.
- Session ID that uniquely identifies the session.
- General information (URL prefix, description, load balancing nodes...) about the virtual proxy and its linked proxy services.
Who's connected right now - listing sessions
The Ctrl-Q documentation provides examples for Windows, so let's use macOS here instead (Linux will be very similar).
Let's start by looking at available options for the ctrl-q session-get
command:
Most options have reasonable default values, so a bare minimum call may look like this:
./ctrl-q session-get --host pro2-win2.lab.ptarmiganlabs.net --auth-user-dir LAB --auth-user-id goran --output-format table
➜ ./ctrl-q session-get --host pro2-win2.lab.ptarmiganlabs.net --auth-user-dir LAB --auth-user-id goran --output-format table
2024-03-15T15:55:37.785Z info: -----------------------------------------------------------
2024-03-15T15:55:37.788Z info: | Ctrl-Q
2024-03-15T15:55:37.789Z info: |
2024-03-15T15:55:37.789Z info: | Version : 3.16.0
2024-03-15T15:55:37.789Z info: | Log level : info
2024-03-15T15:55:37.789Z info: |
2024-03-15T15:55:37.790Z info: | Command : session-get
2024-03-15T15:55:37.790Z info: | : get info about proxy sessions on one or more virtual proxies
2024-03-15T15:55:37.790Z info: |
2024-03-15T15:55:37.790Z info: | Run Ctrl-Q with the '--help' option to see a list of all available options for this command.
2024-03-15T15:55:37.791Z info: |
2024-03-15T15:55:37.791Z info: | https://github.com/ptarmiganlabs/ctrl-q
2024-03-15T15:55:37.791Z info: ----------------------------------------------------------
2024-03-15T15:55:37.792Z info:
2024-03-15T15:55:37.800Z info: Get Qlik Sense proxy sessions
2024-03-15T15:55:38.377Z info: Successfully retrieved 29 virtual proxies from host pro2-win2.lab.ptarmiganlabs.net
2024-03-15T15:55:38.864Z info: Successfully retrieved 2 proxies from host pro2-win2.lab.ptarmiganlabs.net
2024-03-15T15:55:38.879Z info: Available Proxy services.
┌───────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Available proxy services. │
│ │
│ Note: The "sessions-get" command will only work correctly if the correct --host parameter is used when ca │
│ lling Ctrl-Q. │
│ The --host parameter should be one of the host names listed below. │
├─────────┬─────────────────────────────────┬──────────────────────────────────────┬────────────────────────┤
│ Name │ Host name │ Id │ Linked virtual proxies │
├─────────┼─────────────────────────────────┼──────────────────────────────────────┼────────────────────────┤
│ Central │ pro2-win1.lab.ptarmiganlabs.net │ 9d5d7900-3e52-4f22-b6b9-51f38a3afe86 │ 24 │
├─────────┼─────────────────────────────────┼──────────────────────────────────────┼────────────────────────┤
│ dev1 │ pro2-win2.lab.ptarmiganlabs.net │ d0510bbe-c686-459b-b10e-713fcf3951e8 │ 5 │
└─────────┴─────────────────────────────────┴──────────────────────────────────────┴────────────────────────┘
2024-03-15T15:55:38.921Z warn: Virtual proxy is not linked to any proxy. Prefix="mobile", Session cookie header name="X-Qlik-Session-mob"
2024-03-15T15:55:39.062Z warn: Virtual proxy is not linked to any proxy. Prefix="hdr", Session cookie header name="X-Qlik-Session-hdr-dev"
2024-03-15T15:55:39.503Z warn: Virtual proxy is not linked to any proxy. Prefix="hdr-access1", Session cookie header name="X-Qlik-Session-hdr-access1"
2024-03-15T15:55:40.058Z info:
┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ -- Sessions per virtual proxy and proxy services -- │
│ │
│ Total number of sessions: 5 │
│ │
│ Sessions per proxy service: │
│ Central: pro2-win1.lab.ptarmiganlabs.net: 5 │
│ dev1: pro2-win2.lab.ptarmiganlabs.net: 0 │
│ │
├───────────────────────────┬──────────────────────┬─────────────────────────────────────┬─────────────────────────────────┬──────────────────────────────────────────┬────────────────────────┬─────────────────┬───────────────────┬────────────────────┬──────────────────────────────────────┤
│ Virtual proxy description │ Virtual proxy prefix │ Virtual proxy session cookie header │ Linked proxy service │ Load balancing nodes │ Session user directory │ Session user ID │ Session user name │ Session attributes │ Session ID │
├───────────────────────────┼──────────────────────┼─────────────────────────────────────┼─────────────────────────────────┼──────────────────────────────────────────┼────────────────────────┼─────────────────┼───────────────────┼────────────────────┼──────────────────────────────────────┤
│ finance virtual proxy │ finance │ X-Qlik-Session-finance │ Central: │ Central: pro2-win1.lab.ptarmiganlabs.net │ LAB │ testuser_2 │ │ │ 940aa6f6-2738-495c-b994-bb1b03b0fabd │
│ │ │ │ pro2-win1.lab.ptarmiganlabs.net │ dev1: pro2-win2.lab.ptarmiganlabs.net │ │ │ │ │ │
├───────────────────────────┼──────────────────────┼─────────────────────────────────────┼─────────────────────────────────┼──────────────────────────────────────────┼────────────────────────┼─────────────────┼───────────────────┼────────────────────┼──────────────────────────────────────┤
│ finance virtual proxy │ finance │ X-Qlik-Session-finance │ Central: │ Central: pro2-win1.lab.ptarmiganlabs.net │ LAB │ testuser_1 │ │ │ f9de752e-e7ae-4194-ab93-520e98bdc048 │
│ │ │ │ pro2-win1.lab.ptarmiganlabs.net │ dev1: pro2-win2.lab.ptarmiganlabs.net │ │ │ │ │ │
├───────────────────────────┼──────────────────────┼─────────────────────────────────────┼─────────────────────────────────┼──────────────────────────────────────────┼────────────────────────┼─────────────────┼───────────────────┼────────────────────┼──────────────────────────────────────┤
│ finance virtual proxy │ finance │ X-Qlik-Session-finance │ Central: │ Central: pro2-win1.lab.ptarmiganlabs.net │ LAB │ testuser_2 │ │ │ 6171e788-ae6a-49ed-8900-26e2cc8837f8 │
│ │ │ │ pro2-win1.lab.ptarmiganlabs.net │ dev1: pro2-win2.lab.ptarmiganlabs.net │ │ │ │ │ │
├───────────────────────────┼──────────────────────┼─────────────────────────────────────┼─────────────────────────────────┼──────────────────────────────────────────┼────────────────────────┼─────────────────┼───────────────────┼────────────────────┼──────────────────────────────────────┤
│ finance virtual proxy │ finance │ X-Qlik-Session-finance │ Central: │ Central: pro2-win1.lab.ptarmiganlabs.net │ LAB │ testuser_1 │ │ │ d5845fb8-ce38-49c3-bb34-fb3c2b9c654d │
│ │ │ │ pro2-win1.lab.ptarmiganlabs.net │ dev1: pro2-win2.lab.ptarmiganlabs.net │ │ │ │ │ │
├───────────────────────────┼──────────────────────┼─────────────────────────────────────┼─────────────────────────────────┼──────────────────────────────────────────┼────────────────────────┼─────────────────┼───────────────────┼────────────────────┼──────────────────────────────────────┤
│ finance virtual proxy │ finance │ X-Qlik-Session-finance │ Central: │ Central: pro2-win1.lab.ptarmiganlabs.net │ LAB │ testuser_2 │ │ │ 819cccd8-2b7d-43c2-bed0-d784b8e85cb3 │
│ │ │ │ pro2-win1.lab.ptarmiganlabs.net │ dev1: pro2-win2.lab.ptarmiganlabs.net │ │ │ │ │ │
└───────────────────────────┴──────────────────────┴─────────────────────────────────────┴─────────────────────────────────┴──────────────────────────────────────────┴────────────────────────┴─────────────────┴───────────────────┴────────────────────┴──────────────────────────────────────┘
➜
Looks like test user_1
and testuser_2
has in total 5 sessions via the finance
virtual proxy that is linked a proxy service running on the server pro2-win1.lab.ptarmiganlabs.net
.
Filtering and sorting sessions
The example above gave us all sessions for all virtual proxies and proxy services.
Let's say we're only interested in a few select virtual proxies and/or proxy services, what then?
- The
--session-virtual-proxy
option can be used to specify one or more virtual proxies for which sessions should be retrieved. - Similarly, the
--host-proxy
option can be used to specify one or more proxy service hosts for which sessions should be retrieved.
Great, but what if we have 1500 sessions that are sorted by the virtual proxy prefix (i.e. finance
above, which is the default sorting) - but would like the sessions sorted by user ID instead?
Add --sort-by userid
to sort by user ID instead.
Sessions can be sorted by prefix
, proxyhost
, proxyname
, userdir
, userid
or username
.
Output format: Table or JSON
Use the --output-format
to control if the sessions are presented as a table (like above) or as JSON.
Valid options are json
(which is default) and table
.
Bye-bye users - deleting sessions
Ok, next step is to delete those user sessions.
Same thing here, the Ctrl-Q doc site has examples for Windows so let's use macOS here.
Deleting sessions can be done in either of two ways:
- Deleting one or more sessions for a specific virtual proxy and proxy service.
- Which session(s) to be deleted is set using the
--session-id
parameter. Add each session ID separated by a space.
- Which session(s) to be deleted is set using the
- Deleting all sessions for a specific virtual proxy and proxy service.
Let's delete all the sessions above.
When deleting sessions the virtual proxy and proxy service host are mandatory options:
--session-virtual-proxy
is used to define which virtual proxy sessions should be deleted from.--host-proxy
is used to define which proxy service host the sessions are connected to. Think of it this way: All sessions connect to exactly one proxy service. Which host does that service run on?
The command looks like this:
./ctrl-q session-delete --host pro2-win1.lab.ptarmiganlabs.net --host-proxy pro2-win1.lab.ptarmiganlabs.net --session-virtual-proxy finance --auth-user-dir LAB --auth-user-id goran
➜ ctrl-q demo ./ctrl-q session-delete --host pro2-win1.lab.ptarmiganlabs.net --host-proxy pro2-win1.lab.ptarmiganlabs.net --session-virtual-proxy finance --auth-user-dir LAB --auth-user-id goran
2024-03-15T16:07:35.078Z info: -----------------------------------------------------------
2024-03-15T16:07:35.079Z info: | Ctrl-Q
2024-03-15T16:07:35.079Z info: |
2024-03-15T16:07:35.079Z info: | Version : 3.16.0
2024-03-15T16:07:35.079Z info: | Log level : info
2024-03-15T16:07:35.079Z info: |
2024-03-15T16:07:35.079Z info: | Command : session-delete
2024-03-15T16:07:35.080Z info: | : delete proxy session(s) on a specific virtual proxy and proxy service
2024-03-15T16:07:35.080Z info: |
2024-03-15T16:07:35.080Z info: | Run Ctrl-Q with the '--help' option to see a list of all available options for this command.
2024-03-15T16:07:35.080Z info: |
2024-03-15T16:07:35.080Z info: | https://github.com/ptarmiganlabs/ctrl-q
2024-03-15T16:07:35.080Z info: ----------------------------------------------------------
2024-03-15T16:07:35.080Z info:
2024-03-15T16:07:35.084Z info: Delete Qlik Sense proxy sessions
2024-03-15T16:07:35.084Z info: Deleting sessions on proxy "pro2-win1.lab.ptarmiganlabs.net", virtual proxy "finance"
2024-03-15T16:07:35.186Z info: Successfully retrieved 1 virtual proxies from host pro2-win1.lab.ptarmiganlabs.net
2024-03-15T16:07:35.460Z info: Successfully retrieved 2 proxies from host pro2-win1.lab.ptarmiganlabs.net
2024-03-15T16:07:35.470Z info: Available Proxy services.
┌───────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Available proxy services. │
│ │
│ Note: The "sessions-get" command will only work correctly if the correct --host parameter is used when ca │
│ lling Ctrl-Q. │
│ The --host parameter should be one of the host names listed below. │
├─────────┬─────────────────────────────────┬──────────────────────────────────────┬────────────────────────┤
│ Name │ Host name │ Id │ Linked virtual proxies │
├─────────┼─────────────────────────────────┼──────────────────────────────────────┼────────────────────────┤
│ Central │ pro2-win1.lab.ptarmiganlabs.net │ 9d5d7900-3e52-4f22-b6b9-51f38a3afe86 │ 24 │
├─────────┼─────────────────────────────────┼──────────────────────────────────────┼────────────────────────┤
│ dev1 │ pro2-win2.lab.ptarmiganlabs.net │ d0510bbe-c686-459b-b10e-713fcf3951e8 │ 5 │
└─────────┴─────────────────────────────────┴──────────────────────────────────────┴────────────────────────┘
2024-03-15T16:07:35.470Z info: ✅ All host names specified in the --host-proxy parameter are valid.
2024-03-15T16:07:35.511Z info:
No session IDs specified, meaning that all existing sessions will be deleted for proxy "pro2-win1.lab.ptarmiganlabs.net" and virtual proxy "finance".
Are you sure you want to continue? (y/n) y
2024-03-15T16:07:39.258Z info:
2024-03-15T16:07:39.258Z info: Deleting sessions...
2024-03-15T16:07:39.328Z info: Session ID "940aa6f6-2738-495c-b994-bb1b03b0fabd" successfully deleted. User: LAB\testuser_2
2024-03-15T16:07:39.426Z info: Session ID "f9de752e-e7ae-4194-ab93-520e98bdc048" successfully deleted. User: LAB\testuser_1
2024-03-15T16:07:39.466Z info: Session ID "6171e788-ae6a-49ed-8900-26e2cc8837f8" successfully deleted. User: LAB\testuser_2
2024-03-15T16:07:39.507Z info: Session ID "d5845fb8-ce38-49c3-bb34-fb3c2b9c654d" successfully deleted. User: LAB\testuser_1
2024-03-15T16:07:39.543Z info: Session ID "819cccd8-2b7d-43c2-bed0-d784b8e85cb3" successfully deleted. User: LAB\testuser_2
2024-03-15T16:07:39.543Z info:
2024-03-15T16:07:39.543Z info: Deleted 5 sessions
Authenticating with Sense
For completeness a few words about authentication are also needed.
Both examples above use certificates to authenticate with Qlik Sense. In fact, certificate authentication is the only option. But where are the certificate files stored?
If we look at the output when running ctrl-q session-get --help
we see that the default values for the auth-cert-file
, --auth-cert-key-file
and --auth-root-cert-file
options is to store the respective files in a directory called cert
below the directory where Ctrl-Q was started:
-a, --auth-type <type> authentication type (choices: "cert", default: "cert")
--auth-cert-file <file> Qlik Sense certificate file (exported from QMC) (default: "./cert/client.pem")
--auth-cert-key-file <file> Qlik Sense certificate key file (exported from QMC) (default: "./cert/client_key.pem")
--auth-root-cert-file <file> Qlik Sense root certificate file (exported from QMC) (default: "./cert/root.pem")
In the examples above that directory indeed exists and contains the certificate files:
➜ ls -la cert/
total 24
drwxr-xr-x 5 goran staff 160 Mar 15 17:28 .
drwxr-xr-x 11 goran staff 352 Mar 15 15:05 ..
-rw-r--r--@ 1 goran staff 1170 Oct 14 2022 client.pem
-rw-r--r--@ 1 goran staff 1704 Oct 14 2022 client_key.pem
-rw-r--r--@ 1 goran staff 1224 Oct 14 2022 root.pem
➜
If the certificate files are stored elsewhere just include the appropriate options when calling Ctrl-Q and things will work as above.