Skip to main content

Chronicle

Warning

Chronicle is a preview feature. Its configuration, data formats, and behavior may change in future releases.

Posit Chronicle is a self-hosted observability service that collects session telemetry, audit events, and runtime metrics from Posit Connect. It stores that data as CSV and Parquet files on a local or shared filesystem, where downstream tools can query it without depending on an external observability backend.

For a full description of the data Chronicle collects, including the curated data sets and their schemas, see the Posit Chronicle documentation.

System requirements

Chronicle runs alongside Connect on the same host. The recommended minimum resources are:

Resource Minimum
CPU 1 core
Memory 1 GB RAM
Disk 15 GB

Disk usage scales with the number of content items, users, and visits. Larger installations may require significantly more disk space.

Connect’s installer creates the posit-chronicle system user and group automatically; no manual account setup is needed.

Enabling Chronicle

Add the following to your Connect configuration file:

/etc/rstudio-connect/rstudio-connect.gcfg
[Chronicle]
Enabled = true
LocalStorageEnabled = true

[Metrics]
PrometheusListen = ":3232"

[OpenTelemetry]
Enabled = true

Prometheus metrics must be enabled for Chronicle to run. Chronicle scrapes runtime resource metrics from Connect’s /metrics endpoint over a network address, so PrometheusListen must be set.

OpenTelemetry must be enabled for Chronicle to record content visits, publish events, and other usage events. Without it, Chronicle runs and Connect reports it as ready, but Chronicle collects only metrics and API data. See Usage events.

At least one storage backend must be configured. See Storage for S3 and local options.

Connect starts Chronicle as a managed subprocess and automatically provisions a service token for it. After you first enable Chronicle, restart Connect. A configuration reload that enables Chronicle starts it, and Connect reports it as ready, but Chronicle records no usage events until Connect restarts. This applies even when Metrics.PrometheusListen and OpenTelemetry.Enabled are already set. Visits made before the restart are not recorded. Once Chronicle is running with usage events, a reload applies changes to the other Chronicle settings without a restart. The Metrics.PrometheusListen and OpenTelemetry.Enabled settings are not reloadable. If either is not already set when Connect starts, add it and restart Connect. Chronicle also requires HTTP.Listen or HTTPS.Listen, and neither setting is reloadable. If Connect listens only on a Unix domain socket, add one of them and restart Connect.

Connect validates the Chronicle settings at startup and on each configuration reload. If Chronicle is enabled and its configuration is invalid, Connect does not start, and a reload keeps the previous configuration. See Common issues for the settings Connect checks.

Connect creates the local storage directory only at startup. A reload checks that LocalStorageLocation exists and keeps the previous configuration if it does not. To enable local storage at a new LocalStorageLocation with a reload, create the directory first and make it writable by the user Chronicle runs as. Otherwise, restart Connect so that it creates the directory with the correct ownership. Chronicle runs as posit-chronicle when Connect runs as root, and as the Connect user otherwise.

Storage

Chronicle supports two storage backends: local filesystem and Amazon S3. At least one must be enabled. Both can be enabled simultaneously.

Local storage

Chronicle writes local data to /var/lib/posit-chronicle/data by default. Use LocalStorageLocation to customize the path.

/etc/rstudio-connect/rstudio-connect.gcfg
[Chronicle]
Enabled = true
LocalStorageEnabled = true

The LocalStorageAccess setting controls file permissions on the data directory:

Value Description
all Any user on the system can read the files
group Only members of the posit-chronicle group can read the files (default).
owner Only the Chronicle process can read the files.

Granting content access to Chronicle data

Content deployed to Connect (such as the Chronicle Reports dashboard) needs read access to the Chronicle Parquet files. How you grant that access depends on the storage backend.

Local storage: With the default group access, files in the local storage directory are readable only by members of the posit-chronicle group. Rather than loosening file permissions with LocalStorageAccess = all, an administrator can create a Unix account that is a member of the posit-chronicle group, then configure the content to run as that user. Connect executes content under the Applications.RunAs user, which an administrator can override per content item on the Runtime tab of the content settings panel. As long as that account belongs to the posit-chronicle group, its content processes can read the data files without changing the LocalStorageAccess setting. The group default is intentional: it keeps Chronicle data from being readable by every user on the host. Administrators grant access deliberately through group membership rather than exposing data by default.

S3 storage: When Chronicle writes to S3, content reads directly from the bucket using AWS credentials. Configure an AWS integration so that content assumes an Identity and Access Management (IAM) role scoped to the Chronicle bucket. Grant that role s3:GetObject and s3:ListBucket permissions on the Chronicle bucket and prefix. No file-system permission configuration is required.

Multi-node setups

In multi-node deployments, LocalStorageLocation must point to shared storage (for example, NFS or Amazon EFS) so that all nodes write to the same location. However, ConfigDir must remain a node-local path because each Connect replica runs its own Chronicle process.

The installer creates the posit-chronicle user and group automatically, assigning the next available system UID and GID on each host. As described in Consistent users and groups, shared storage such as NFS or EFS enforces permissions by numeric ID, so the posit-chronicle user’s UID and group’s GID must be identical on every node for Chronicle to read and write shared data across nodes.

The IDs may line up on their own, but they can diverge when hosts have different existing accounts. To check, compare the IDs reported on each node:

Terminal
id posit-chronicle

If the IDs differ, align them so that posit-chronicle has the same UID and GID across all nodes. To avoid the requirement entirely, use S3 storage instead of local storage. Chronicle never writes to the shared filesystem when using S3, so no UID/GID alignment is required.

Off-host execution (Kubernetes)

