Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
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
38 changes: 38 additions & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Copilot Instructions for OpenTelemetry Java Contrib

This repository provides observability instrumentation for Java applications.

## Code Review Priorities

### Style Guide Compliance

**PRIORITY**: Verify that all code changes follow the [Style Guide](../docs/style-guide.md). Check:

- Code formatting (auto-formatting, static imports, class organization)
- Java language conventions (`final` usage, `@Nullable` annotations, `Optional` usage)
- Performance constraints (hot path allocations)
- Implementation patterns (SPI registration, configuration conventions)
- Gradle conventions (Kotlin DSL, plugin usage, module naming)
- Documentation standards (README files, deprecation processes)

### Critical Areas

- **Public APIs**: Changes affect downstream users and require careful review
- **Performance**: Instrumentation must have minimal overhead
- **Thread Safety**: Ensure safe concurrent access patterns
- **Memory Management**: Prevent leaks and excessive allocations

### Quality Standards

- Proper error handling with appropriate logging levels
- OpenTelemetry specification and semantic convention compliance
- Resource cleanup and lifecycle management
- Comprehensive unit tests for new functionality

## Coding Agent Instructions

When implementing changes or new features:

1. Follow all [Style Guide](../docs/style-guide.md) conventions and the Code Review Priorities above
2. Run tests to ensure they still pass (use `./gradlew test` and `./gradlew integrationTest` as needed)
3. **Always run `./gradlew spotlessApply`** after making code changes to ensure proper formatting
34 changes: 34 additions & 0 deletions .github/workflows/copilot-setup-steps.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Custom setup steps for GitHub Copilot coding agent to speed up Copilot's work on coding tasks
name: "Copilot Setup Steps"

on:
pull_request:
paths:
- .github/workflows/copilot-setup-steps.yml
push:
paths:
- .github/workflows/copilot-setup-steps.yml
workflow_dispatch:

permissions:
contents: read

jobs:
copilot-setup-steps: # Job name required by GitHub Copilot coding agent
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0

- name: Set up JDK for running Gradle
uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
with:
distribution: temurin
java-version: 17

- name: Set up gradle
uses: gradle/actions/setup-gradle@017a9effdb900e5b5b2fddfb590a105619dca3c3 # v4.4.2

- name: Build project and download dependencies
run: ./gradlew build -x test
89 changes: 36 additions & 53 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,82 +1,65 @@
# Contributing

Welcome to the OpenTelemetry Java Contrib Repository!
Welcome to the OpenTelemetry Java Contrib repository!

## Introduction

