mirror of https://github.com/hashicorp/consul
469 lines
12 KiB
Plaintext
469 lines
12 KiB
Plaintext
|
---
|
||
|
layout: docs
|
||
|
page_title: Watches
|
||
|
description: >-
|
||
|
Watches are a way of specifying a view of data (e.g. list of nodes, KV pairs,
|
||
|
health checks) which is monitored for updates. When an update is detected, an
|
||
|
external handler is invoked. A handler can be any executable. As an example,
|
||
|
you could watch the status of health checks and notify an external system when
|
||
|
a check is critical.
|
||
|
---
|
||
|
|
||
|
# Watches
|
||
|
|
||
|
Watches are a way of specifying a view of data (e.g. list of nodes, KV pairs, health
|
||
|
checks) which is monitored for updates. When an update is detected, an external handler
|
||
|
is invoked. A handler can be any executable or HTTP endpoint. As an example, you could watch the status
|
||
|
of health checks and notify an external system when a check is critical.
|
||
|
|
||
|
Watches are implemented using blocking queries in the [HTTP API](/api).
|
||
|
Agents automatically make the proper API calls to watch for changes
|
||
|
and inform a handler when the data view has updated.
|
||
|
|
||
|
Watches can be configured as part of the [agent's configuration](/docs/agent/options#watches),
|
||
|
causing them to run once the agent is initialized. Reloading the agent configuration
|
||
|
allows for adding or removing watches dynamically.
|
||
|
|
||
|
Alternatively, the [watch command](/commands/watch) enables a watch to be
|
||
|
started outside of the agent. This can be used by an operator to inspect data in Consul
|
||
|
or to easily pipe data into processes without being tied to the agent lifecycle.
|
||
|
|
||
|
In either case, the `type` of the watch must be specified. Each type of watch
|
||
|
supports different parameters, some required and some optional. These options are specified
|
||
|
in a JSON body when using agent configuration or as CLI flags for the watch command.
|
||
|
|
||
|
## Handlers
|
||
|
|
||
|
The watch configuration specifies the view of data to be monitored.
|
||
|
Once that view is updated, the specified handler is invoked. Handlers can be either an
|
||
|
executable or an HTTP endpoint. A handler receives JSON formatted data
|
||
|
with invocation info, following a format that depends on the type of the watch.
|
||
|
Each watch type documents the format type. Because they map directly to an HTTP
|
||
|
API, handlers should expect the input to match the format of the API. A Consul
|
||
|
index is also given, corresponding to the responses from the
|
||
|
[HTTP API](/api).
|
||
|
|
||
|
### Executable
|
||
|
|
||
|
An executable handler reads the JSON invocation info from stdin. Additionally,
|
||
|
the `CONSUL_INDEX` environment variable will be set to the Consul index
|
||
|
Anything written to stdout is logged.
|
||
|
|
||
|
Here is an example configuration, where `handler_type` is optionally set to
|
||
|
`script`:
|
||
|
|
||
|
```json
|
||
|
{
|
||
|
"type": "key",
|
||
|
"key": "foo/bar/baz",
|
||
|
"handler_type": "script",
|
||
|
"args": ["/usr/bin/my-service-handler.sh", "-redis"]
|
||
|
}
|
||
|
```
|
||
|
|
||
|
Prior to Consul 1.0, watches used a single `handler` field to define the command to run, and
|
||
|
would always run in a shell. In Consul 1.0, the `args` array was added so that handlers can be
|
||
|
run without a shell. The `handler` field is deprecated, and you should include the shell in
|
||
|
the `args` to run under a shell, eg. `"args": ["sh", "-c", "..."]`.
|
||
|
|
||
|
### HTTP endpoint
|
||
|
|
||
|
An HTTP handler sends an HTTP request when a watch is invoked. The JSON invocation info is sent
|
||
|
as a payload along the request. The response also contains the Consul index as a header named
|
||
|
`X-Consul-Index`.
|
||
|
|
||
|
The HTTP handler can be configured by setting `handler_type` to `http`. Additional handler options
|
||
|
are set using `http_handler_config`. The only required parameter is the `path` field which specifies
|
||
|
the URL to the HTTP endpoint. Consul uses `POST` as the default HTTP method, but this is also configurable.
|
||
|
Other optional fields are `header`, `timeout` and `tls_skip_verify`. The watch invocation data is
|
||
|
always sent as a JSON payload.
|
||
|
|
||
|
Here is an example configuration:
|
||
|
|
||
|
```json
|
||
|
{
|
||
|
"type": "key",
|
||
|
"key": "foo/bar/baz",
|
||
|
"handler_type": "http",
|
||
|
"http_handler_config": {
|
||
|
"path": "https://localhost:8000/watch",
|
||
|
"method": "POST",
|
||
|
"header": { "x-foo": ["bar", "baz"] },
|
||
|
"timeout": "10s",
|
||
|
"tls_skip_verify": false
|
||
|
}
|
||
|
}
|
||
|
```
|
||
|
|
||
|
## Global Parameters
|
||
|
|
||
|
In addition to the parameters supported by each option type, there
|
||
|
are a few global parameters that all watches support:
|
||
|
|
||
|
- `datacenter` - Can be provided to override the agent's default datacenter.
|
||
|
- `token` - Can be provided to override the agent's default ACL token.
|
||
|
- `args` - The handler subprocess and arguments to invoke when the data view updates.
|
||
|
- `handler` - The handler shell command to invoke when the data view updates.
|
||
|
|
||
|
## Watch Types
|
||
|
|
||
|
The following types are supported. Detailed documentation on each is below:
|
||
|
|
||
|
- [`key`](#key) - Watch a specific KV pair
|
||
|
- [`keyprefix`](#keyprefix) - Watch a prefix in the KV store
|
||
|
- [`services`](#services) - Watch the list of available services
|
||
|
- [`nodes`](#nodes) - Watch the list of nodes
|
||
|
- [`service`](#service)- Watch the instances of a service
|
||
|
- [`checks`](#checks) - Watch the value of health checks
|
||
|
- [`event`](#event) - Watch for custom user events
|
||
|
|
||
|
### Type: key ((#key))
|
||
|
|
||
|
The "key" watch type is used to watch a specific key in the KV store.
|
||
|
It requires that the "key" parameter be specified.
|
||
|
|
||
|
This maps to the `/v1/kv/` API internally.
|
||
|
|
||
|
Here is an example configuration:
|
||
|
|
||
|
```javascript
|
||
|
{
|
||
|
"type": "key",
|
||
|
"key": "foo/bar/baz",
|
||
|
"args": ["/usr/bin/my-service-handler.sh", "-redis"]
|
||
|
}
|
||
|
```
|
||
|
|
||
|
Or, using the watch command:
|
||
|
|
||
|
```shell-session
|
||
|
$ consul watch -type=key -key=foo/bar/baz /usr/bin/my-key-handler.sh
|
||
|
```
|
||
|
|
||
|
An example of the output of this command:
|
||
|
|
||
|
```json
|
||
|
{
|
||
|
"Key": "foo/bar/baz",
|
||
|
"CreateIndex": 1793,
|
||
|
"ModifyIndex": 1793,
|
||
|
"LockIndex": 0,
|
||
|
"Flags": 0,
|
||
|
"Value": "aGV5",
|
||
|
"Session": ""
|
||
|
}
|
||
|
```
|
||
|
|
||
|
### Type: keyprefix ((#keyprefix))
|
||
|
|
||
|
The "keyprefix" watch type is used to watch a prefix of keys in the KV store.
|
||
|
It requires that the "prefix" parameter be specified. This watch
|
||
|
returns _all_ keys matching the prefix whenever _any_ key matching the prefix
|
||
|
changes.
|
||
|
|
||
|
This maps to the `/v1/kv/` API internally.
|
||
|
|
||
|
Here is an example configuration:
|
||
|
|
||
|
```json
|
||
|
{
|
||
|
"type": "keyprefix",
|
||
|
"prefix": "foo/",
|
||
|
"args": ["/usr/bin/my-prefix-handler.sh", "-redis"]
|
||
|
}
|
||
|
```
|
||
|
|
||
|
Or, using the watch command:
|
||
|
|
||
|
```shell-session
|
||
|
$ consul watch -type=keyprefix -prefix=foo/ /usr/bin/my-prefix-handler.sh
|
||
|
```
|
||
|
|
||
|
An example of the output of this command:
|
||
|
|
||
|
```text
|
||
|
[
|
||
|
{
|
||
|
Key: 'foo/bar',
|
||
|
CreateIndex: 1796,
|
||
|
ModifyIndex: 1796,
|
||
|
LockIndex: 0,
|
||
|
Flags: 0,
|
||
|
Value: 'TU9BUg==',
|
||
|
Session: '',
|
||
|
},
|
||
|
{
|
||
|
Key: 'foo/baz',
|
||
|
CreateIndex: 1795,
|
||
|
ModifyIndex: 1795,
|
||
|
LockIndex: 0,
|
||
|
Flags: 0,
|
||
|
Value: 'YXNkZg==',
|
||
|
Session: '',
|
||
|
},
|
||
|
{
|
||
|
Key: 'foo/test',
|
||
|
CreateIndex: 1793,
|
||
|
ModifyIndex: 1793,
|
||
|
LockIndex: 0,
|
||
|
Flags: 0,
|
||
|
Value: 'aGV5',
|
||
|
Session: '',
|
||
|
},
|
||
|
]
|
||
|
```
|
||
|
|
||
|
### Type: services ((#services))
|
||
|
|
||
|
The "services" watch type is used to watch the list of available
|
||
|
services. It has no parameters.
|
||
|
|
||
|
This maps to the `/v1/catalog/services` API internally.
|
||
|
|
||
|
An example of the output of this command:
|
||
|
|
||
|
```json
|
||
|
{
|
||
|
"consul": [],
|
||
|
"redis": [],
|
||
|
"web": []
|
||
|
}
|
||
|
```
|
||
|
|
||
|
### Type: nodes ((#nodes))
|
||
|
|
||
|
The "nodes" watch type is used to watch the list of available
|
||
|
nodes. It has no parameters.
|
||
|
|
||
|
This maps to the `/v1/catalog/nodes` API internally.
|
||
|
|
||
|
An example of the output of this command:
|
||
|
|
||
|
```text
|
||
|
[
|
||
|
{
|
||
|
Node: 'nyc1-consul-1',
|
||
|
Address: '192.241.159.115',
|
||
|
},
|
||
|
{
|
||
|
Node: 'nyc1-consul-2',
|
||
|
Address: '192.241.158.205',
|
||
|
},
|
||
|
{
|
||
|
Node: 'nyc1-consul-3',
|
||
|
Address: '198.199.77.133',
|
||
|
},
|
||
|
{
|
||
|
Node: 'nyc1-worker-1',
|
||
|
Address: '162.243.162.228',
|
||
|
},
|
||
|
{
|
||
|
Node: 'nyc1-worker-2',
|
||
|
Address: '162.243.162.226',
|
||
|
},
|
||
|
{
|
||
|
Node: 'nyc1-worker-3',
|
||
|
Address: '162.243.162.229',
|
||
|
}
|
||
|
]
|
||
|
```
|
||
|
|
||
|
### Type: service ((#service))
|
||
|
|
||
|
The "service" watch type is used to monitor the providers
|
||
|
of a single service. It requires the "service" parameter
|
||
|
and optionally takes the parameters "tag" and
|
||
|
"passingonly". The "tag" parameter will filter by one or more tags.
|
||
|
It may be either a single string value or a slice of strings.
|
||
|
The "passingonly" is a boolean that will filter to only the
|
||
|
instances passing all health checks.
|
||
|
|
||
|
This maps to the `/v1/health/service` API internally.
|
||
|
|
||
|
Here is an example configuration with a single tag:
|
||
|
|
||
|
```json
|
||
|
{
|
||
|
"type": "service",
|
||
|
"service": "redis",
|
||
|
"args": ["/usr/bin/my-service-handler.sh", "-redis"],
|
||
|
"tag": "bar"
|
||
|
}
|
||
|
```
|
||
|
|
||
|
Here is an example configuration with multiple tags:
|
||
|
|
||
|
```json
|
||
|
{
|
||
|
"type": "service",
|
||
|
"service": "redis",
|
||
|
"args": ["/usr/bin/my-service-handler.sh", "-redis"],
|
||
|
"tag": ["bar", "foo"]
|
||
|
}
|
||
|
```
|
||
|
|
||
|
Or, using the watch command:
|
||
|
|
||
|
Single tag:
|
||
|
|
||
|
```shell-session
|
||
|
$ consul watch -type=service -service=redis -tag=bar /usr/bin/my-service-handler.sh
|
||
|
```
|
||
|
|
||
|
Multiple tag:
|
||
|
|
||
|
```shell-session
|
||
|
$ consul watch -type=service -service=redis -tag=bar -tag=foo /usr/bin/my-service-handler.sh
|
||
|
```
|
||
|
|
||
|
An example of the output of this command:
|
||
|
|
||
|
```text
|
||
|
[
|
||
|
{
|
||
|
Node: {
|
||
|
Node: 'foobar',
|
||
|
Address: '10.1.10.12',
|
||
|
},
|
||
|
Service: {
|
||
|
ID: 'redis',
|
||
|
Service: 'redis',
|
||
|
Tags: ['bar', 'foo'],
|
||
|
Port: 8000,
|
||
|
},
|
||
|
Checks: [
|
||
|
{
|
||
|
Node: 'foobar',
|
||
|
CheckID: 'service:redis',
|
||
|
Name: "Service 'redis' check",
|
||
|
Status: 'passing',
|
||
|
Notes: '',
|
||
|
Output: '',
|
||
|
ServiceID: 'redis',
|
||
|
ServiceName: 'redis',
|
||
|
},
|
||
|
{
|
||
|
Node: 'foobar',
|
||
|
CheckID: 'serfHealth',
|
||
|
Name: 'Serf Health Status',
|
||
|
Status: 'passing',
|
||
|
Notes: '',
|
||
|
Output: '',
|
||
|
ServiceID: '',
|
||
|
ServiceName: '',
|
||
|
},
|
||
|
],
|
||
|
}
|
||
|
]
|
||
|
```
|
||
|
|
||
|
### Type: checks ((#checks))
|
||
|
|
||
|
The "checks" watch type is used to monitor the checks of a given
|
||
|
service or those in a specific state. It optionally takes the "service"
|
||
|
parameter to filter to a specific service or the "state" parameter to
|
||
|
filter to a specific state. By default, it will watch all checks.
|
||
|
|
||
|
This maps to the `/v1/health/state/` API if monitoring by state
|
||
|
or `/v1/health/checks/` if monitoring by service.
|
||
|
|
||
|
Here is an example configuration for monitoring by state:
|
||
|
|
||
|
```json
|
||
|
{
|
||
|
"type": "checks",
|
||
|
"state": "passing",
|
||
|
"args": ["/usr/bin/my-check-handler.sh", "-passing"]
|
||
|
}
|
||
|
```
|
||
|
|
||
|
Here is an example configuration for monitoring by service:
|
||
|
|
||
|
```json
|
||
|
{
|
||
|
"type": "checks",
|
||
|
"service": "redis",
|
||
|
"args": ["/usr/bin/my-check-handler.sh", "-redis"]
|
||
|
}
|
||
|
```
|
||
|
|
||
|
Or, using the watch command:
|
||
|
|
||
|
State:
|
||
|
|
||
|
```shell-session
|
||
|
$ consul watch -type=checks -state=passing /usr/bin/my-check-handler.sh -passing
|
||
|
```
|
||
|
|
||
|
Service:
|
||
|
|
||
|
```shell-session
|
||
|
$ consul watch -type=checks -service=redis /usr/bin/my-check-handler.sh -redis
|
||
|
```
|
||
|
|
||
|
An example of the output of this command:
|
||
|
|
||
|
```json
|
||
|
[
|
||
|
{
|
||
|
"Node": "foobar",
|
||
|
"CheckID": "service:redis",
|
||
|
"Name": "Service 'redis' check",
|
||
|
"Status": "passing",
|
||
|
"Notes": "",
|
||
|
"Output": "",
|
||
|
"ServiceID": "redis",
|
||
|
"ServiceName": "redis"
|
||
|
}
|
||
|
]
|
||
|
```
|
||
|
|
||
|
### Type: event ((#event))
|
||
|
|
||
|
The "event" watch type is used to monitor for custom user
|
||
|
events. These are fired using the [consul event](/commands/event) command.
|
||
|
It takes only a single optional "name" parameter which restricts
|
||
|
the watch to only events with the given name.
|
||
|
|
||
|
This maps to the `/v1/event/list` API internally.
|
||
|
|
||
|
Here is an example configuration:
|
||
|
|
||
|
```json
|
||
|
{
|
||
|
"type": "event",
|
||
|
"name": "web-deploy",
|
||
|
"args": ["/usr/bin/my-event-handler.sh", "-web-deploy"]
|
||
|
}
|
||
|
```
|
||
|
|
||
|
Or, using the watch command:
|
||
|
|
||
|
```shell-session
|
||
|
$ consul watch -type=event -name=web-deploy /usr/bin/my-event-handler.sh -web-deploy
|
||
|
```
|
||
|
|
||
|
An example of the output of this command:
|
||
|
|
||
|
```json
|
||
|
[
|
||
|
{
|
||
|
"ID": "f07f3fcc-4b7d-3a7c-6d1e-cf414039fcee",
|
||
|
"Name": "web-deploy",
|
||
|
"Payload": "MTYwOTAzMA==",
|
||
|
"NodeFilter": "",
|
||
|
"ServiceFilter": "",
|
||
|
"TagFilter": "",
|
||
|
"Version": 1,
|
||
|
"LTime": 18
|
||
|
},
|
||
|
...
|
||
|
]
|
||
|
```
|
||
|
|
||
|
To fire a new `web-deploy` event the following could be used:
|
||
|
|
||
|
```shell-session
|
||
|
$ consul event -name=web-deploy 1609030
|
||
|
```
|