mirror of
https://github.com/prometheus/prometheus.git
synced 2024-12-25 05:34:05 -08:00
Add AZ ID label to discovered EC2 targets (#8896)
* Add AZ ID to EC2 SD Signed-off-by: George Brighton <george@gebn.co.uk>
This commit is contained in:
parent
b1ed4a0a66
commit
bc0e76c8a3
|
@ -28,6 +28,7 @@ import (
|
||||||
"github.com/aws/aws-sdk-go/aws/session"
|
"github.com/aws/aws-sdk-go/aws/session"
|
||||||
"github.com/aws/aws-sdk-go/service/ec2"
|
"github.com/aws/aws-sdk-go/service/ec2"
|
||||||
"github.com/go-kit/log"
|
"github.com/go-kit/log"
|
||||||
|
"github.com/go-kit/log/level"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/prometheus/common/config"
|
"github.com/prometheus/common/config"
|
||||||
"github.com/prometheus/common/model"
|
"github.com/prometheus/common/model"
|
||||||
|
@ -42,6 +43,7 @@ const (
|
||||||
ec2Label = model.MetaLabelPrefix + "ec2_"
|
ec2Label = model.MetaLabelPrefix + "ec2_"
|
||||||
ec2LabelAMI = ec2Label + "ami"
|
ec2LabelAMI = ec2Label + "ami"
|
||||||
ec2LabelAZ = ec2Label + "availability_zone"
|
ec2LabelAZ = ec2Label + "availability_zone"
|
||||||
|
ec2LabelAZID = ec2Label + "availability_zone_id"
|
||||||
ec2LabelArch = ec2Label + "architecture"
|
ec2LabelArch = ec2Label + "architecture"
|
||||||
ec2LabelIPv6Addresses = ec2Label + "ipv6_addresses"
|
ec2LabelIPv6Addresses = ec2Label + "ipv6_addresses"
|
||||||
ec2LabelInstanceID = ec2Label + "instance_id"
|
ec2LabelInstanceID = ec2Label + "instance_id"
|
||||||
|
@ -132,8 +134,14 @@ func (c *EC2SDConfig) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
||||||
// the Discoverer interface.
|
// the Discoverer interface.
|
||||||
type EC2Discovery struct {
|
type EC2Discovery struct {
|
||||||
*refresh.Discovery
|
*refresh.Discovery
|
||||||
cfg *EC2SDConfig
|
logger log.Logger
|
||||||
ec2 *ec2.EC2
|
cfg *EC2SDConfig
|
||||||
|
ec2 *ec2.EC2
|
||||||
|
|
||||||
|
// azToAZID maps this account's availability zones to their underlying AZ
|
||||||
|
// ID, e.g. eu-west-2a -> euw2-az2. Refreshes are performed sequentially, so
|
||||||
|
// no locking is required.
|
||||||
|
azToAZID map[string]string
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewEC2Discovery returns a new EC2Discovery which periodically refreshes its targets.
|
// NewEC2Discovery returns a new EC2Discovery which periodically refreshes its targets.
|
||||||
|
@ -142,7 +150,8 @@ func NewEC2Discovery(conf *EC2SDConfig, logger log.Logger) *EC2Discovery {
|
||||||
logger = log.NewNopLogger()
|
logger = log.NewNopLogger()
|
||||||
}
|
}
|
||||||
d := &EC2Discovery{
|
d := &EC2Discovery{
|
||||||
cfg: conf,
|
logger: logger,
|
||||||
|
cfg: conf,
|
||||||
}
|
}
|
||||||
d.Discovery = refresh.NewDiscovery(
|
d.Discovery = refresh.NewDiscovery(
|
||||||
logger,
|
logger,
|
||||||
|
@ -153,7 +162,7 @@ func NewEC2Discovery(conf *EC2SDConfig, logger log.Logger) *EC2Discovery {
|
||||||
return d
|
return d
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *EC2Discovery) ec2Client() (*ec2.EC2, error) {
|
func (d *EC2Discovery) ec2Client(ctx context.Context) (*ec2.EC2, error) {
|
||||||
if d.ec2 != nil {
|
if d.ec2 != nil {
|
||||||
return d.ec2, nil
|
return d.ec2, nil
|
||||||
}
|
}
|
||||||
|
@ -185,8 +194,28 @@ func (d *EC2Discovery) ec2Client() (*ec2.EC2, error) {
|
||||||
return d.ec2, nil
|
return d.ec2, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *EC2Discovery) azID(ctx context.Context, az string) (string, error) {
|
||||||
|
if azID, ok := d.azToAZID[az]; ok {
|
||||||
|
return azID, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
azs, err := d.ec2.DescribeAvailabilityZonesWithContext(ctx, &ec2.DescribeAvailabilityZonesInput{})
|
||||||
|
if err != nil {
|
||||||
|
return "", errors.Wrap(err, "could not describe availability zones")
|
||||||
|
}
|
||||||
|
d.azToAZID = make(map[string]string, len(azs.AvailabilityZones))
|
||||||
|
for _, az := range azs.AvailabilityZones {
|
||||||
|
d.azToAZID[*az.ZoneName] = *az.ZoneId
|
||||||
|
}
|
||||||
|
|
||||||
|
if azID, ok := d.azToAZID[az]; ok {
|
||||||
|
return azID, nil
|
||||||
|
}
|
||||||
|
return "", fmt.Errorf("no availability zone ID mapping found for %s", az)
|
||||||
|
}
|
||||||
|
|
||||||
func (d *EC2Discovery) refresh(ctx context.Context) ([]*targetgroup.Group, error) {
|
func (d *EC2Discovery) refresh(ctx context.Context) ([]*targetgroup.Group, error) {
|
||||||
ec2Client, err := d.ec2Client()
|
ec2Client, err := d.ec2Client(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -211,6 +240,14 @@ func (d *EC2Discovery) refresh(ctx context.Context) ([]*targetgroup.Group, error
|
||||||
if inst.PrivateIpAddress == nil {
|
if inst.PrivateIpAddress == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
azID, err := d.azID(ctx, *inst.Placement.AvailabilityZone)
|
||||||
|
if err != nil {
|
||||||
|
level.Warn(d.logger).Log(
|
||||||
|
"msg", "Unable to determine availability zone ID",
|
||||||
|
"az", *inst.Placement.AvailabilityZone,
|
||||||
|
"err", err)
|
||||||
|
}
|
||||||
|
|
||||||
labels := model.LabelSet{
|
labels := model.LabelSet{
|
||||||
ec2LabelInstanceID: model.LabelValue(*inst.InstanceId),
|
ec2LabelInstanceID: model.LabelValue(*inst.InstanceId),
|
||||||
}
|
}
|
||||||
|
@ -237,6 +274,7 @@ func (d *EC2Discovery) refresh(ctx context.Context) ([]*targetgroup.Group, error
|
||||||
|
|
||||||
labels[ec2LabelAMI] = model.LabelValue(*inst.ImageId)
|
labels[ec2LabelAMI] = model.LabelValue(*inst.ImageId)
|
||||||
labels[ec2LabelAZ] = model.LabelValue(*inst.Placement.AvailabilityZone)
|
labels[ec2LabelAZ] = model.LabelValue(*inst.Placement.AvailabilityZone)
|
||||||
|
labels[ec2LabelAZID] = model.LabelValue(azID)
|
||||||
labels[ec2LabelInstanceState] = model.LabelValue(*inst.State.Name)
|
labels[ec2LabelInstanceState] = model.LabelValue(*inst.State.Name)
|
||||||
labels[ec2LabelInstanceType] = model.LabelValue(*inst.InstanceType)
|
labels[ec2LabelInstanceType] = model.LabelValue(*inst.InstanceType)
|
||||||
|
|
||||||
|
|
|
@ -893,6 +893,7 @@ The following meta labels are available on targets during [relabeling](#relabel_
|
||||||
* `__meta_ec2_ami`: the EC2 Amazon Machine Image
|
* `__meta_ec2_ami`: the EC2 Amazon Machine Image
|
||||||
* `__meta_ec2_architecture`: the architecture of the instance
|
* `__meta_ec2_architecture`: the architecture of the instance
|
||||||
* `__meta_ec2_availability_zone`: the availability zone in which the instance is running
|
* `__meta_ec2_availability_zone`: the availability zone in which the instance is running
|
||||||
|
* `__meta_ec2_availability_zone_id`: the [availability zone ID](https://docs.aws.amazon.com/ram/latest/userguide/working-with-az-ids.html) in which the instance is running
|
||||||
* `__meta_ec2_instance_id`: the EC2 instance ID
|
* `__meta_ec2_instance_id`: the EC2 instance ID
|
||||||
* `__meta_ec2_instance_lifecycle`: the lifecycle of the EC2 instance, set only for 'spot' or 'scheduled' instances, absent otherwise
|
* `__meta_ec2_instance_lifecycle`: the lifecycle of the EC2 instance, set only for 'spot' or 'scheduled' instances, absent otherwise
|
||||||
* `__meta_ec2_instance_state`: the state of the EC2 instance
|
* `__meta_ec2_instance_state`: the state of the EC2 instance
|
||||||
|
|
Loading…
Reference in a new issue