Skip to content

Commit ea019a0

Browse files
authored
Merge branch 'main' into hongshi/notable_events_collector_health_stats
2 parents b1589ef + f57e7a3 commit ea019a0

1,385 files changed

Lines changed: 29213 additions & 24439 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 153 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,100 +1,191 @@
11
---
22
name: create-config-field
3-
description: Add a new configuration field to the Datadog Agent (datadog.yaml)
3+
description: Add a new configuration field to the Datadog Agent (datadog.yaml) by declaring it in the config schema
44
allowed-tools: Bash, Read, Write, Edit, Glob, Grep, AskUserQuestion
55
argument-hint: "[config.key.name]"
66
model: sonnet
77
---
88

9-
Add a new configuration field to a Datadog Agent. This involves registering the key with defaults/env bindings in Go, and optionally documenting it in the config template.
9+
Add a new configuration setting to a Datadog Agent config file by declaring it in
10+
the **configuration schema**.
1011

11-
There are **two separate config objects**, each with their own Go init function. Within the core agent config, many **subsystems** have dedicated setup functions and template sections.
12+
The schema is the single source of truth for every Agent setting: its type,
13+
default, documentation, environment variables, validation rules and visibility
14+
all live in one YAML node. Do **not** add `BindEnvAndSetDefault` calls by hand —
15+
the `pkg/config/setup/*_settings.go` files are generated from the schema, and so
16+
are `datadog.yaml.example` / `system-probe.yaml.example`, the JSON Schema
17+
published to SchemaStore, and the runtime config validation.
1218

13-
### Config objects
19+
Full reference: `docs/public/agent-schema/`[index](../../../docs/public/agent-schema/index.md),
20+
[keywords](../../../docs/public/agent-schema/keywords.md),
21+
[examples](../../../docs/public/agent-schema/examples.md),
22+
[cli](../../../docs/public/agent-schema/cli.md),
23+
[faq](../../../docs/public/agent-schema/faq.md).
1424

15-
| Config object | Config file | Go init function |
25+
## Where settings live
26+
27+
One schema per config file, all under `pkg/config/schema/yaml/`:
28+
29+
| Config file | Schema | `--schema` value |
1630
|---|---|---|
17-
| Core Agent | `datadog.yaml` | `InitConfig()` in `pkg/config/setup/config.go` |
18-
| System Probe | `system-probe.yaml` | `InitSystemProbeConfig()` in `pkg/config/setup/system_probe.go` |
19-
20-
### Core Agent subsystems
21-
22-
| Subsystem | Go setup function | Template conditional | Key prefix examples |
23-
|---|---|---|---|
24-
| Common / General | `agent()` or inline in `InitConfig()` | `.Common`, `.Agent` | `api_key`, `hostname`, `site` |
25-
| Logs Agent | `logsagent()` | `.LogsAgent` | `logs_config.*` |
26-
| APM / Trace Agent | `setupAPM()` in `apm.go` | `.TraceAgent` | `apm_config.*` |
27-
| Process Agent | `setupProcesses()` in `process.go` | `.ProcessAgent` | `process_config.*` |
28-
| DogStatsD | `dogstatsd()` | `.Dogstatsd` | `dogstatsd_*` |
29-
| Security Agent | via `InitConfig()` | `.SecurityAgent` | `security_agent.*` |
30-
| Cluster Agent | via `InitConfig()` | `.ClusterAgent` | `cluster_agent.*` |
31-
| OTLP | `OTLP()` in `otlp.go` | `.OTLP` | `otlp_config.*` |
32-
33-
### System Probe subsystems
34-
35-
| Subsystem | Go setup function | Template conditional | Key prefix examples |
36-
|---|---|---|---|
37-
| General | `InitSystemProbeConfig()` | `.SystemProbe` | `system_probe_config.*` |
38-
| CWS | `initCWSSystemProbeConfig()` in `system_probe_cws.go` | `.SecurityModule` | `runtime_security_config.*` |
39-
| USM | `initUSMSystemProbeConfig()` in `system_probe_usm.go` | `.UniversalServiceMonitoringModule` | `service_monitoring_config.*` |
40-
| Network | via `InitSystemProbeConfig()` | `.NetworkModule` | `network_config.*` |
31+
| `datadog.yaml` | `pkg/config/schema/yaml/core_schema.yaml` | `core` (default) |
32+
| `system-probe.yaml` | `pkg/config/schema/yaml/system-probe_schema.yaml` | `system-probe` |
33+
34+
Large top-level sections are **split into sibling files** referenced via `$ref`,
35+
so the node for `apm_config.enabled` lives in `apm_config.yaml`, not in
36+
`core_schema.yaml`.
37+
38+
Never grep for the file by hand — `dda inv -- schema.locate` resolves the `$ref`
39+
for you (see Step 2).
4140

4241
## Instructions
4342

4443
### Step 1: Gather information from the user
4544

