The observers are responsible for discovering monitoring targets. Examples of
targets are an open TCP port on a container, or a Kubernetes Node, or a
listening TCP socket on localhost. For these discovered targets to result in a
new monitor instance that is monitoring that target, you must apply discovery
rules to your monitor configuration. Every monitor that supports monitoring
specific services (i.e. not a static monitor like the cpu
monitor) can be
configured with a discoveryRule
config option that specifies a rule using a
mini rule language.
For example, to monitor a Redis instance that has been discovered by a container-based observer, you could use the following configuration:
monitors:
- type: collectd/redis
discoveryRule: container_image =~ "redis" && port == 6379
There are currently several target types that can be discovered by the various
observers in the agent. You can match these target types explicitly in your
discovery rules with the expression target == <type>
, where <types>
are:
-
pod
: A Kubernetes pod as a whole. Thehost
field will be populated with the Pod IP address, but no specificport
. -
hostport
: A host and port combination, i.e. a network endpoint. This endpoint could be on any type of runtime, e.g. container, remote host, running on same host with no container. This type of target will always havehost
,port
, andport_type
fields set. -
container
: A container, e.g. a Docker container. Thehost
field will be populated with the container IP address, but noport
will be specified. -
k8s-node
: A Kubernetes Node -- thehost
field will be populated with the Node's Internal DNS name or IP address.
You don't have to specify the target
in your discovery rules, but it can help
to prevent ambiguity.
A rule is an expression that is matched against each discovered target to determine if a monitor should be active for a particular target. The basic operators are:
Operator | Description |
---|---|
== | Equals |
!= | Not equals |
< | Less than |
<= | Less than or equal |
> | Greater than |
>= | Greater than or equal |
=~ | Regex matches |
!~ | Regex does not match |
&& | And |
|| | Or |
For all available operators, see the
expr language definition (this is what the agent uses under the covers).
We have a shim set of logic that lets you use the =~
operator even though it
is not actually part of the expr language -- mainly to preserve backwards
compatibility with older agent releases before expr was used.
The variables available in the expression are dependent on which observer you are using and the type of target(s) it is producing. See the individual observer docs for details on the variables available.
For a list of observers and the discovery rule variables they provide, see Observers.
In addition, these extra functions are provided:
-
Sprintf(format, args...)
: This is your typical printf style function that can be used to compose strings from a complex set of disparately typed variables. Underneath this is the Golang fmt.Sprintf function. -
Getenv(envvar)
: Gets an environment variable set on the agent process, or a blank string if the specified envvar is not set.
There are no implicit rules built into the agent, so each rule must be specified manually in the config file, in conjunction with the monitor that should monitor the discovered target.
Sometimes it might be useful to use certain attributes of a discovered target. These discovered targets are created by observers and will usually contain a full set of metadata that the observer obtains coincidently when it is doing discovery (e.g. container labels). This metadata can be mapped directly to monitor configuration for the monitor that is instantiated for that target.
To do this, you can set the configEndpointMappings option
on a monitor config block (endpoint was the old name for target). For
example, the collectd/kafka
monitor has the clusterName
config option,
which is an arbirary value used to group together broker instances. You could
derive this from the cluster
container label on the kafka container instances
like this:
monitors:
- type: collectd/kafka
discoveryRule: 'container_image =~ "kafka" && port == 9999'
configEndpointMappings:
clusterName: 'Get(container_labels, "cluster")'
The simplest way to see what services an instance of the agent has discovered
is to run the command signalfx-agent status endpoints
. The fields shown will
be the same values that can be used in discovery rules.
While service discovery is useful, sometimes it is just easier to manually
define services to monitor. This can be done by setting the host
and
port
option in a monitor's config to the host and port that you need to
monitor. These two values are the core of what the auto-discovery mechanism
often provides for you automatically.
For example (making use of YAML references to reduce repetition):
- &es
type: elasticsearch
username: admin
password: s3cr3t
host: es
port: 9200
- <<: *es
host: es2
port: 9300
This would monitor two ElasticSearch instances at the given hosts and ports and would use the same username and password given in the top-level monitor config to connect to both of them. If you needed different configuration for the two ES hosts, you could simply define two monitor configurations, each with one service endpoint.
It is invalid to have both manually defined service endpoints and a discovery rule on a single monitor configuration.