Files
weatherfeeder/docs/config.md

216 lines
6.7 KiB
Markdown

# Configuration Reference
## Config File
`weatherfeeder` reads exactly one YAML file named `config.yml` from the current
working directory. There is no config path flag and no search path.
YAML decoding is strict for config struct fields: misspelled fields such as
`sources[].drviver` fail startup. Driver-specific `params` maps are validated by
the source or sink constructor that consumes them.
The top-level file contains:
```yaml
sources:
- name: NWSObservationKSTL
mode: poll
driver: nws_observation
every: 10m
kinds: ["observation"]
params:
url: "https://api.weather.gov/stations/KSTL/observations/latest"
user_agent: "Example weatherfeeder operator (ops@example.com)"
sinks:
- name: stdout
driver: stdout
params: {}
routes:
- sink: stdout
kinds: ["observation"]
```
`sources` and `sinks` must each contain at least one entry. `routes` is optional.
When `routes` is omitted, every configured sink receives every event kind.
## Production-Oriented Shape
A typical deployment uses multiple polling sources and sends the same canonical
event stream to a broker or database:
```yaml
sources:
- name: NWSAlertsLocal
mode: poll
driver: nws_alerts
every: 1m
kinds: ["alert"]
params:
url: "https://api.weather.gov/alerts?point=38.6239,-90.3571&limit=20"
user_agent: "Example weatherfeeder operator (ops@example.com)"
sinks:
- name: nats_weather
driver: nats
params:
url: nats://nats:4222
subject: weatherfeeder
- name: pg_weather
driver: postgres
params:
uri: postgres://weatherdb:5432/weatherdb?sslmode=disable
username: weatherdb
password: "<set outside source control>"
prune: 3d
routes:
- sink: nats_weather
kinds: ["observation", "forecast", "forecast_discussion", "weather_story", "alert"]
- sink: pg_weather
kinds: ["observation", "forecast", "forecast_discussion", "weather_story", "alert"]
```
Do not commit real API keys, database passwords, or personal contact addresses in
copyable configs.
## Top-Level Fields
| Field | Required | Description |
|---|:---:|---|
| `sources` | yes | List of configured input sources. |
| `sinks` | yes | List of configured output sinks. |
| `routes` | no | List of sink routing rules. If omitted, all sinks receive all kinds. |
## Source Fields
| Field | Required | Description |
|---|:---:|---|
| `name` | yes | Unique source name. Used as the event source identifier. |
| `driver` | yes | Source driver name. |
| `mode` | no | `poll`, `stream`, or omitted for auto. Current weatherfeeder drivers are polling drivers. |
| `every` | yes | Poll interval for current weatherfeeder source drivers. |
| `kinds` | no | Expected event kinds. If present, startup verifies they match the source driver. |
| `params` | driver-specific | Driver parameters. Current source drivers require HTTP params. |
Current event kinds are `observation`, `forecast`, `forecast_discussion`,
`weather_story`, and `alert`.
## Source Drivers
| Driver | Kind | Upstream product |
|---|---|---|
| `nws_observation` | `observation` | NWS station latest observation. |
| `nws_alerts` | `alert` | NWS alerts collection. |
| `nws_forecast_hourly` | `forecast` | NWS hourly gridpoint forecast. |
| `nws_forecast_narrative` | `forecast` | NWS narrative gridpoint forecast. |
| `nws_forecast_discussion` | `forecast_discussion` | NWS forecast discussion HTML product. |
| `nws_weatherstories` | `weather_story` | NWS office weather stories. |
| `openmeteo_observation` | `observation` | Open-Meteo current conditions. |
| `openmeteo_forecast` | `forecast` | Open-Meteo hourly forecast. |
| `openweather_observation` | `observation` | OpenWeather current weather. |
## HTTP Source Params
All current source drivers use the shared HTTP polling helper.
| Param | Required | Description |
|---|:---:|---|
| `url` | yes | Full upstream request URL. `URL` is also accepted by the helper. |
| `user_agent` | yes | User-Agent sent to the upstream provider. `userAgent` is also accepted by the helper. |
| `conditional` | no | Boolean. Defaults to `true`; enables ETag and Last-Modified conditional requests. |
| `http_timeout` | no | Positive duration for the HTTP client timeout. |
| `http_response_body_limit_bytes` | no | Positive integer response body limit in bytes. |
When `conditional` is enabled and the upstream returns `304 Not Modified`, the
source emits no events for that poll.
OpenWeather observation URLs must include `units=metric`. Startup fails if the
URL omits it or sets another unit system.
## Sink Fields
| Field | Required | Description |
|---|:---:|---|
| `name` | yes | Unique sink name. Routes refer to this value. |
| `driver` | yes | Sink driver name. |
| `params` | driver-specific | Sink parameters. |
## Sink Drivers
### `stdout`
Prints each event as JSON to stdout.
```yaml
sinks:
- name: stdout
driver: stdout
params: {}
```
### `nats`
Publishes each event as JSON to a NATS subject.
| Param | Required | Description |
|---|:---:|---|
| `url` | yes | NATS server URL, such as `nats://localhost:4222`. |
| `subject` | yes | Subject to publish events to. |
### `postgres`
Writes supported canonical weather events to Postgres using weatherfeeder's
registered schema mapping. The table contract is documented in
[Postgres integration](integrations/postgres.md).
| Param | Required | Description |
|---|:---:|---|
| `uri` | yes | PostgreSQL connection URI. |
| `username` | yes | Database username. |
| `password` | yes | Database password. |
| `prune` | no | Retention window. If set, rows older than the window are pruned on each write transaction. |
`prune` accepts Go duration strings such as `72h`, plus day and week suffixes
such as `3d` and `2w`.
## Routes
Routes connect event kinds to sinks:
```yaml
routes:
- sink: stdout
kinds: ["observation", "alert"]
```
| Field | Required | Description |
|---|:---:|---|
| `sink` | yes | Name of a configured sink. |
| `kinds` | no | Event kinds to send to that sink. Omit or use an empty list to match all kinds. |
Route `kinds` values are trimmed and lowercased by the dispatcher. Blank entries
are rejected.
## Duration Formats
Top-level source `every` accepts:
- Go duration strings such as `30s`, `10m`, or `1h`;
- integer values, interpreted as minutes;
- numeric strings such as `"15"`, also interpreted as minutes.
HTTP param durations such as `http_timeout` accept Go duration strings. Numeric
values and numeric strings are interpreted as seconds.
Postgres `prune` must be a string duration.
## Secrets
The config file is read directly from disk and has no built-in secret expansion.
Keep real credentials out of repository-tracked configs. Use deployment tooling
to render `config.yml` with the needed secret values before starting the daemon.