Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
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
4 changes: 4 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ Check [Adding a New Instrumentation](docs/add_new_instrumentation.md) for instru

Check [How Instrumentations Work](docs/how_instrumentations_work.md) for a deep dive into how instrumentations work.

## Adding Configurations

Check [Adding a New Configuration](docs/add_new_configurations.md) for instructions on adding a new configuration.

## Code contributions

### Development environment quick check
Expand Down
34 changes: 34 additions & 0 deletions docs/add_new_configurations.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Add a New Configuration

This doc will walk through how to properly add and document a new configuration in the Java Tracer.

## Where Configurations Live

All configurations in the Java Tracer are defined in `dd-trace-api/src/main/java/datadog/trace/api/config`.
Configurations are separated into different files based on the product they are related to. e.g. `CiVisiblity` related configurations live in `CiVisibilityConfig`, `Tracer` related in `TracerConfig`, etc.
Default values for configurations live in `ConfigDefaults.java`.

Configuration values are read in `Config.java`, which utilizes helper methods in `ConfigProvider.java` to fetch the final value for a configuration after searching through all Configuration Sources and determining the final value based on Source priority.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 suggestion: ‏It could be nice to show a list of the various configuration sources and what their purpose are. Typically, the one from CI Vis is not trivial.

Copy link
Contributor Author

@mhlidd mhlidd Oct 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mtoffl01 and I discussed that we wait to add documentation for Sources until Stable/Declarative/Hands-Off Config has a finalized term to be used publicly.

Documentation about sources will likely be a new README that is linked from this page.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's alright to document this now in dd-trace-java docs; in our conversations, I meant that public docs (docs.datadoghq.com) must wait.

The name for this file-based config stuff is definitely, officially Declarative Config 😁 .

Happy to help craft the sources doc if need be.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What could actually be good is if we mention the sources here, and link to the public docs with more info. I don't think devs generally need to be super concerned about the sources when adding new configurations, but a link could always be good to provide more info. WDYT?

`Config.java` also includes getters that can be used in other classes to get the value of a configuration.

## Adding a Configuration

In order to properly add a new configuration in the tracer, follow the below steps.
1. Determine whether this configuration exists in another tracer in the [Feature Parity Dashboard](https://feature-parity.us1.prod.dog/#/configurations?viewType=configurations). Developers can search by Environment Variable name or description of the configuration.
1. If the configuration exists in a separate tracer, reuse the name of the existing configuration. If the configuration already exists in the Java Tracer, utilize that instead.
2. Add the definition of the configuration to the appropriate class based on its related product.
1. Consider separating words by `.` and compound words by `-`. Note that `dd.` or `DD_` should not belong in the configuration definition as the base definitions are normalized to include those prefixes when querying the varying Configuration Sources.
3. If relevant, add the default value of the configuration in a static field in `ConfigDefaults.java`.
4. Create a local field in `Config.java` to represent the configuration. In the constructor of `Config.java`, call the relevant helper from `ConfigProvider.java` to query and assign the value of the configuration.
5. Create a getter for the field for other classes to access the value of the configuration.
6. Add the configuration to the `toString()` method or logging.
7. Add the Environment Variable name of the configuration to the `supportedConfigurations` key of `metadata/supported-configurations.json` in the format of `ENV_VAR: ["VERSION", ...]`. If the configuration already existed in another tracer, add the version listed on the Feature Parity Dashboard. If introducing a new configuration, provide a version of `A`.
1. If there are aliases of the Environment Variable, add them to the `aliases` key of the file.
8. If the configuration is unique to all tracers, add it to the [Feature Parity Dashboard](https://feature-parity.us1.prod.dog/#/configurations?viewType=configurations). This ensures that we have good documentation of all configurations supported in the tracer.

For details on adding environment variables to `metadata/supported-configurations.json` or the Feature Parity Dashboard, refer to this [document](https://datadoghq.atlassian.net/wiki/spaces/APMINT/pages/5372248222/APM+-+Centralized+Configuration+Config+inversion#dd-trace-java).

## Verifying the Configuration

To verify a configuration has been correctly added, developers can modify existing test cases in `ConfigTest.groovy` to set the value of the configuration with various sources and confirm the internal value is correctly set in `Config.java`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be sick to have a new test populate for the new config automatically... maybe someday. 😄

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure that "automated generated tests" will have real value if it's only testing "getter" behavior to comply with the code coverage policy.
To me, it make sense to write tests when there is a specific logic at play, like this will be enabled if both X and Y are enable and Z contains xxx.

On thing I would like at mid term is to have:

  • Config declaration per product -- like we have today TracerConfig, CiVisibilityConfig
  • Such config would declare keys, aliases, type (and parser if needed)
  • This config declaration would be used to generate the Config class(es).

It does not have to be a god class with all config from it, it can be split by products too.
But this would get rid of the contructor / getter / toString / testing boilerplate...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds like this could be something Config Inversion/Registry could be very useful for with our new v2 format. :)

Optionally, new test cases can be added for testing specific to the behavior of a configuration.
Loading