Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# AGENTS.md

## Project Conventions

- The project uses the `speq` skill, see https://github.com/marconae/speq-skill
- The project uses OpenFastTrace (OFT).
- Reference skill: https://github.com/itsallcode/openfasttrace/blob/main/skills/openfasttrace-skill/SKILL.md

## OpenFastTrace Artifact Types

- `feat`: high level features in the mission
- `req`: requirements in the speq spec files
- `impl`: implementation in code
- `utest`: unit tests
- `itest`: integration tests

## Tag Maintenance

- Always add or update OpenFastTrace tags for features, requirements, and code tags when updating the mission or speq spec files.

## Validation

- Ensure that all requirements are covered by running `mvn generate-sources org.itsallcode:openfasttrace-maven-plugin:trace`.
13 changes: 8 additions & 5 deletions dependencies.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

42 changes: 31 additions & 11 deletions doc/app-user-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,17 @@ This guide is for end users of applications that use `telemetry-java`.

It explains:

- which data is collected
- how to see whether telemetry is enabled
- what data is collected
- how to tell whether telemetry is enabled
- how to disable telemetry

## What Is Collected?

The library collects only the data needed for feature-usage telemetry:
The library collects only the data required for feature-usage telemetry:

- product name, sent as the telemetry category
- the product name, sent as the telemetry category
- product version
- which application features are used
- which features are used
- when those features are used

It does not collect:
Expand All @@ -31,22 +31,42 @@ For Exasol's general privacy information, see the [Exasol Privacy Policy](https:

## How To See Whether Telemetry Is Enabled

Applications can use lifecycle log messages from the library to show whether telemetry is enabled or disabled.
Applications can use lifecycle log messages from the library to indicate whether telemetry is enabled or disabled.

When telemetry is disabled, the library does not enqueue or send usage events.
When telemetry is disabled, the library does not queue or send usage events.

## How To Disable Telemetry

Host applications can disable telemetry globally by setting environment variable `EXASOL_TELEMETRY_DISABLE` to any non-empty value.
### In Java-Based Virtual Schemas

In Exasol UDFs, set the environment variable in the script definition with `%env`. Example:
When you create or update a Java-based virtual schema, disable telemetry by setting the adapter property `TELEMETRY=false`. Example:

```sql
CREATE VIRTUAL SCHEMA hive USING adapter.jdbc_adapter
WITH
CONNECTION_STRING = 'jdbc:hive2://localhost:10000/default'
// ...
TELEMETRY = 'false';
```