In an off-host execution (Kubernetes) deployment, Connect runs a separate Chronicle process inside each Connect pod. Because every pod runs its own process, all pods must write to a single shared destination. Choose a storage backend based on where Connect runs:

  • On AWS: Use S3 storage. Each pod writes to the same bucket, so you do not need a shared volume.
  • On other platforms: Use local storage backed by a shared filesystem that every Connect pod can read and write.

When using local storage, provision a dedicated shared location for Chronicle data. Do not place it inside the Connect data directory (Server.DataDir); the Chronicle data must be a separate location, even if it uses the same class of shared storage.

S3 storage

To write Parquet files to an S3 bucket:

/etc/rstudio-connect/rstudio-connect.gcfg
[Chronicle]
Enabled = true
S3StorageEnabled = true
S3Bucket = my-chronicle-bucket
S3Region = us-east-1

Both S3Bucket and S3Region are required when S3 storage is enabled. You can optionally set S3Prefix to organize files under a key prefix, and S3Profile to use a specific AWS credentials profile.

Chronicle uses the standard AWS credential chain. If S3Profile and S3Region are not set, Chronicle falls back to the AWS_PROFILE and AWS_REGION environment variables.

Usage events

Connect sends usage events to Chronicle as OpenTelemetry log events through the embedded OpenTelemetry Collector. These events include content visits (connect.content.hit) and content publishes (connect.content.published). Chronicle builds the connect_content_hits data set from the visit events, and the Connect Usage report in Chronicle Reports reads data sets built from it.

Connect forwards these events only when both Chronicle.Enabled and OpenTelemetry.Enabled are true at startup:

/etc/rstudio-connect/rstudio-connect.gcfg
[Chronicle]
Enabled = true

[OpenTelemetry]
Enabled = true

If OpenTelemetry.Enabled is false, Chronicle receives no usage events, and the connect_content_hits data set is never created. Connect does not log a warning in this case.

The OpenTelemetry.Enabled setting is not reloadable. If a configuration reload enables Chronicle, restart Connect to start forwarding usage events to Chronicle.

To check that Chronicle receives usage events, look for a LogOTLPEndpoint setting in the generated configuration.

Connect forwards usage events through an OTLP endpoint named chronicle. It replaces any [OTLPEndpoint "chronicle"] section in your configuration, including its headers and signal settings. Give your own OTLP endpoints a different name.

Environment labeling

Use the Environment setting to tag data with a label identifying this deployment:

/etc/rstudio-connect/rstudio-connect.gcfg
[Chronicle]
Enabled = true
Environment = production

This label appears in Chronicle reports and can be used to filter or group data across multiple deployments (for example, separating production from staging).

Troubleshooting

Log files

After Chronicle loads its configuration, it writes its logs to:

/var/log/rstudio/connect-chronicle/chronicle.log

If Chronicle fails before it loads its configuration, its output is written to the Connect server log. Search for log entries with subprocess=chronicle.

Generated configuration

Connect writes a runtime configuration file for Chronicle at:

/etc/rstudio-connect/chronicle/connect-chronicle.gcfg

This file is generated automatically by Connect. Do not edit it directly. Inspecting it can be useful for verifying that Chronicle is configured as expected.

Common issues

Connect fails to start after enabling Chronicle

Connect exits with an Unable to apply the configuration error that names the Chronicle setting at fault. Connect checks the following when Chronicle.Enabled is true:

  • Metrics.PrometheusListen is set.
  • HTTP.Listen or HTTPS.Listen is set. Chronicle reads the Connect API over a network address, so a Unix domain socket listener such as HTTP.UnixDomainSocket is not enough on its own.
  • ConfigDir is no longer than 95 bytes. Chronicle creates its Unix socket in this directory, and Linux limits the length of a socket path in bytes. A non-ASCII character, such as é, takes more than one byte.
  • At least one of LocalStorageEnabled or S3StorageEnabled is true.
  • LocalStorageLocation is an absolute path, when local storage is enabled.
  • LocalStorageLocation exists or Connect can create it, when local storage is enabled. A read-only file system or a parent directory that Connect cannot write to causes this check to fail. On a configuration reload, Connect checks that LocalStorageLocation exists but does not create it.
  • S3Bucket is set, when S3 storage is enabled.
  • LocalStorageAccess, if set, is all, group, or owner.

Correct the setting, or set Chronicle.Enabled = false, and restart Connect.

A configuration reload does not apply the Chronicle settings
Connect logs a Cannot reload the configuration error that names the Chronicle setting at fault and keeps running with its previous configuration. Connect checks the same settings as at startup, except that it checks that LocalStorageLocation exists and does not create it. Correct the setting and reload the configuration again. A reload cannot apply Metrics.PrometheusListen, HTTP.Listen, or HTTPS.Listen. If the error names one of these settings, set it and restart Connect. Connect also logs a warning that names the changed settings a reload does not apply. Restart Connect to apply them.
Chronicle fails to start
Check the Connect server log for entries with subprocess=chronicle. If Chronicle loaded its configuration, also check the Chronicle log file. Common causes include insufficient permissions on the data directory or invalid S3 credentials.
No content visit data
The connect_content_hits data set is missing, or the Connect Usage report in Chronicle Reports shows no visits. Check that OpenTelemetry.Enabled is true and restart Connect. See Usage events.
Disk usage growing unexpectedly
Chronicle’s disk usage scales with the number of content items, users, and visits. Monitor the data directory and increase disk allocation as needed.
S3 access denied
Verify that the AWS credentials available to Chronicle have s3:PutObject, s3:GetObject, s3:ListBucket, and s3:DeleteObject permissions on the configured bucket and prefix.

Configuration reference

For the full list of [Chronicle] settings, see the configuration appendix.