You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
- When a "using" directive is missing in a file, add it instead of using fully-qualified type names.
218
218
- Use modern C# syntax, but avoid syntax that requires types not available in older runtimes (for example, don't use syntax that requires ValueTuple because is not included in .NET Framework 4.6.1)
219
-
- StyleCop: `tracer/stylecop.json`; address warnings before pushing.
220
-
- C/C++: `.clang-format`; keep consistent naming.
219
+
- Prefer modern collection expressions (`[]`)
220
+
- StyleCop: see `tracer/stylecop.json`; address warnings before pushing.
221
+
- C/C++: see `.clang-format`; keep consistent naming.
222
+
223
+
## Logging Guidelines
224
+
225
+
Use clear, customer-facing terminology in log messages to avoid confusion. `Profiler` is ambiguous—it can refer to the .NET profiling APIs we use internally or the Continuous Profiler product.
-`CorProfiler` / `ICorProfiler` / `COR Profiler` for runtime components
240
+
241
+
**Reference:** See PR 7467 for examples of consistent terminology in native logs.
242
+
243
+
## Performance Guidelines
244
+
245
+
- Minimize heap allocations: The tracer runs in-process with customer applications and must have minimal performance impact. Avoid unnecessary object allocations, prefer value types where appropriate, use object pooling for frequently allocated objects, and cache reusable instances.
246
+
247
+
### Performance-Critical Code Paths
248
+
249
+
Performance is especially critical in two areas:
250
+
251
+
1.**Bootstrap/Startup Code**: Initialization code runs at application startup in every instrumented process, including:
252
+
- The managed loader (`Datadog.Trace.ClrProfiler.Managed.Loader`)
253
+
- Tracer initialization in `Datadog.Trace` (static constructors, configuration loading, first tracer instance creation)
254
+
- Integration registration and setup
255
+
256
+
Any allocations or inefficiencies here directly impact application startup time and customer experience. This code must be extremely efficient.
257
+
258
+
2.**Hot Paths**: Code that executes frequently during application runtime, such as:
259
+
- Span creation and tagging (executes on every traced operation)
260
+
- Context propagation (executes on every HTTP request/response)
261
+
- Sampling decisions (executes on every trace)
262
+
- Integration instrumentation callbacks (executes on every instrumented method call)
263
+
- Any code in the request/response pipeline
264
+
265
+
In these areas, even small inefficiencies are multiplied by the frequency of execution and can significantly impact application performance.
266
+
267
+
### Performance Optimization Patterns
268
+
269
+
**Zero-Allocation Provider Structs**
270
+
- Use `readonly struct` implementing interfaces instead of classes for frequently-instantiated abstractions
271
+
- Use generic type parameters with interface constraints to avoid boxing: `<TProvider> where TProvider : IProvider`
272
+
- Example: `EnvironmentVariableProvider` in managed loader (see tracer/src/Datadog.Trace.ClrProfiler.Managed.Loader)
273
+
- Benefits: Zero heap allocations, no boxing, better JIT optimization
274
+
275
+
**Avoid Allocation in Logging**
276
+
- Use format strings (`Log("value: {0}", x)`) instead of interpolation (`Log($"value: {x}")`)
277
+
- Allows logger to check level before formatting
278
+
- Critical in startup and hot paths where logging is frequent
279
+
280
+
**Avoid params Array Allocations**
281
+
- Provide overloads for common cases (0, 1, 2 args) that avoid `params object?[]` array allocation
282
+
- Keep params overload as fallback for 3+ args
283
+
- Example: Logging methods with multiple overloads for different argument counts
- Projects: `*.Tests.csproj` under `tracer/test`, native under `profiler/test`.
226
289
- Filters: `--filter "Category=Smoke"`, `--framework net6.0` as needed.
227
290
- Docker: Many integration tests require Docker; services in `docker-compose.yml`.
291
+
- Test style: Inline result variables in assertions. Prefer `SomeMethod().Should().Be(expected)` over storing intermediate `result` variables.
292
+
293
+
### Testing Patterns
294
+
295
+
**Abstraction for Testability**
296
+
- Extract interfaces for environment/filesystem dependencies (e.g., `IEnvironmentVariableProvider`)
297
+
- Allows mocking in unit tests without affecting production performance
298
+
- Use struct implementations with generic constraints for zero-allocation production code
299
+
- Example: Managed loader tests use `MockEnvironmentVariableProvider` for isolation (see tracer/test/Datadog.Trace.Tests/ClrProfiler/Managed/Loader/)
228
300
229
301
## Commit & Pull Request Guidelines
230
302
231
-
- Commits: Imperative; optional scope tag (e.g., `fix(telemetry): …` or `[Debugger] …`); reference issues.
303
+
- Commits: Imperative; optional scope tag (e.g., `fix(telemetry): …` or `[Debugger] …`); reference issues. Keep messages concise - avoid including full diffs or extensive details in the commit message.
- follow the existing PR description template in .github/pull_request_template.md
305
+
- Follow the existing PR description template in `.github/pull_request_template.md`
306
+
- Keep descriptions concise - provide essential context without excessive detail
307
+
- Focus on "what" and "why", with brief "how" for complex changes
234
308
- CI: All checks green; include tests/docs for changes.
235
309
236
310
## Internal Docs & References
@@ -282,7 +356,67 @@ tracer/src/Datadog.Trace
282
356
- Build/registration: Definitions are discovered and generated during build; no manual native changes required.
283
357
- Tests: Add tests under `tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests` and corresponding samples under `tracer/test/test-applications/integrations`. Run with OS‑specific Nuke targets; filter with `--filter`/`--framework`.
- Integration details: See `docs/development/AzureFunctions.md` for in-process vs isolated worker model differences, instrumentation specifics, and ASP.NET Core integration.
392
+
- Tests: `BuildAndRunWindowsAzureFunctionsTests` Nuke target; samples under `tracer/test/test-applications/azure-functions/`.
393
+
- Dependencies: `Datadog.AzureFunctions` transitively references `Datadog.Serverless.Compat` ([datadog-serverless-compat-dotnet](https://github.com/DataDog/datadog-serverless-compat-dotnet)), which contains the Datadog Agent executable. The agent process is started either via `DOTNET_STARTUP_HOOKS` or by calling `Datadog.Serverless.CompatibilityLayer.Start()` explicitly during bootstrap in user code.
394
+
285
395
## Security & Configuration Tips
286
396
287
397
- Do not commit secrets; prefer env vars (`DD_*`). `.env` should not contain credentials.
288
398
- Use `global.json` SDK; confirm with `dotnet --version`.
399
+
400
+
## Glossary
401
+
402
+
Common acronyms used in this repository:
403
+
404
+
-**AAS** — Azure App Services
405
+
-**AAP** — App and API Protection (formerly ASM, previously AppSec)
406
+
-**AOT** — Ahead-of-Time (compilation)
407
+
-**APM** — Application Performance Monitoring
408
+
-**ASM** — Application Security Management (formerly AppSec; now AAP)
0 commit comments