This repository focuses on providing tools and utilities for Java-based observability, such as remote JMX metric gathering and reporting. We’re excited to have you here! Whether you’re fixing a bug, adding a feature, or suggesting an idea, your contributions are invaluable.
This repository provides observability libraries and utilities for Java applications that complement
the [OpenTelemetry Java SDK](https://github.com/open-telemetry/opentelemetry-java) and
[OpenTelemetry Java Instrumentation](https://github.com/open-telemetry/opentelemetry-java-instrumentation)
projects.

Before submitting new features or changes to current functionality, it is recommended to first
[open an issue](https://github.com/open-telemetry/opentelemetry-java-contrib/issues/new)
and discuss your ideas or propose the changes you wish to make.

Questions? Ask in the OpenTelemetry [java channel](https://cloud-native.slack.com/archives/C014L2KCTE3)
Before submitting new features or changes, please consider
[opening an issue](https://github.com/open-telemetry/opentelemetry-java-contrib/issues/new) first to
discuss your ideas.

Pull requests for bug fixes are always welcome!

## Pre-requisites

To work with this repository, ensure you have:

### Tools:

Java 17 or higher

### Platform Notes:
## Building and Testing

macOS/Linux: Ensure JAVA_HOME is set correctly.
While most modules target Java 8, building this project requires Java 17 or higher.

## Workflow

1. Fork the repository
2. Clone locally
3. Create a branch before working on an issue

## Local Run/Build

In order to build and test this whole repository you need JDK 11+.

#### Snapshot builds

For developers testing code changes before a release is complete, there are
snapshot builds of the `main` branch. They are available from
the Sonatype snapshot repository at `https://central.sonatype.com/repository/maven-snapshots/`
([browse](https://central.sonatype.com/service/rest/repository/browse/maven-snapshots/io/opentelemetry/contrib/)).

#### Building from source

Building using Java 11+:
To build the project:

```bash
$ java -version
./gradlew assemble
```

To run the tests:

```bash
$ ./gradlew assemble
./gradlew test
```

## Testing
Some modules include integration tests that can be run with:

```bash
$ ./gradlew test
./gradlew integrationTest
```

### Some modules have integration tests
## Snapshot Builds

```
$ ./gradlew integrationTest
```
Snapshot builds of the `main` branch are available from the Sonatype snapshot repository at:
`https://central.sonatype.com/repository/maven-snapshots/`
([browse](https://central.sonatype.com/service/rest/repository/browse/maven-snapshots/io/opentelemetry/contrib/)).

## Style Guide

See [Style Guide](docs/style-guide.md).

Follow the Java Instrumentation [Style Guide](https://github.com/open-telemetry/opentelemetry-java-instrumentation/blob/main/docs/contributing/style-guideline.md) from the opentelemetry-java-instrumentation repository.
## Pull Request Guidelines

Failure? Check logs for errors or mismatched dependencies.
When submitting a pull request, please ensure that you:

## Gradle conventions
- Clearly describe the change and its motivation
- Mention any breaking changes
- Include tests for new functionality
- Follow the [Style Guide](docs/style-guide.md)

- Use kotlin instead of groovy
- Plugin versions should be specified in `settings.gradle.kts`, not in individual modules
- All modules use `plugins { id("otel.java-conventions") }`
## Getting Help

## Further Help
If you need assistance or have questions:

Join [#otel-java](https://cloud-native.slack.com/archives/C014L2KCTE3) on OpenTelemetry Slack
- Post on the [#otel-java](https://cloud-native.slack.com/archives/C014L2KCTE3) Slack channel
- [Open an issue](https://github.com/open-telemetry/opentelemetry-java-contrib/issues/new/choose) in
this repository
23 changes: 1 addition & 22 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,30 +48,9 @@ On reaching stable status, the `otel.stable` value in `gradle.properties` should
Note that currently all the libraries are released together with the version of this repo, so breaking changes (after stable
status is reached) would bump the major version of all libraries together. This could get complicated so `stable` has a high bar.

## Getting Started

```bash
# Apply formatting
$ ./gradlew spotlessApply

# Build the complete project
$ ./gradlew build

# Run integration tests
$ ./gradlew integrationTest

# Clean artifacts
$ ./gradlew clean
```

## Contributing

The Java Contrib project was initially formed to provide methods of easy remote JMX metric gathering and reporting,
which is actively in development. If you have an idea for a similar use case in the metrics, traces, or logging
domain we would be very interested in supporting it. Please
[open an issue](https://github.com/open-telemetry/opentelemetry-java-contrib/issues/new/choose) to share your idea or
suggestion. PRs are always welcome and greatly appreciated, but for larger functional changes a pre-coding introduction
can be helpful to ensure this is the correct place and that active or conflicting efforts don't exist.
See [CONTRIBUTING.md](CONTRIBUTING.md).

### Maintainers

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
import java.io.IOException;
import java.util.concurrent.TimeUnit;

public class LogRecordFromDiskExporter implements FromDiskExporter {
public final class LogRecordFromDiskExporter implements FromDiskExporter {

private final FromDiskExporterImpl<LogRecordData> delegate;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
* This class implements a {@link LogRecordExporter} that delegates to an instance of {@code
* ToDiskExporter<LogRecordData>}.
*/
public class LogRecordToDiskExporter implements LogRecordExporter {
public final class LogRecordToDiskExporter implements LogRecordExporter {
private final ToDiskExporter<LogRecordData> delegate;

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
import java.io.IOException;
import java.util.concurrent.TimeUnit;

public class MetricFromDiskExporter implements FromDiskExporter {
public final class MetricFromDiskExporter implements FromDiskExporter {

private final FromDiskExporterImpl<MetricData> delegate;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
* This class implements a {@link MetricExporter} that delegates to an instance of {@code
* ToDiskExporter<MetricData>}.
*/
public class MetricToDiskExporter implements MetricExporter {
public final class MetricToDiskExporter implements MetricExporter {

private final ToDiskExporter<MetricData> delegate;
private final AggregationTemporalitySelector aggregationTemporalitySelector;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
import java.io.IOException;
import java.util.concurrent.TimeUnit;

public class SpanFromDiskExporter implements FromDiskExporter {
public final class SpanFromDiskExporter implements FromDiskExporter {

private final FromDiskExporterImpl<SpanData> delegate;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
* This class implements a SpanExporter that delegates to an instance of {@code
* ToDiskExporter<SpanData>}.
*/
public class SpanToDiskExporter implements SpanExporter {
public final class SpanToDiskExporter implements SpanExporter {

private final ToDiskExporter<SpanData> delegate;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@

package io.opentelemetry.contrib.disk.buffering.config;

import static java.util.concurrent.TimeUnit.HOURS;
import static java.util.concurrent.TimeUnit.SECONDS;

import com.google.auto.value.AutoValue;
import java.io.File;
import java.util.concurrent.TimeUnit;

/** Defines how the storage should be managed. */
@AutoValue
Expand Down Expand Up @@ -56,9 +58,9 @@ public static Builder builder() {
return new AutoValue_StorageConfiguration.Builder()
.setMaxFileSize(1024 * 1024) // 1MB
.setMaxFolderSize(10 * 1024 * 1024) // 10MB
.setMaxFileAgeForWriteMillis(TimeUnit.SECONDS.toMillis(30))
.setMinFileAgeForReadMillis(TimeUnit.SECONDS.toMillis(33))
.setMaxFileAgeForReadMillis(TimeUnit.HOURS.toMillis(18))
.setMaxFileAgeForWriteMillis(SECONDS.toMillis(30))
.setMinFileAgeForReadMillis(SECONDS.toMillis(33))
.setMaxFileAgeForReadMillis(HOURS.toMillis(18))
.setDebugEnabled(false);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import io.opentelemetry.contrib.disk.buffering.SignalType;
import javax.annotation.Nullable;

final class NoopExporterCallback implements ExporterCallback {
class NoopExporterCallback implements ExporterCallback {
static final NoopExporterCallback INSTANCE = new NoopExporterCallback();

private NoopExporterCallback() {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

package io.opentelemetry.contrib.disk.buffering.exporters;

import static java.util.concurrent.TimeUnit.MILLISECONDS;

import io.opentelemetry.contrib.disk.buffering.SignalType;
import io.opentelemetry.contrib.disk.buffering.storage.SignalStorage;
import io.opentelemetry.contrib.disk.buffering.storage.result.WriteResult;
Expand All @@ -13,11 +15,10 @@
import java.util.Collection;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

/** Internal utility for common export to disk operations across all exporters. */
final class SignalStorageExporter<T> {
class SignalStorageExporter<T> {
private final SignalStorage<T> storage;
private final ExporterCallback callback;
private final Duration writeTimeout;
Expand All @@ -34,7 +35,7 @@ public SignalStorageExporter(
public CompletableResultCode exportToStorage(Collection<T> items) {
CompletableFuture<WriteResult> future = storage.write(items);
try {
WriteResult operation = future.get(writeTimeout.toMillis(), TimeUnit.MILLISECONDS);
WriteResult operation = future.get(writeTimeout.toMillis(), MILLISECONDS);
if (operation.isSuccessful()) {
callback.onExportSuccess(type);
return CompletableResultCode.ofSuccess();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,18 @@

/** Exporter that stores spans into disk. */
public final class SpanToDiskExporter implements SpanExporter {
private static final SignalType TYPE = SignalType.SPAN;

private final SignalStorageExporter<SpanData> storageExporter;
private final ExporterCallback callback;
private static final SignalType TYPE = SignalType.SPAN;

private SpanToDiskExporter(
SignalStorageExporter<SpanData> storageExporter, ExporterCallback callback) {
this.storageExporter = storageExporter;
this.callback = callback;
}

public Builder builder(SignalStorage.Span storage) {
public static Builder builder(SignalStorage.Span storage) {
return new Builder(storage);
}

Expand All @@ -51,6 +52,10 @@ public static final class Builder {
private ExporterCallback callback = ExporterCallback.noop();
private Duration writeTimeout = Duration.ofSeconds(10);

private Builder(SignalStorage.Span storage) {
this.storage = storage;
}

@CanIgnoreReturnValue
public Builder setExporterCallback(ExporterCallback value) {
callback = value;
Expand All @@ -68,9 +73,5 @@ public SpanToDiskExporter build() {
new SignalStorageExporter<>(storage, callback, writeTimeout, TYPE);
return new SpanToDiskExporter(storageExporter, callback);
}

private Builder(SignalStorage.Span storage) {
this.storage = storage;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
* Signal-type generic class that can read telemetry previously buffered on disk and send it to
* another delegated exporter.
*/
public final class FromDiskExporterImpl<EXPORT_DATA> implements FromDiskExporter {
public class FromDiskExporterImpl<EXPORT_DATA> implements FromDiskExporter {
private final DebugLogger logger;
private final Storage storage;
private final SignalDeserializer<EXPORT_DATA> deserializer;
Expand Down
Loading