46-
Use `AskUserQuestion` to collect the following. If `$ARGUMENTS` provides the config key name, skip that question.
45+
Use `AskUserQuestion` to collect the following. If `$ARGUMENTS` provides the
46+
setting path, skip that question.
47+
48+
1. **Target schema**: `datadog.yaml` (core) or `system-probe.yaml`?
49+
2. **Setting path** (dot-separated, e.g. `my_feature.enabled`).
50+
3. **Type**: `boolean`, `string`, `number`, `integer`, `array`, or `object`. For `array`, also the element type
51+
(`items.type` is mandatory).
52+
4. **Default**: a single `default`, or per-platform `platform_default`.
53+
5. **Visibility**: `public` (appears in the generated `*.yaml.example` and public docs) or undocumented (the default —
54+
internal, no keyword emitted).
55+
6. **Description**: mandatory for `public`, strongly encouraged otherwise. Written for **users**, not Agent developers.
56+
This should explain what the settings does and how to use it.
57+
7. **Description for each ancestor section**: if a setting is public, each parent section must be public too with their
58+
own description. Ask for a **description per section newly made public**, separately from the setting's. Never reuse
59+
or copy the setting's description into its parent section — a section describes what the group of settings is *for*,
60+
a setting describes its own value.
61+
8. **Comment**: an optional description aimed at developers.
62+
63+
### Step 2: Check the setting does not already exist
4764

48-
1. **Target config**: Core Agent (`datadog.yaml`) or System Probe (`system-probe.yaml`)?
49-
2. **Subsystem**: Which subsystem does this field belong to? (see tables above)
50-
3. **Config key** (dot-separated, e.g. `my_feature.enabled`): the YAML path.
51-
4. **Value type**: Boolean, String, Integer, Float, Duration, String slice, or Map.
52-
5. **Default value**: What should the default be?
53-
6. **Description**: Human-readable description of what this field controls.
54-
7. **Scope**: Add inline in the subsystem function, or create a dedicated setup file (`pkg/config/setup/<feature>.go`) for a group of related fields?
55-
8. **User-facing?**: Should the rendered example yaml (`datadog.yaml`, `system-probe.yaml`, ...) show this setting?
65+
```bash
66+
dda inv -- schema.locate my_feature.enabled # exact path
67+
dda inv -- schema.locate '.*my_feature' # pattern (regex/glob)
68+
```
5669

57-
### Step 2: Register the config key
70+
This also tells you which file to edit. See the `locate-config-setting` skill for
71+
the full flag set.
5872

59-
Find the right subsystem function from the tables above and add the binding. Use `Grep` if unsure where related keys live.
73+
### Step 3: Add the node to the schema
6074

