License Server

License Server Logging

The Squish License Server sends its log messages to a platform-specific destination by default.

License Server Logging on Linux

When Squish License Server is installed as a systemd service on Linux, it writes log messages via the standard syslog interface and they will be stored as part of the systemd journal. To see today's log messages, execute journalctl --since today -u squish-license-server.service as an administrator.

Example log output:

$ journalctl -u squish-license-server.service --since today
-- Logs begin at Tue 2021-08-31 19:17:32 CEST, end at Fri 2022-01-21 12:32:57 CET. --
Jan 21 09:43:18 host systemd[1]: Starting Squish Floating License Server...
Jan 21 09:43:18 host systemd[1]: Started Squish Floating License Server.
Jan 21 09:43:18 host licenseserver[1477]: Searching for license files (*.cfg) in '/etc/squish-license-server/licenses'
Jan 21 09:43:18 host licenseserver[1477]: Starting Squish License Server 7.0.0 on machine id f7ff1122a223344f5544ff00
Jan 21 09:43:18 host licenseserver[1477]: Loading server settings from '/etc/squish-license-server/licenses/my_license.settings.ini'
Jan 21 09:43:18 host licenseserver[1477]: Serving REST API on [0.0.0.0]:47001
Jan 21 09:43:18 host licenseserver[1477]: [my_license] Serving 10 tester and 10 execution licenses on [0.0.0.0]:49345, host:49345

Jan 21 09:43:18 host licenseserver[1477]: Announcing server via SSDP as licenseserver://host:49345
Jan 21 12:12:47 host systemd[1]: squish-license-server.service: Succeeded.

Additional ways to filter, limit or follow log messages as they are created can be found in systemd's journalctl manual.

License Server Logging on macOS

When Squish License Server is installed as a service on macOS, it writes log messages via the standard syslog interface and they will be stored as part of the Apple unified log system. To see today's log messages, execute log show --process licenseserver --style compact --info --last 1d as an administrator.

Example log output:

$ log show --process licenseserver --style compact --info --last 1d
Filtering the log data using "process BEGINSWITH[cd] "licenseserver""
Skipping debug messages, pass --debug to include.
Timestamp               Ty Process[PID:TID]
2022-01-25 09:35:51.057 I  licenseserver[736:2989] Searching for license files (*.cfg) in '/etc/squish-license-server/licenses'
2022-01-25 09:35:51.058 I  licenseserver[736:2989] [com.apple.CarbonCore:coreservicesdaemon] SCSession SCSession( id=100, this=0x0x7fd9b1508070 option=65538) created, forUID=0 mach_port_t=0x2503.
2022-01-25 09:35:51.058 I  licenseserver[736:2989] [com.apple.CarbonCore:coreservicesdaemon] SCSession SCSession( id=101, this=0x0x7fd9b1508180 option=65538) created, forUID=0 mach_port_t=0x2603.
2022-01-25 09:35:51.058 I  licenseserver[736:2989] [com.apple.CarbonCore:coreservicesdaemon] connectToCoreServicesD Instantiating server (coreservicesd based) SCSession, port=0x2503 serverOptions=0x10002.
2022-01-25 09:35:51.059 I  licenseserver[736:2989] Starting Squish License Server 7.0.0 on machine id f7ff1122a223344f5544ff00
2022-01-25 09:35:51.060 I  licenseserver[736:2989] Saving default server settings to '/etc/squish-license-server/licenses/my_license.settings.ini'
2022-01-25 09:35:51.062 I  licenseserver[736:2989] No listen address/port configured, disabling REST API
2022-01-25 09:35:51.064 I  licenseserver[736:2989] [my_license] Serving 10 tester and 10 execution licenses on [0.0.0.0]:49345, host:49345
2022-01-25 09:35:51.064 I  licenseserver[736:2989] Announcing server via SSDP as licenseserver://host:49345

License Server Logging on Windows

When running as a Windows Service, Squish License Server will write its log messages to C:\ProgramData\Squish License Server\log\squish-license-server.log. The logfile will be limited to a maximum size of 2 MB and be rotated (i.e. renamed) automatically to keep up to 5 previous logfiles around.

Example logfile contents:

2022-01-31T13:33:25 Searching for license files (*.cfg) in 'C:\ProgramData\Squish License Server\licenses'
2022-01-31T13:33:25 Starting Squish License Server 7.0.0 Alpha on machine id f7ff1122a223344f5544ff00
2022-01-31T13:33:25 Saving default server settings to 'C:\ProgramData\Squish License Server\licenses\my_license.settings.ini'
2022-01-31T13:33:25 No listen address/port configured, disabling REST API
2022-01-31T13:33:25 [my_license] Serving 10 tester and 10 execution licenses on [0.0.0.0]:49345, host:49345
2022-01-31T13:33:25 Announcing server via SSDP as licenseserver://host:49345

Configuration

Squish License Server expects one or more license files whose filename ends with .cfg. By default it searches for license files in the following directory:

  • Linux and macOS: /etc/squish-license-server/licenses/
  • Windows: C:\ProgramData\Squish License Server\licenses\

In addition, per-license settings will be read from a file in the aforementioned directory with the same filename as the license file but ending in .settings.ini instead of .cfg. If this file does not exist then the server will create it with default values to serve as a template for editing. The following groups of settings can be modified by editing the settings file (followed by a server restart):

[License]
LeaseTime=0

LeaseTime is the maximum time in seconds that a connected client (like Squish IDE) can use a license. The default 0 (or an empty value) means that there's no limit of how long a client can hold onto a license. Set this to automatically disconnect clients if they use a license for "too long". Keep in mind that this also limits the maximum allowed time any automated Squish test execution can take because a loss of license will abort script execution.

