Skip to content

Commit 68d85b5

Browse files
authored
Add copilot-instructions.md (#4321)
1 parent eb427e2 commit 68d85b5

File tree

1 file changed

+127
-0
lines changed

1 file changed

+127
-0
lines changed

.github/copilot-instructions.md

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
# Application Insights Java Agent - Development Guide
2+
3+
## Architecture Overview
4+
5+
This is a **Java agent** that extends OpenTelemetry Java Agent to provide Azure Application Insights telemetry. The agent is packaged as a single JAR that instruments applications at runtime without code changes.
6+
7+
### Key Components
8+
9+
- **Agent Entry Point**: `Agent.java` - wraps OpenTelemetry Agent with Application Insights-specific initialization
10+
- **Agent Bootstrap**: Minimal classes loaded into bootstrap classloader for early initialization
11+
- **Agent Tooling**: Main Application Insights logic (configuration, exporters, processors) isolated in agent classloader
12+
- **Instrumentation Modules**: C Functions, ASP.NET Core interop, etc.
13+
- **Classic SDK**: Legacy 2.x SDK maintained for compatibility
14+
15+
### Multi-Module Build Structure
16+
ustom instrumentation for Azure
17+
```
18+
agent/
19+
├── agent/ # Final agent JAR assembly (shadow plugin)
20+
├── agent-bootstrap/ # Bootstrap classloader components
21+
├── agent-tooling/ # Core agent logic & Azure exporters
22+
├── instrumentation/ # Custom instrumentation modules
23+
└── runtime-attach/ # Dynamic attach support
24+
```
25+
26+
## Development Workflows
27+
28+
### Building the Agent
29+
30+
```bash
31+
# Build complete agent JAR
32+
./gradlew assemble
33+
34+
# Agent JAR location
35+
# agent/agent/build/libs/applicationinsights-agent-<version>.jar
36+
```
37+
38+
### Running Smoke Tests
39+
40+
Smoke tests use containerized applications with the agent attached.
41+
42+
Generally you shouldn't run all of the smoke tests, as they can take a long time.
43+
Instead, focus on running a single test.
44+
45+
```bash
46+
# Run a specific smoke test
47+
./gradlew :smoke-tests:apps:HttpClients:smokeTest --tests "*HttpClientTest\$Tomcat8Java8Test"
48+
```
49+
50+
## Project-Specific Conventions
51+
52+
### Build Conventions (buildSrc/)
53+
54+
- **ai.java-conventions**: Base Java setup with JDK 17 toolchain, targets Java 8
55+
- **ai.javaagent-instrumentation**: Plugin for OpenTelemetry instrumentation modules
56+
- **ai.smoke-test-war**: WAR-based smoke test applications
57+
- **ai.shadow-conventions**: JAR shadowing with relocation rules
58+
59+
### Agent JAR Assembly Process
60+
61+
The agent JAR is built in **3 critical steps** (see `agent/agent/build.gradle.kts`):
62+
63+
1. **Relocate** distro-specific libraries to avoid conflicts
64+
2. **Isolate** classes to `inst/` directory with `.classdata` extensions
65+
3. **Merge** with upstream OpenTelemetry agent, excluding duplicates
66+
67+
### Configuration Pattern
68+
69+
- Main config: `Configuration.java` - comprehensive JSON-based configuration
70+
- Environment variables: `APPLICATIONINSIGHTS_CONNECTION_STRING`, etc.
71+
72+
### Smoke Test Pattern
73+
74+
- **Framework**: `smoke-tests/framework/` - shared test infrastructure
75+
- **Apps**: `smoke-tests/apps/` - containerized test applications
76+
- **Assertions**: `DependencyAssert`, `RequestAssert`, `MetricAssert` for validating telemetry
77+
- **Fake Ingestion**: Mock Application Insights endpoint for testing
78+
- **Environment Matrix**: Tests run across multiple environments (Java 8/11/17/21/23, Tomcat/Wildfly, HotSpot/OpenJ9)
79+
- **Nested Test Classes**: Each abstract test class has nested static classes for different environments:
80+
```java
81+
abstract class HttpClientTest {
82+
@Environment(TOMCAT_8_JAVA_8)
83+
static class Tomcat8Java8Test extends HttpClientTest {}
84+
85+
@Environment(TOMCAT_8_JAVA_11)
86+
static class Tomcat8Java11Test extends HttpClientTest {}
87+
}
88+
```
89+
90+
## Common Patterns
91+
92+
### Error Handling
93+
94+
Use `FriendlyException` for user-facing errors with actionable messages:
95+
96+
```java
97+
throw new FriendlyException(
98+
"Connection string is required",
99+
"Please set APPLICATIONINSIGHTS_CONNECTION_STRING environment variable");
100+
```
101+
102+
### Dependency Management
103+
104+
- All dependencies managed through `dependencyManagement/` module
105+
- Strict version conflict resolution (`failOnVersionConflict()`)
106+
- Dependency locking enabled for reproducible builds
107+
108+
### Testing Patterns
109+
110+
- **Unit Tests**: Standard JUnit 5 with 15-minute timeout
111+
- **Smoke Tests**: Containerized integration tests with fake ingestion
112+
- **Muzzle Tests**: Bytecode compatibility validation for instrumentation
113+
114+
## Key Files for Understanding
115+
116+
- `agent/agent/build.gradle.kts` - Agent assembly process
117+
- `agent/agent-tooling/src/main/java/.../configuration/Configuration.java` - Main configuration
118+
- `smoke-tests/framework/src/main/java/.../smoketest/` - Test infrastructure
119+
- `buildSrc/src/main/kotlin/ai.*.gradle.kts` - Build conventions
120+
121+
## Development Tips
122+
123+
- Agent JAR must be self-contained (no external dependencies)
124+
- Bootstrap classes are loaded early - keep minimal
125+
- Use `hideFromDependabot()` for test-only dependencies
126+
- Smoke tests validate end-to-end functionality in realistic environments
127+
- Check `gradle.lockfile` when dependency issues arise

0 commit comments

Comments
 (0)