61-
```go
62-
config.BindEnvAndSetDefault("my_feature.enabled", false)
75+
Preferred — the interactive wizard, which routes split sections to the right
76+
sub-file, preserves the file's hand-curated ordering, makes ancestor sections
77+
public when needed, and lints at the end:
78+
79+
```bash
80+
dda inv schema.add-setting # core schema
81+
dda inv schema.add-setting --schema=system-probe # system-probe schema
82+
```
83+
84+
The wizard is interactive (it reads from stdin), so when you cannot drive a TTY,
85+
edit the YAML directly instead. Read a neighbouring node first and match its
86+
style:
87+
88+
```yaml
89+
my_feature:
90+
node_type: section
91+
type: object
92+
visibility: public
93+
description: Configuration for my feature.
94+
properties:
95+
96+
enabled:
97+
node_type: setting
98+
type: boolean
99+
default: false
100+
description: Enables my feature.
101+
visibility: public
63102
```
64103
65-
For a **group of related fields**, create `pkg/config/setup/<feature>.go` with a dedicated setup function, then call it from the appropriate init function. Read an existing setup file (e.g. `pkg/config/setup/apm.go`) for the pattern.
104+
Rules that the linter enforces:
66105
67-
For **serverless-compatible** core agent fields, register via the `serverlessConfigComponents` slice in `config.go` instead of directly in `InitConfig`.
106+
- Every node needs `node_type: section` or `node_type: setting`.
107+
- Every setting needs a `type` and exactly one of `default` / `platform_default`.
108+
- `platform_default` must cover every platform — list `linux`, `windows`,
109+
`darwin`, `aix` explicitly, or add an `other` catch-all. `container` /
110+
`fargate` are optional and fall back to `linux` then `other`.
111+
- An `array` setting must declare `items.type`.
112+
- A `public` node needs a non-empty `description`, **and every ancestor section
113+
must also be `public` with a description** — its own description, gathered in
114+
Step 1, not a copy of the child setting's.
115+
- A section needs at least one child; a public section needs at least one direct
116+
public child.
117+
- Set `node_type: setting` — not `section` — when the value *is* an object
118+
(e.g. `docker_labels_as_tags`: `type: object`, `default: {}`). A section is only
119+
for grouping child settings.
68120

69-
### Step 3: Regenerate the schema
121+
**Placement matters**: the generated config examples follow schema order, so
122+
insert the node where it belongs logically, not at the end of the file.
70123

71-
The example yaml configs (`datadog.yaml`, `system-probe.yaml`, etc.) are rendered from the enriched schema under `pkg/config/schema/yaml/`. The schema is derived from the running agent, so build first, then regenerate:
124+
### Step 4: Lint and preview
72125

73126
```bash
74-
dda inv agent.build --build-exclude=systemd
75-
dda inv schema.generate --agent-bin=./bin/agent/agent
127+
dda inv schema.lint
76128
```
77129

78-
Commit the resulting changes under `pkg/config/schema/yaml/` alongside your Go code.
79-
80-
### Step 4: Verify
130+
## Keyword quick reference
81131

82-
1. Lint: `dda inv linter.go`
83-
2. Report the results to the user.
132+
Full up-to-date details in `docs/public/agent-schema/keywords.md`.
84133

85-
## Key Methods Reference
134+
| Keyword | Where | Notes |
135+
|---|---|---|
136+
| `node_type` | all | `section` or `setting`. Mandatory. |
137+
| `type` | setting | `boolean`, `number`, `integer`, `string`, `array`, `object`. |
138+
| `default` | setting | Must match `type`. Mutually exclusive with `platform_default`. |
139+
| `platform_default` | setting | Keys: `linux`, `windows`, `darwin`, `aix`, `container`, `fargate`, `other`. |
140+
| `description` | all | Mandatory when `public`. Use the `\|` block scalar for multi-line. |
141+
| `visibility` | all | `public` or `undocumented` (default). |
142+
| `env_vars` | setting | Overrides the derived `DD_*` name; first match wins. |
143+
| `env_parser` | setting | `comma_separated`, `space_separated`, `json`. Needed for complex types. |
144+
| `sensitive` | setting | Scrubs the value from logs, flare and Fleet Automation. |
145+
| `items` | setting | Mandatory for `array`. |
146+
| `properties` | section / object setting | Child settings on a section; value sub-schema on an object setting. |
147+
| `title` | section | Banner heading in the generated example. |
148+
| `comment` | all | Developer-only note; never rendered to users. |
149+
| `example` | setting | Overrides the value shown on the rendered example line. |
150+
| `tags` | all | See below. |
151+
152+
**Relative defaults**: use `${conf_path}`, `${install_path}`, `${log_path}`,
153+
`${run_path}` with `/` separators rather than hardcoding per-OS paths — e.g.
154+
`default: "${conf_path}/conf.d"`. Valid in `default` and `platform_default`.
155+
156+
### Tags
157+
158+
Three are usable for new settings:
159+
160+
- `template_section:<name>` — selects which config-example flavors include the
161+
setting. Omit it and the setting renders in every build type.
162+
- `platform_only:<os>[,<os>]` — restricts the setting to the listed OSes
163+
(`windows`, `linux`, `darwin`); it is dropped from the examples generated for
164+
any other `--os-target`.
165+
- `generate_const:<Name>` — emits a Go constant `<Name>` in `pkg/config/setup`
166+
holding this setting's default. Use it instead of hardcoding a default (port,
167+
timeout, path) in Go code, so the two can never drift.
168+
169+
`golang_type:*`, `no-env` and the legacy `env_parser` values
170+
(`comma_and_space_separated`, `traces_span`, `csv_comma_separated`,
171+
`comma_then_space_separated`, `json_list_or_*`) exist only to support existing
172+
settings — do not use them for new ones.
173+
174+
## Reading the setting from Go
86175

87-
- **`BindEnvAndSetDefault(key, default, envVars...)`** — Preferred. Registers key, sets default, binds `DD_*` env var.
88-
- **`SetDefault(key, value)`** — Default without env binding.
176+
```go
177+
pkgconfigsetup.Datadog().GetBool("my_feature.enabled")
178+
pkgconfigsetup.SystemProbe().GetInt("system_probe_config.max_conns")
179+
```
89180

90-
`BindEnvAndSetDefault("my_feature.timeout", 30)` auto-creates `DD_MY_FEATURE_TIMEOUT`. Custom alias: `BindEnvAndSetDefault("my_feature.timeout", 30, "DD_MY_TIMEOUT")`.
181+
In components, prefer the injected `config.Component` over the global accessor.
91182

92-
## Important Notes
183+
## Related
93184

94-
- Config priority: `default < file < env-var < fleet-policies < agent-runtime < remote-config < cli`.
95-
- Define exported string constants for keys when creating a dedicated setup file.
185+
- `locate-config-setting` — find where an existing setting is defined.
186+
- `create-release-note` — a user-visible new setting needs a reno note.
96187

97188
## Usage
98189

99-
- `/create-config-field`Interactive: prompts for all details
100-
- `/create-config-field my_feature.enabled`Pre-fills the key name
190+
- `/create-config-field` — interactive: prompts for all details
191+
- `/create-config-field my_feature.enabled` pre-fills the setting path

0 commit comments

Comments
 (0)