[REST]
AnonymousReadAccess=true
ListenAddress=
ListenPort=
ReadAccessTokens=

AnonymousReadAccess controls whether unauthenticated HTTP GET requests to the REST API are allowed. If set to false, you will also need to add one or more tokens to REST/ReadAccessTokens to make use of the REST API.

ListenAddress is the IP address to accept REST API requests on. If left empty, the REST API will be available on all network interfaces.

ListenPort is the TCP port number to accept REST API request on. If empty (or an invalid value), the REST API will be disabled. To enable the REST API, set an otherwise unused TCP port number (1 - 65535) here.

ReadAccessTokens is a comma-separated list of tokens for authenticated HTTP GET requests to the REST API. The tokens do not have a defined format (yet) but they cannot contain whitespace and we recommend to stick to ASCII characters to make it easy for clients to provide them in their HTTP requests.

[SSDP]
AnnouncementHostName=
AnnouncementPort=
Enabled=true

AnnouncementHostName is the (DNS) hostname used in network-wide SSDP announcements. Change this value if the hostname that clients should connect to differs from the local hostname of the system.

AnnouncementPort is the TCP port number used in network-wide SSDP announcements. If empty (or an invalid value), the TCP port number from the license configuration will be used. Change this value when some sort of redirection or tunneling requires clients to connect to a different TCP port number (1 - 65535) than the one the server is actually listening on.

Enabled is the switch for enabling/disabling SSDP announcements. The default value is true. If set to false, SSDP announcements will be disabled.

REST API

Squish License Server supports querying information about itself, connected clients as well as statistics about license usage via a HTTP-based REST API. This functionality is disabled by default and can be enabled by setting a valid TCP port number in the settings file, see REST/ListenPort.

Clients need to be able to issue HTTP requests (currently limited to GET requests) and will receive a JSON-formatted reply both in case of success or errors. By default requests do not require any form of authentication. Administrators can configure the server to require HTTP Bearer Token Authentication, see REST/ReadAccessTokens.

This document uses the commandline tools curl and jq in its commandline examples to create HTTP requests and format the resulting JSON output.

Currently the following API endpoints are available:

/v1/clients

Returns an array of connected clients. A client object can contain the following properties:

  • clientAddress: IP address of the connected client.
  • clientPort: Server-side port number of the connection.
  • grantTime: ISO timestamp of the time a license was granted to this client. Empty if the client did not receive a license yet.
  • licenseType: Type of license requested by the client. Possible values include execution and tester or an empty string in case the client did not request a license so far.
  • machineId: Internal identifier of the connected client.
  • requestTime: Time when the client requested a license. Empty string if the client did not request a license so far.

Example curl request:

curl -s "http://localhost:47001/v1/clients" | jq

Example JSON response:

[
  {
    "clientAddress": "::ffff:127.0.0.1",
    "clientPort": 44198,
    "grantTime": "2022-01-05T11:34:37.732Z",
    "licenseType": "tester",
    "machineId": "{5544eebb-1234-4a00-abcd-7a7a7aff99d2}",
    "requestTime": "2022-01-05T11:34:37.732Z"
  }
]

/v1/serverinfo

Returns an object with information about the license served to clients. The following properties can be present:

  • customerNumber: Internal number of the customer owning the license.
  • editions: Array of strings for the product editions supported by the license.
  • expirationDate: ISO date when the served license will expire. Clients connecting after this date will not receive a license anymore!
  • issueDate: ISO date when the served license was issued to the customer.
  • machineId: Internal identifier for the host running the server.
  • port: TCP port number the server accepts license requests on.

Example curl request:

curl -s "http://localhost:47001/v1/serverinfo" | jq

Example JSON response:

{
  "customerNumber": 12345,
  "editions": [
    "Squish/Qt"
  ],
  "expirationDate": "2023-01-23",
  "issueDate": "2021-01-22",
  "machineId": "ca3ff112233001122abcdabcd",
  "port": 49345
}

/v1/statistics

Returns an object containing statistics about clients and how long they waited for a license. Currently statistics are not kept during a server restart but this may change in a future release.

  • activeLicenses: Counts the number of licenses that are in use for the individual license types. Contains an execution and tester sub-object with the following properties:
    • current: Number of actively used licenses at the time of the HTTP request.
    • max: Maximum number of active licenses (determined by the license configuration file).
    • peak: Highest number of actively used licenses since the last statistics reset.
  • waitingQueue: Counts the number of clients waiting for an unused license. Contains an execution and tester sub-object, each with the following properties:
    • current: Number of clients waiting for a license at the time of the HTTP request.
    • peak: Highest number of clients waiting for a license since the last statistics reset.
  • waitingTimeInMs: Duration of clients waiting for an unused license. Contains an execution and tester sub-object, each with the following properties:
    • current: Duration (in milliseconds) of the longest waiting client right now.
    • peak: Highest duration a client was waiting for an unused license since the last statistics reset.

These statistics can serve as a way to find out if the number of tester and execution seats is enough for all users. Especially the peak values can tell when more seats are needed to not keep users or automated tests waiting for a free license.

Example curl request:

curl -s http://localhost:47001/v1/statistics | jq

Example JSON response:

{
  "activeLicenses": {
    "execution": {
      "current": 0,
      "max": 10,
      "peak": 0
    },
    "tester": {
      "current": 1,
      "max": 2,
      "peak": 1
    }
  },
  "waitingQueue": {
    "execution": {
      "current": 0,
      "peak": 0
    },
    "tester": {
      "current": 0,
      "peak": 1
    }
  },
  "waitingTimeInMs": {
    "execution": {
      "current": 0,
      "peak": 0
    },
    "tester": {
      "current": 0,
      "peak": 16637
    }
  }
}