Skip to content

Commit 8ef63a6

Browse files
authored
Add copilot review instructions (#2170)
1 parent d1603cf commit 8ef63a6

File tree

4 files changed

+256
-75
lines changed

4 files changed

+256
-75
lines changed

.github/copilot-instructions.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# Copilot Instructions for OpenTelemetry Java Contrib
2+
3+
This repository provides observability instrumentation for Java applications.
4+
5+
## Code Review Priorities
6+
7+
### Style Guide Compliance
8+
9+
**PRIORITY**: Verify that all code changes follow the [Style Guide](../docs/style-guide.md). Check:
10+
11+
- Code formatting (auto-formatting, static imports, class organization)
12+
- Java language conventions (`final` usage, `@Nullable` annotations, `Optional` usage)
13+
- Performance constraints (hot path allocations)
14+
- Implementation patterns (SPI registration, configuration conventions)
15+
- Gradle conventions (Kotlin DSL, plugin usage, module naming)
16+
- Documentation standards (README files, deprecation processes)
17+
18+
### Critical Areas
19+
20+
- **Public APIs**: Changes affect downstream users and require careful review
21+
- **Performance**: Instrumentation must have minimal overhead
22+
- **Thread Safety**: Ensure safe concurrent access patterns
23+
- **Memory Management**: Prevent leaks and excessive allocations
24+
25+
### Quality Standards
26+
27+
- Proper error handling with appropriate logging levels
28+
- OpenTelemetry specification and semantic convention compliance
29+
- Resource cleanup and lifecycle management
30+
- Comprehensive unit tests for new functionality
31+
32+
## Coding Agent Instructions
33+
34+
When implementing changes or new features:
35+
36+
1. Follow all [Style Guide](../docs/style-guide.md) conventions and the Code Review Priorities above
37+
2. Run tests to ensure they still pass (use `./gradlew test` and `./gradlew integrationTest` as needed)
38+
3. **Always run `./gradlew spotlessApply`** after making code changes to ensure proper formatting
39+
4. Run markdown lint to ensure it still passes: `npx [email protected] -c .github/config/markdownlint.yml **/*.md`

CONTRIBUTING.md

Lines changed: 36 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,82 +1,65 @@
11
# Contributing
22

3-
Welcome to the OpenTelemetry Java Contrib Repository!
3+
Welcome to the OpenTelemetry Java Contrib repository!
44

55
## Introduction
66

7-
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.
7+
This repository provides observability libraries and utilities for Java applications that complement
8+
the [OpenTelemetry Java SDK](https://github.com/open-telemetry/opentelemetry-java) and
9+
[OpenTelemetry Java Instrumentation](https://github.com/open-telemetry/opentelemetry-java-instrumentation)
10+
projects.
811

9-
Before submitting new features or changes to current functionality, it is recommended to first
10-
[open an issue](https://github.com/open-telemetry/opentelemetry-java-contrib/issues/new)
11-
and discuss your ideas or propose the changes you wish to make.
12-
13-
Questions? Ask in the OpenTelemetry [java channel](https://cloud-native.slack.com/archives/C014L2KCTE3)
12+
Before submitting new features or changes, please consider
13+
[opening an issue](https://github.com/open-telemetry/opentelemetry-java-contrib/issues/new) first to
14+
discuss your ideas.
1415

1516
Pull requests for bug fixes are always welcome!
1617

17-
## Pre-requisites
18-
19-
To work with this repository, ensure you have:
20-
21-
### Tools:
22-
23-
Java 17 or higher
24-
25-
### Platform Notes:
18+
## Building and Testing
2619

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

29-
## Workflow
30-
31-
1. Fork the repository
32-
2. Clone locally
33-
3. Create a branch before working on an issue
34-
35-
## Local Run/Build
36-
37-
In order to build and test this whole repository you need JDK 11+.
38-
39-
#### Snapshot builds
40-
41-
For developers testing code changes before a release is complete, there are
42-
snapshot builds of the `main` branch. They are available from
43-
the Sonatype snapshot repository at `https://central.sonatype.com/repository/maven-snapshots/`
44-
([browse](https://central.sonatype.com/service/rest/repository/browse/maven-snapshots/io/opentelemetry/contrib/)).
45-
46-
#### Building from source
47-
48-
Building using Java 11+:
22+
To build the project:
4923

5024
```bash
51-
$ java -version
25+
./gradlew assemble
5226
```
5327

28+
To run the tests:
29+
5430
```bash
55-
$ ./gradlew assemble
31+
./gradlew test
5632
```
5733

58-
## Testing
34+
Some modules include integration tests that can be run with:
5935

6036
```bash
61-
$ ./gradlew test
37+
./gradlew integrationTest
6238
```
6339

64-
### Some modules have integration tests
40+
## Snapshot Builds
6541

66-
```
67-
$ ./gradlew integrationTest
68-
```
42+
Snapshot builds of the `main` branch are available from the Sonatype snapshot repository at:
43+
`https://central.sonatype.com/repository/maven-snapshots/`
44+
([browse](https://central.sonatype.com/service/rest/repository/browse/maven-snapshots/io/opentelemetry/contrib/)).
45+
46+
## Style Guide
47+
48+
See [Style Guide](docs/style-guide.md).
6949

70-
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.
50+
## Pull Request Guidelines
7151

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

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

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

80-
## Further Help
61+
If you need assistance or have questions:
8162

82-
Join [#otel-java](https://cloud-native.slack.com/archives/C014L2KCTE3) on OpenTelemetry Slack
63+
- Post on the [#otel-java](https://cloud-native.slack.com/archives/C014L2KCTE3) Slack channel
64+
- [Open an issue](https://github.com/open-telemetry/opentelemetry-java-contrib/issues/new/choose) in
65+
this repository

README.md

Lines changed: 1 addition & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -48,30 +48,9 @@ On reaching stable status, the `otel.stable` value in `gradle.properties` should
4848
Note that currently all the libraries are released together with the version of this repo, so breaking changes (after stable
4949
status is reached) would bump the major version of all libraries together. This could get complicated so `stable` has a high bar.
5050

51-
## Getting Started
52-
53-
```bash
54-
# Apply formatting
55-
$ ./gradlew spotlessApply
56-
57-
# Build the complete project
58-
$ ./gradlew build
59-
60-
# Run integration tests
61-
$ ./gradlew integrationTest
62-
63-
# Clean artifacts
64-
$ ./gradlew clean
65-
```
66-
6751
## Contributing
6852

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

7655
### Maintainers
7756

docs/style-guide.md

Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
# Style Guide
2+
3+
This project follows the
4+
[Google Java Style Guide](https://google.github.io/styleguide/javaguide.html).
5+
6+
## Code Formatting
7+
8+
### Auto-formatting
9+
10+
The build will fail if source code is not formatted according to Google Java Style.
11+
12+
Run the following command to reformat all files:
13+
14+
```bash
15+
./gradlew spotlessApply
16+
```
17+
18+
For IntelliJ users, an `.editorconfig` file is provided that IntelliJ will automatically use to
19+
adjust code formatting settings. However, it does not support all required rules, so you may still
20+
need to run `./gradlew spotlessApply` periodically.
21+
22+
### Static imports
23+
24+
Consider statically importing the following commonly used methods and constants:
25+
26+
- **Test methods**
27+
- `io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.*`
28+
- `org.assertj.core.api.Assertions.*`
29+
- `org.mockito.Mockito.*`
30+
- `org.mockito.ArgumentMatchers.*`
31+
- **Utility methods**
32+
- `io.opentelemetry.api.common.AttributeKey.*`
33+
- `java.util.Arrays` - asList, stream
34+
- `java.util.Collections` - singleton*, empty*, unmodifiable*, synchronized*, checked*
35+
- `java.util.Objects` - requireNonNull
36+
- `java.util.function.Function` - identity
37+
- `java.util.stream.Collectors.*`
38+
- **Utility constants**
39+
- `java.util.Locale.*`
40+
- `java.util.concurrent.TimeUnit.*`
41+
- `java.util.logging.Level.*`
42+
- `java.nio.charset.StandardCharsets.*`
43+
- **OpenTelemetry semantic convention constants**
44+
- All constants under `io.opentelemetry.semconv.**`, except for
45+
`io.opentelemetry.semconv.SchemaUrls.*` constants.
46+
47+
### Class organization
48+
49+
Prefer this order:
50+
51+
- Static fields (final before non-final)
52+
- Instance fields (final before non-final)
53+
- Constructors
54+
- Methods
55+
- Nested classes
56+
57+
**Method ordering**: Place calling methods above the methods they call. For example, place private
58+
methods below the non-private methods that use them.
59+
60+
**Static utility classes**: Place the private constructor (used to prevent instantiation) after all
61+
methods.
62+
63+
## Java Language Conventions
64+
65+
### Visibility modifiers
66+
67+
Follow the principle of minimal necessary visibility. Use the most restrictive access modifier that
68+
still allows the code to function correctly.
69+
70+
### Internal packages
71+
72+
Classes in `.internal` packages are not considered public API and may change without notice. These
73+
packages contain implementation details that should not be used by external consumers.
74+
75+
- Use `.internal` packages for implementation classes that need to be public within the module but
76+
should not be used externally
77+
- Try to avoid referencing `.internal` classes from other modules
78+
79+
### `final` keyword usage
80+
81+
Public non-internal classes should be declared `final` where possible. Internal and non-public
82+
classes should not be declared `final`.
83+
84+
Methods should only be declared `final` if they are in public non-internal non-final classes.
85+
86+
Fields should be declared `final` where possible.
87+
88+
Method parameters and local variables should never be declared `final`.
89+
90+
### `@Nullable` annotation usage
91+
92+
**Note: This section is aspirational and may not reflect the current codebase.**
93+
94+
Annotate all parameters and fields that can be `null` with `@Nullable` (specifically
95+
`javax.annotation.Nullable`, which is included by the `otel.java-conventions` Gradle plugin as a
96+
`compileOnly` dependency).
97+
98+
`@NonNull` is unnecessary as it is the default.
99+
100+
**Defensive programming**: Public APIs should still check for `null` parameters even if not
101+
annotated with `@Nullable`. Internal APIs do not need these checks.
102+
103+
### `Optional` usage
104+
105+
Following the reasoning from
106+
[Writing a Java library with better experience (slide 12)](https://speakerdeck.com/trustin/writing-a-java-library-with-better-experience?slide=12),
107+
`java.util.Optional` usage is kept to a minimum.
108+
109+
**Guidelines**:
110+
111+
- `Optional` shouldn't appear in public API signatures
112+
- Avoid `Optional` on the hot path (instrumentation code), unless the instrumented library uses it
113+
114+
## Tooling conventions
115+
116+
### AssertJ
117+
118+
Prefer AssertJ assertions over JUnit assertions (assertEquals, assertTrue, etc.) for better error
119+
messages.
120+
121+
### JUnit
122+
123+
Test classes and test methods should generally be package-protected (no explicit visibility
124+
modifier) rather than `public`. This follows the principle of minimal necessary visibility and is
125+
sufficient for JUnit to discover and execute tests.
126+
127+
### AutoService
128+
129+
Use the `@AutoService` annotation when implementing SPI interfaces. This automatically generates the
130+
necessary `META-INF/services/` files at compile time, eliminating the need to manually create and
131+
maintain service registration files.
132+
133+
```java
134+
@AutoService(AutoConfigurationCustomizerProvider.class)
135+
public class MyCustomizerProvider implements AutoConfigurationCustomizerProvider {
136+
// implementation
137+
}
138+
```
139+
140+
### Gradle
141+
142+
- Use Kotlin instead of Groovy for build scripts
143+
- Plugin versions should be specified in `settings.gradle.kts`, not in individual modules
144+
- All modules should use `plugins { id("otel.java-conventions") }`
145+
- Set module names with `otelJava.moduleName.set("io.opentelemetry.contrib.mymodule")`
146+
147+
## Configuration
148+
149+
- Use `otel.` prefix for all configuration property keys
150+
- Read configuration via the `ConfigProperties` interface
151+
- Provide sensible defaults and document all options
152+
- Validate configuration early with clear error messages
153+
154+
## Performance
155+
156+
Avoid allocations on the hot path (instrumentation code) whenever possible. This includes `Iterator`
157+
allocations from collections; note that `for (SomeType t : plainJavaArray)` does not allocate an
158+
iterator object.
159+
160+
Non-allocating Stream API usage on the hot path is acceptable but may not fit the surrounding code
161+
style; this is a judgment call. Some Stream APIs make efficient allocation difficult (e.g.,
162+
`collect` with pre-sized sink data structures involves convoluted `Supplier` code, or lambdas passed
163+
to `forEach` may be capturing/allocating lambdas).
164+
165+
## Documentation
166+
167+
### Component README files
168+
169+
- Include a component owners section in each module's README
170+
- Document configuration options with examples
171+
172+
### Deprecation and breaking changes
173+
174+
Breaking changes are allowed in unstable modules (published with `-alpha` version suffix).
175+
176+
1. Mark APIs with `@Deprecated` and a removal timeline (there must be at least one release with the
177+
API marked as deprecated before removing it)
178+
2. Document the replacement in Javadoc with `@deprecated` tag
179+
3. Note the migration path for breaking changes under a "Migration notes" section of CHANGELOG.md
180+
(create this section at the top of the Unreleased section if not already present)

0 commit comments

Comments
 (0)