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
4 changes: 2 additions & 2 deletions azure-resources/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ plugins {
id("maven-publish")
}

description = "OpenTelemetry GCP Resources Support"
otelJava.moduleName.set("io.opentelemetry.contrib.gcp.resource")
description = "OpenTelemetry Azure Resources Support"
otelJava.moduleName.set("io.opentelemetry.contrib.azure.resource")

// enable publishing to maven local
java {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
import java.util.Optional;
import java.util.function.Supplier;

public class AzureAksResourceProvider extends CloudResourceProvider {
public final class AzureAksResourceProvider extends CloudResourceProvider {

private static final Map<String, AzureVmResourceProvider.Entry> COMPUTE_MAPPING = new HashMap<>();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import static io.opentelemetry.contrib.azure.resource.IncubatingAttributes.HOST_ID;
import static io.opentelemetry.contrib.azure.resource.IncubatingAttributes.SERVICE_INSTANCE_ID;
import static io.opentelemetry.semconv.ServiceAttributes.SERVICE_NAME;
import static java.util.Objects.requireNonNull;

import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;
Expand All @@ -20,10 +21,9 @@
import io.opentelemetry.sdk.resources.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import javax.annotation.Nullable;

public class AzureAppServiceResourceProvider extends CloudResourceProvider {
public final class AzureAppServiceResourceProvider extends CloudResourceProvider {

static final AttributeKey<String> AZURE_APP_SERVICE_STAMP_RESOURCE_ATTRIBUTE =
AttributeKey.stringKey("azure.app.service.stamp");
Expand Down Expand Up @@ -68,7 +68,7 @@ public Attributes getAttributes() {
if (detect != AzureEnvVarPlatform.APP_SERVICE) {
return Attributes.empty();
}
String name = Objects.requireNonNull(env.get(WEBSITE_SITE_NAME));
String name = requireNonNull(env.get(WEBSITE_SITE_NAME));
AttributesBuilder builder = AzureVmResourceProvider.azureAttributeBuilder(AZURE_APP_SERVICE);
builder.put(SERVICE_NAME, name);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
import java.util.HashMap;
import java.util.Map;

public class AzureContainersResourceProvider extends CloudResourceProvider {
public final class AzureContainersResourceProvider extends CloudResourceProvider {

static final String CONTAINER_APP_NAME = "CONTAINER_APP_NAME";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
import java.util.HashMap;
import java.util.Map;

public class AzureFunctionsResourceProvider extends CloudResourceProvider {
public final class AzureFunctionsResourceProvider extends CloudResourceProvider {

static final String FUNCTIONS_VERSION = "FUNCTIONS_EXTENSION_VERSION";
private static final String FUNCTIONS_MEM_LIMIT = "WEBSITE_MEMORY_LIMIT_MB";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@

package io.opentelemetry.contrib.azure.resource;

import static java.util.Objects.requireNonNull;

import com.fasterxml.jackson.core.JsonFactory;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.time.Duration;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Supplier;
import java.util.logging.Level;
Expand All @@ -19,9 +20,11 @@
import okhttp3.Request;
import okhttp3.Response;

public class AzureMetadataService {
public final class AzureMetadataService {
static final JsonFactory JSON_FACTORY = new JsonFactory();
private static final URL METADATA_URL;
private static final Duration TIMEOUT = Duration.ofSeconds(5);
private static final Logger logger = Logger.getLogger(AzureMetadataService.class.getName());

static {
try {
Expand All @@ -31,12 +34,6 @@ public class AzureMetadataService {
}
}

private AzureMetadataService() {}

private static final Duration TIMEOUT = Duration.ofSeconds(5);

private static final Logger logger = Logger.getLogger(AzureMetadataService.class.getName());

static Supplier<Optional<String>> defaultClient() {
return () -> fetchMetadata(METADATA_URL);
}
Expand Down Expand Up @@ -66,10 +63,12 @@ static Optional<String> fetchMetadata(URL url) {
return Optional.empty();
}

return Optional.of(Objects.requireNonNull(response.body()).string());
return Optional.of(requireNonNull(response.body()).string());
} catch (IOException e) {
logger.log(Level.FINE, "Failed to fetch Azure VM metadata", e);
return Optional.empty();
}
}

private AzureMetadataService() {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.sdk.resources.ResourceBuilder;

public class AzureResourceDetector implements ComponentProvider<Resource> {
public final class AzureResourceDetector implements ComponentProvider<Resource> {

@Override
public Class<Resource> getType() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,21 +34,7 @@
import java.util.logging.Logger;
import org.jetbrains.annotations.NotNull;

public class AzureVmResourceProvider extends CloudResourceProvider {

static class Entry {
final AttributeKey<String> key;
final Function<String, String> transform;

Entry(AttributeKey<String> key) {
this(key, Function.identity());
}

Entry(AttributeKey<String> key, Function<String, String> transform) {
this.key = key;
this.transform = transform;
}
}
public final class AzureVmResourceProvider extends CloudResourceProvider {

private static final Map<String, Entry> COMPUTE_MAPPING = new HashMap<>();

Expand Down Expand Up @@ -161,4 +147,18 @@ private static void consumeJson(JsonParser parser, BiConsumer<String, String> co
consumer.accept(parser.currentName(), parser.nextTextValue());
}
}

static class Entry {
final AttributeKey<String> key;
final Function<String, String> transform;

Entry(AttributeKey<String> key) {
this(key, Function.identity());
}

Entry(AttributeKey<String> key, Function<String, String> transform) {
this.key = key;
this.transform = transform;
}
}
}
Loading