Configuring plintz¶
Two files configure the stack, both in deploy/ and both kept out of Git: .env holds the secrets, and plintz.yaml is the deployment config. Create them from their examples:
cp .env.example .env
cp plintz.example.yaml plintz.yaml
Secrets¶
.env has these variables:
| Variable | What it is |
|---|---|
POSTGRES_PASSWORD |
The password of the postgres service's database. Required: Compose refuses to start without it. Use URL-safe characters only, because Compose builds the backend's DATABASE_URL from it, overriding any DATABASE_URL in .env. |
OIDC_CLIENT_SECRET |
The client secret of plintz at your OpenID Connect provider. See Sign-in. |
INVALIDATION_TOKEN |
The Invalidation service token. See Invalidation service token. |
PLINTZ_HTTP_PORT |
The host port of the Workbench. 8080 if left out. |
Every variable in .env reaches the backend container's environment, and plintz.yaml refers to it as ${NAME}. To give a Datasource a secret, add NAME=value to .env and write ${NAME} in plintz.yaml. A ${NAME} that is not set in the environment stops the backend at startup: environment variable NAME is not set.
The deployment config¶
plintz.yaml is mounted into the backend container, read-only, as /etc/plintz/plintz.yaml. It is read once, when the backend starts. After editing plintz.yaml or .env, recreate the backend:
docker compose up -d --force-recreate --no-deps backend
An unknown key, a missing required one or an invalid value stops the backend at startup, with the problem in its log. See When startup fails. The keys:
| Key | Meaning |
|---|---|
database_url |
The PostgreSQL database. Keep the example's ${DATABASE_URL}, which Compose sets. |
oidc |
The OpenID Connect provider users sign in with. Required. See Sign-in. |
invalidation_token |
The Invalidation service token. Required. |
cache_dir |
Where the block cache's files go. Keep the example's /var/lib/plintz/cache, where the block-cache volume is mounted. The default, .cache, is not writable in the container, so leaving the key out stops the backend. |
cache_disk_budget_gib |
The most disk space, in GiB, that the files in cache_dir may use. Required, with no default. Set it below the free space of the block-cache volume. See The block cache's disk budget. |
indexing_interval_seconds |
How often Indexing runs, in seconds. 300 (five minutes) if left out. |
max_points |
The most points an XY Plot draws, from 1,000 to 1,000,000. 150,000 if left out. See XY Plot points. |
administrators |
The users who are Administrators. None if left out. See Administrators. |
datasources |
The Datasources. At least one is required. See Datasources. |
XY Plot points¶
An XY Plot draws at most max_points points. If the two Signals have no more than that many distinct Sample timestamps in the Display Range, the plot uses each timestamp and interpolates both Signals there. If they have more timestamps, the plot uses max_points evenly spaced times from the Display Range's start to its end and interpolates both Signals at those times. The plot omits a point if either Signal has no value because the time falls in a gap wider than its Maximum Interpolation or outside its Boundary Samples.
max_points must be a whole number from 1,000 to 1,000,000. Any other value stops the backend at startup, with a message naming that range. A higher value includes more data in a long Display Range, but increases the amount plintz reads, computes and sends on every refresh.
Datasources¶
Each entry of datasources is one Datasource:
| Key | Meaning |
|---|---|
id |
The Datasource's name in plintz, 1 to 255 characters. Unique. |
connector |
The built-in Connector that reads the Datasource. Set it to databricks or synthetic. There are no other Connectors. |
uncertainty_lag_seconds |
The Datasource's Uncertainty Lag, in seconds. 3600 (one hour) if left out. |
options |
The Connector's options, below. |
The Uncertainty Lag sets how far before now the Datasource's uncertain region begins. Samples at or after that point are Uncertain Data. They may still change, so plintz never caches them and reads them from the Datasource on every request. A longer Uncertainty Lag keeps more recent data out of the cache. Administrators can replace it for one Stored Signal with an Uncertainty Override (see Item properties).
Don't rename a Datasource. Analyses refer to a Stored Signal by its Datasource's id and its Data ID. Changing the id creates a different Datasource. Follow the instructions for removing and adding back a Datasource.
Databricks¶
A Databricks Datasource reads Stored Signals in place from two Databricks tables, typically liquid-clustered on (timestamp, tag_id):
- id: lakehouse
connector: databricks
options:
server_hostname: adb-1234567890123456.7.azuredatabricks.net
http_path: /sql/1.0/warehouses/1234567890abcdef
sample_table: main.plant.samples
metadata_table: main.plant.tags
columns:
timestamp: timestamp
data_id: tag_id
value: value
name: name
description: description
unit_of_measure: unit
All the options are required, except the metadata table's interpolation_method and maximum_interpolation columns, which the example leaves out:
server_hostnameandhttp_path: use the values shown in the SQL warehouse's Connection details in Databricks.sample_table: the table of Samples, one row per Data ID and timestamp, ascatalog.schema.table.metadata_table: the table with one row per Stored Signal, read at Indexing.columns: the table's column names.timestamp(aTIMESTAMP),data_id(the Data ID, such astag_id, which both tables have) andvaluebelong to the sample table.name,descriptionandunit_of_measurebelong to the metadata table. The metadata table may also haveinterpolation_method(Step,LinearorPILinear, matched case-insensitively) andmaximum_interpolation(a duration such as2dayor40h). If either column is absent or its value is NULL, Indexing uses the corresponding default:Stepor 40 hours.
The Connector authenticates to Databricks as an OAuth service principal using machine-to-machine authentication. Put its client ID and secret in .env as DATABRICKS_CLIENT_ID and DATABRICKS_CLIENT_SECRET. The backend won't start without them when a Databricks Datasource is configured. The service principal needs access to the warehouse, and to read both tables.
Each query carries Databricks query tags that you can group by in system.query.history. plintz_user identifies the user who caused the query, not their name or email. plintz_analysis identifies the Analysis when the request came from one. plintz_items lists the Items the query reads, and plintz_items_omitted counts those left out to keep the tag within 128 characters. User-triggered Indexing carries only the user tag. Scheduled Indexing is untagged. Databricks query tags are in Public Preview. If Databricks rejects them, the queries run without tags and plintz logs a message once per Datasource each time the backend starts. See Logs.
Synthetic¶
The Synthetic Connector generates Samples, so you can try plintz without Databricks. The example config declares a Datasource that uses it, synthetic. It has no Samples at or after now. Its options, all optional:
sample_rate_seconds: the Sample interval. 60 if left out.noise_seed: the seed of its noise. 17 if left out.demo_signals:trueadds Stored Signals that demonstrate interpolation, and a pump with its speed, discharge pressure, motor temperature and vibration for trending, XY Plots and Capsules. Search for "Demo" to find them. Off if left out.fetch_rollups:falsemakes plintz compute Rollups from the Samples, instead of the Connector. On if left out.
Checking the running stack searches for the Synthetic Datasource's Stored Signal sine, so keep it in the config if you use the smoke test.
Sign-in¶
Users sign in through your OpenID Connect provider, using the Authorization Code Flow. Register plintz with it as a client, with the redirect URI <Workbench URL>/api/auth/callback, such as https://plintz.example.com/api/auth/callback. Then set, under oidc:
issuer: the provider's issuer URL. Its discovery document must be at<issuer>/.well-known/openid-configurationand name exactly this issuer.client_idandclient_secret: the client you registered. Reference the secret from.env, as${OIDC_CLIENT_SECRET}. plintz authenticates to the token endpoint withclient_secret_basic, orclient_secret_postif that is all the provider supports.redirect_uri: the redirect URI you registered, character for character. Session cookies areSecurewhen it ishttps.
plintz requests the openid profile email scopes. The provider must supply the email claim and the name claim (or given_name and family_name), in the ID token or from its UserInfo endpoint. plintz identifies a user by the issuer and the sub claim, and creates them at their first login. A session lasts 24 hours from login.
The development stack's fake OpenID Connect provider authenticates no one. Anyone can sign in as any username. Never use it as the issuer of a real deployment.
Administrators¶
Administrators are the only users who override a Stored Signal's properties or move a Stored Signal to the Trash, which changes it for every user, and who use the Administration page, where they disable and enable users, manage Groups, see the Datasources and the effective configuration, run Indexing on demand and clear a Datasource's cache. List them under administrators by username, which is the sub claim of your provider. There are none unless you list them.
administrators:
- 1f3c9a52-77de-4c0b-9f8e-2b6d4a1e0c33
The username may differ from the name a user types to sign in. After signing in, users can open /api/users/me in their browser. Add the value of username to the list. The administrator field shows whether they are an Administrator. Recreate the backend after changing the list.
Invalidation service token¶
Data pipelines authenticate to the Invalidation API with the service token invalidation_token, which is required. Put a long random value in .env as INVALIDATION_TOKEN, for example from openssl rand -hex 32, and reference it as ${INVALIDATION_TOKEN}. A user's session doesn't authenticate to the Invalidation API, and the token authenticates to nothing else. Give the token to the pipelines that need it, and to no one else. See Cache invalidation.