See the [documentation](https://docs.exasol.com/db/latest/sql/create_schema.htm) for details.

### In General Java-Based Exasol UDFs

Set the environment variable `EXASOL_TELEMETRY_DISABLE` to any non-empty value in the script definition with `%env`. Example:

```sql
CREATE OR REPLACE JAVA SCALAR SCRIPT MY_UDF(...) RETURNS VARCHAR(100) AS
%env EXASOL_TELEMETRY_DISABLE=1;
/
```

In Exasol UDF script options, each environment variable declaration must end with a semicolon and the value must not be quoted.
In Exasol UDF script options, each environment variable declaration must end with a semicolon, and the value must not be quoted. See the [UDF documentation](https://docs.exasol.com/db/latest/database_concepts/udf_scripts/udf_overview.htm#Environmentvariables) for details.

### In Other Applications

Disable telemetry by setting the environment variable `EXASOL_TELEMETRY_DISABLE` to any non-empty value.

### In Continuous Integration

Telemetry is also disabled automatically when environment variable `CI` is set to any non-empty value, so CI and test environments do not emit usage data by default.
Telemetry is also disabled automatically when the environment variable `CI` is set to any non-empty value. This ensures that CI and test environments do not emit usage data by default.
8 changes: 7 additions & 1 deletion doc/changes/changes_0.1.0.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Telemetry Java 0.1.0, released 2026-??-??
# Telemetry Java 0.1.0, released 2026-04-16

Code name: Initial Release

Expand All @@ -9,6 +9,11 @@ Initial release of the telemetry-java library.
## Features

* #2: Create initial version
* #6: Add category (project tag) and product version to message

## Documentation

* #3: Add requirements tracing using OFT

## Dependency Updates

Expand Down Expand Up @@ -42,6 +47,7 @@ Initial release of the telemetry-java library.
* Added `org.apache.maven.plugins:maven-surefire-plugin:3.5.4`
* Added `org.apache.maven.plugins:maven-toolchains-plugin:3.2.0`
* Added `org.basepom.maven:duplicate-finder-maven-plugin:2.0.1`
* Added `org.codehaus.mojo:build-helper-maven-plugin:3.6.1`
* Added `org.codehaus.mojo:flatten-maven-plugin:1.7.3`
* Added `org.codehaus.mojo:versions-maven-plugin:2.21.0`
* Added `org.itsallcode:openfasttrace-maven-plugin:2.3.0`
Expand Down
10 changes: 10 additions & 0 deletions doc/developer-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,13 @@ Standard Maven commands are used:
## Project Workflow

This project uses `speq-skill` and recorded specs for mission definition, planning, implementation, verification, and recording into the permanent spec library. See [speq-skill documentation](https://github.com/marconae/speq-skill?tab=readme-ov-file) for details.

## OpenFastTrace Requirement Tracing

OpenFastTrace tags are included in the speq-skill spec to avoid duplication.

Tracing runs in the Maven `verify` phase. You can specifically run tracing using this command:

```sh
mvn generate-sources org.itsallcode:openfasttrace-maven-plugin:trace
```
4 changes: 2 additions & 2 deletions doc/integration-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ Example changelog entry:
```markdown
## Added

- Added anonymous feature-usage telemetry via `telemetry-java`. See the [documentation](app-user-guide.md) for details on collected data and opt-out behavior.
- Added anonymous feature-usage telemetry via `telemetry-java`. See the [documentation](https://github.com/exasol/telemetry-java/blob/main/doc/app-user-guide.md) for details on collected data and opt-out behavior.
```

Example end-user documentation entry:
Expand All @@ -40,7 +40,7 @@ Example end-user documentation entry:

This application uses `telemetry-java` to send anonymous feature-usage events.

For details on what is collected and how to disable telemetry, see the [documentation](app-user-guide.md).
For details on what is collected and how to disable telemetry, see the [documentation](https://github.com/exasol/telemetry-java/blob/main/doc/app-user-guide.md).
```

## Environment Variables
Expand Down
20 changes: 20 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,26 @@
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>3.6.1</version>
<executions>
<execution>
<id>add-spec-to-source</id>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<!-- Add spec to OFT requirement tracing -->
<source>specs/</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.itsallcode</groupId>
<artifactId>openfasttrace-maven-plugin</artifactId>
Expand Down
18 changes: 18 additions & 0 deletions specs/config/client-identity/spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,16 @@

Defines the required product identity values that the host application configures once and the library attaches to every emitted telemetry message.

## Requirement: Client Identity
`req~client-identity~1`

The library shall require caller-configured identity values and attach them to emitted telemetry messages as described by the scenarios below.

Covers:
* `feat~client-identity~1`

Needs: impl, utest, itest

## Background

Telemetry messages carry three stable identity fields: `category`, which is the configured project tag; `version`, which is the telemetry protocol version; and `productVersion`, which is the integrating product or library version. Feature names remain arbitrary caller-provided strings and MUST NOT duplicate project identity.
Expand All @@ -14,3 +24,11 @@ Telemetry messages carry three stable identity fields: `category`, which is the
* *WHEN* the host application provides a blank project tag or a blank `productVersion`
* *THEN* the library SHALL reject configuration creation
* *AND* the library MUST require both values before a telemetry client can be created

### Scenario: Attaches configured identity values to emitted telemetry messages

* *GIVEN* the library is configured with a project tag and `productVersion`
* *WHEN* the library emits a telemetry message
* *THEN* the library SHALL emit the configured project tag as `category`
* *AND* the library SHALL emit the configured `productVersion` as `productVersion`
* *AND* the library SHALL keep `version` reserved for telemetry protocol version `0.2.0`
10 changes: 10 additions & 0 deletions specs/config/tracking-controls/spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,16 @@

Allows host applications and deployment environments to disable tracking or redirect telemetry delivery without code changes.

## Requirement: Tracking Controls
`req~tracking-controls~1`

The library shall resolve tracking controls from configuration and environment variables so telemetry can be disabled automatically or redirected to an overridden endpoint as described by the scenarios below.

Covers:
* `feat~tracking-controls~1`

Needs: impl, utest, itest

## Background

Tracking can be deactivated by `EXASOL_TELEMETRY_DISABLE` or automatically by `CI` when either environment variable is set to any non-empty value. If the host application does not configure an endpoint, the library uses `https://metrics.exasol.com`. The configured endpoint can be overridden by `EXASOL_TELEMETRY_ENDPOINT`.
Expand Down
10 changes: 10 additions & 0 deletions specs/delivery/async-delivery/spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,16 @@

Delivers accepted usage events to an HTTP endpoint without blocking the host application's main execution path.

## Requirement: Async Delivery
`req~async-delivery~1`

The library shall batch accepted telemetry events into protocol messages and deliver them asynchronously over HTTP with retry handling and bounded in-memory buffering as described by the scenarios below.

Covers:
* `feat~async-delivery~1`

Needs: impl, utest, itest

## Background

Accepted telemetry events are serialized to JSON and delivered via HTTP `POST` to a configured endpoint or the default endpoint `https://metrics.exasol.com`. The JSON payload contains `category`, protocol `version`, `productVersion`, `timestamp`, and `features` fields, and the library uses bounded in-memory buffering with no persistent local storage.
Expand Down
10 changes: 10 additions & 0 deletions specs/lifecycle/shutdown-flush/spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,16 @@

Ensures host applications can shut down cleanly while still giving queued telemetry an opportunity to be delivered.

## Requirement: Shutdown Flush
`req~shutdown-flush~1`

The library shall flush queued telemetry work during close and stop background delivery threads before shutdown completes as described by the scenarios below.

Covers:
* `feat~shutdown-flush~1`

Needs: impl, utest, itest

## Background

The telemetry client participates in application shutdown through `AutoCloseable`.
Expand Down
37 changes: 37 additions & 0 deletions specs/mission.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,43 @@ Application end users use the host application and, when they allow it, the appl
- Provide clean shutdown behavior and ensure queued usage data is sent during shutdown.
- Allow tracking to be deactivated via environment variables.

## Traceable Features

### Tracking API
`feat~tracking-api~1`

Provides the host-facing API for recording feature-usage events with minimal integration effort.

Needs: req

### Tracking Controls
`feat~tracking-controls~1`

Allows host applications and deployment environments to disable tracking or override telemetry delivery settings.

Needs: req

### Client Identity
`feat~client-identity~1`

Defines the required product identity values that the host application configures once and the library attaches to emitted telemetry messages.

Needs: req

### Async Delivery
`feat~async-delivery~1`

Delivers accepted telemetry events over HTTP without blocking the host application's calling thread.

Needs: req

### Shutdown Flush
`feat~shutdown-flush~1`

Ensures queued telemetry is flushed during shutdown and background work stops when the client closes.

Needs: req

## Out of Scope

The library does not collect:
Expand Down
26 changes: 14 additions & 12 deletions specs/tracking/tracking-api/spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,23 @@

Enables host applications to record allowed feature-usage events with minimal integration effort.

## Requirement: Tracking API
`req~tracking-api~1`

The library shall provide a tracking API that accepts feature-usage events from the host application, queues accepted tracking work for asynchronous delivery, and keeps the caller thread free of delivery work as described by the scenarios below.

Covers:
* `feat~tracking-api~1`

Needs: impl, utest, itest

## Background

The host application still configures project identity once at startup, but accepted feature names are transmitted as caller-provided strings. Project tag and `productVersion` are emitted separately as message metadata, while the JSON `version` field remains reserved for the telemetry protocol version. The library does not validate which feature names applications choose apart from ignoring `null` values.

## Scenarios

### Scenario: Records a tagged feature usage event
### Scenario: Records a feature usage event

* *GIVEN* the library is configured with a project short tag and `productVersion`
* *AND* tracking is enabled
Expand All @@ -19,25 +29,17 @@ The host application still configures project identity once at startup, but acce
* *AND* the library SHALL keep `version` reserved for protocol version `0.2.0`
* *AND* the library MUST NOT validate or reject the feature name based on application-defined naming choices

### Scenario: Rejects unsupported usage payloads

* *GIVEN* the library is configured and tracking is enabled
* *WHEN* the host application records usage data that contains unsupported fields
* *THEN* the library SHALL reject the event
* *AND* the library MUST NOT enqueue the rejected payload for delivery
* *AND* the library MUST NOT emit logs, stack traces, or PII in the protocol payload

### Scenario: Rejects tracking after the client is closed
### Scenario: Ignores tracking after the client is closed

* *GIVEN* the host application has closed the telemetry client
* *WHEN* the host application records a feature-usage event
* *THEN* the library SHALL report that the client is closed
* *THEN* the library SHALL ignore that call
* *AND* the library MUST NOT enqueue the event for delivery

### Scenario: Keeps caller-thread overhead low for accepted tracking

* *GIVEN* tracking is enabled
* *AND* the host application records a valid feature-usage event
* *AND* the host application records a feature-usage event
* *WHEN* the library accepts the event for delivery
* *THEN* the library SHALL keep caller-thread work limited to receiving the feature name, timestamp capture, and queue admission
* *AND* the library SHALL defer JSON serialization and HTTP delivery to background processing
Expand Down
1 change: 1 addition & 0 deletions src/main/java/com/exasol/telemetry/HttpTransport.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ private static RequestSender defaultSender(final TelemetryConfig config) {
};
}

// [impl~http-transport-send~1->req~async-delivery~1]
void send(final Message message) throws IOException {
final HttpRequest request = HttpRequest.newBuilder(config.getEndpoint())
.header("Content-Type", "application/json")
Expand Down
Loading