Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add awsfargate module for AWS ECS Fargate #22034

Merged
merged 18 commits into from
Nov 23, 2020
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
529 changes: 529 additions & 0 deletions metricbeat/docs/fields.asciidoc

Large diffs are not rendered by default.

43 changes: 43 additions & 0 deletions metricbeat/docs/modules/awsfargate.asciidoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
////
This file is generated! See scripts/mage/docs_collector.go
////

[[metricbeat-module-awsfargate]]
[role="xpack"]
== AWS Fargate module

experimental[]

Amazon ECS on Fargate provides a method to retrieve various metadata, network
metrics, and Docker stats about tasks and containers. This is referred to as the
https://docs.aws.amazon.com/AmazonECS/latest/userguide/task-metadata-endpoint-v4-fargate.html[task metadata endpoint]
and this endpoint is available per container.

The awsfargate module is a Metricbeat module which collects AWS fargate metrics
from task metadata endpoint.


[float]
=== Example configuration

The AWS Fargate module supports the standard configuration options that are described
in <<configuration-metricbeat>>. Here is an example configuration:

[source,yaml]
----
metricbeat.modules:
- module: awsfargate
period: 10s
metricsets:
- task_stats
----

[float]
=== Metricsets

The following metricsets are available:

* <<metricbeat-metricset-awsfargate-task_stats,task_stats>>

include::awsfargate/task_stats.asciidoc[]

25 changes: 25 additions & 0 deletions metricbeat/docs/modules/awsfargate/task_stats.asciidoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
////
This file is generated! See scripts/mage/docs_collector.go
////

[[metricbeat-metricset-awsfargate-task_stats]]
[role="xpack"]
=== AWS Fargate task_stats metricset

experimental[]

include::../../../../x-pack/metricbeat/module/awsfargate/task_stats/_meta/docs.asciidoc[]

This is a default metricset. If the host module is unconfigured, this metricset is enabled by default.

==== Fields

For a description of each field in the metricset, see the
<<exported-fields-awsfargate,exported fields>> section.

Here is an example document generated by this metricset:

[source,json]
----
include::../../../../x-pack/metricbeat/module/awsfargate/task_stats/_meta/data.json[]
----
1 change: 0 additions & 1 deletion metricbeat/docs/modules/docker/container.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ This file is generated! See scripts/mage/docs_collector.go

include::../../../module/docker/container/_meta/docs.asciidoc[]

This is a default metricset. If the host module is unconfigured, this metricset is enabled by default.
kaiyan-sheng marked this conversation as resolved.
Show resolved Hide resolved

==== Fields

Expand Down
1 change: 0 additions & 1 deletion metricbeat/docs/modules/docker/diskio.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ This file is generated! See scripts/mage/docs_collector.go

include::../../../module/docker/diskio/_meta/docs.asciidoc[]

This is a default metricset. If the host module is unconfigured, this metricset is enabled by default.

==== Fields

Expand Down
1 change: 0 additions & 1 deletion metricbeat/docs/modules/docker/event.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ This file is generated! See scripts/mage/docs_collector.go

include::../../../module/docker/event/_meta/docs.asciidoc[]

This is a default metricset. If the host module is unconfigured, this metricset is enabled by default.

==== Fields

Expand Down
1 change: 0 additions & 1 deletion metricbeat/docs/modules/docker/healthcheck.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ This file is generated! See scripts/mage/docs_collector.go

include::../../../module/docker/healthcheck/_meta/docs.asciidoc[]

This is a default metricset. If the host module is unconfigured, this metricset is enabled by default.

==== Fields

Expand Down
1 change: 0 additions & 1 deletion metricbeat/docs/modules/docker/info.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ This file is generated! See scripts/mage/docs_collector.go

include::../../../module/docker/info/_meta/docs.asciidoc[]

This is a default metricset. If the host module is unconfigured, this metricset is enabled by default.

==== Fields

Expand Down
1 change: 0 additions & 1 deletion metricbeat/docs/modules/docker/memory.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ This file is generated! See scripts/mage/docs_collector.go

include::../../../module/docker/memory/_meta/docs.asciidoc[]

This is a default metricset. If the host module is unconfigured, this metricset is enabled by default.

==== Fields

Expand Down
1 change: 0 additions & 1 deletion metricbeat/docs/modules/docker/network.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ This file is generated! See scripts/mage/docs_collector.go

include::../../../module/docker/network/_meta/docs.asciidoc[]

This is a default metricset. If the host module is unconfigured, this metricset is enabled by default.

==== Fields

Expand Down
3 changes: 3 additions & 0 deletions metricbeat/docs/modules_list.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ This file is generated! See scripts/mage/docs_collector.go
|<<metricbeat-metricset-aws-transitgateway,transitgateway>> beta[]
|<<metricbeat-metricset-aws-usage,usage>> beta[]
|<<metricbeat-metricset-aws-vpn,vpn>> beta[]
|<<metricbeat-module-awsfargate,AWS Fargate>> experimental[] |image:./images/icon-no.png[No prebuilt dashboards] |
.1+| .1+| |<<metricbeat-metricset-awsfargate-task_stats,task_stats>> experimental[]
|<<metricbeat-module-azure,Azure>> |image:./images/icon-yes.png[Prebuilt dashboards are available] |
.11+| .11+| |<<metricbeat-metricset-azure-app_insights,app_insights>> beta[]
|<<metricbeat-metricset-azure-app_state,app_state>> beta[]
Expand Down Expand Up @@ -296,6 +298,7 @@ include::modules/aerospike.asciidoc[]
include::modules/apache.asciidoc[]
include::modules/appsearch.asciidoc[]
include::modules/aws.asciidoc[]
include::modules/awsfargate.asciidoc[]
include::modules/azure.asciidoc[]
include::modules/beat.asciidoc[]
include::modules/ceph.asciidoc[]
Expand Down
4 changes: 2 additions & 2 deletions metricbeat/module/docker/cpu/cpu_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ import (

var cpuService CPUService

func cpuUsageFor(stats types.StatsJSON) *cpuUsage {
u := cpuUsage{
func cpuUsageFor(stats types.StatsJSON) *CPUUsage {
u := CPUUsage{
Stat: &docker.Stat{Stats: stats},
systemDelta: 1000000000, // Nanoseconds in a second
}
Expand Down
29 changes: 15 additions & 14 deletions metricbeat/module/docker/cpu/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ func (c *CPUService) getCPUStatsList(rawStats []docker.Stat, dedot bool) []CPUSt
}

func (c *CPUService) getCPUStats(myRawStat *docker.Stat, dedot bool) CPUStats {
usage := cpuUsage{Stat: myRawStat}
usage := CPUUsage{Stat: myRawStat}

stats := CPUStats{
Time: common.Time(myRawStat.Stats.Read),
Expand All @@ -89,7 +89,8 @@ func (c *CPUService) getCPUStats(myRawStat *docker.Stat, dedot bool) CPUStats {

// TODO: These helper should be merged with the cpu helper in system/cpu

type cpuUsage struct {
// CPUUsage is a struct representation of container CPU usage stats
type CPUUsage struct {
*docker.Stat

cpus uint32
Expand All @@ -98,7 +99,7 @@ type cpuUsage struct {

// CPUS returns the number of cpus. If number of cpus is equal to zero, the field will
// be updated/initialized with the corresponding value retrieved from Docker API.
func (u *cpuUsage) CPUs() uint32 {
func (u *CPUUsage) CPUs() uint32 {
if u.cpus == 0 {
if u.Stats.CPUStats.OnlineCPUs != 0 {
u.cpus = u.Stats.CPUStats.OnlineCPUs
Expand All @@ -119,15 +120,15 @@ func (u *cpuUsage) CPUs() uint32 {
}

// SystemDelta calculates system delta.
func (u *cpuUsage) SystemDelta() uint64 {
func (u *CPUUsage) SystemDelta() uint64 {
if u.systemDelta == 0 {
u.systemDelta = u.Stats.CPUStats.SystemUsage - u.Stats.PreCPUStats.SystemUsage
}
return u.systemDelta
}

// PerCPU calculates per CPU usage.
func (u *cpuUsage) PerCPU() common.MapStr {
func (u *CPUUsage) PerCPU() common.MapStr {
var output common.MapStr
if len(u.Stats.CPUStats.CPUUsage.PercpuUsage) == len(u.Stats.PreCPUStats.CPUUsage.PercpuUsage) {
output = common.MapStr{}
Expand All @@ -151,50 +152,50 @@ func (u *cpuUsage) PerCPU() common.MapStr {
}

// TotalNormalized calculates total CPU usage normalized.
func (u *cpuUsage) Total() float64 {
func (u *CPUUsage) Total() float64 {
return u.calculatePercentage(u.Stats.CPUStats.CPUUsage.TotalUsage, u.Stats.PreCPUStats.CPUUsage.TotalUsage, u.CPUs())
}

// TotalNormalized calculates total CPU usage normalized by the number of CPU cores.
func (u *cpuUsage) TotalNormalized() float64 {
func (u *CPUUsage) TotalNormalized() float64 {
return u.calculatePercentage(u.Stats.CPUStats.CPUUsage.TotalUsage, u.Stats.PreCPUStats.CPUUsage.TotalUsage, 1)
}

// InKernelMode calculates percentage of time in kernel space.
func (u *cpuUsage) InKernelMode() float64 {
func (u *CPUUsage) InKernelMode() float64 {
return u.calculatePercentage(u.Stats.CPUStats.CPUUsage.UsageInKernelmode, u.Stats.PreCPUStats.CPUUsage.UsageInKernelmode, u.CPUs())
}

// InKernelModeNormalized calculates percentage of time in kernel space normalized by the number of CPU cores.
func (u *cpuUsage) InKernelModeNormalized() float64 {
func (u *CPUUsage) InKernelModeNormalized() float64 {
return u.calculatePercentage(u.Stats.CPUStats.CPUUsage.UsageInKernelmode, u.Stats.PreCPUStats.CPUUsage.UsageInKernelmode, 1)
}

// InUserMode calculates percentage of time in user space.
func (u *cpuUsage) InUserMode() float64 {
func (u *CPUUsage) InUserMode() float64 {
return u.calculatePercentage(u.Stats.CPUStats.CPUUsage.UsageInUsermode, u.Stats.PreCPUStats.CPUUsage.UsageInUsermode, u.CPUs())
}

// InUserModeNormalized calculates percentage of time in user space normalized by the number of CPU cores.
func (u *cpuUsage) InUserModeNormalized() float64 {
func (u *CPUUsage) InUserModeNormalized() float64 {
return u.calculatePercentage(u.Stats.CPUStats.CPUUsage.UsageInUsermode, u.Stats.PreCPUStats.CPUUsage.UsageInUsermode, 1)
}

// System calculates percentage of total CPU time in the system.
func (u *cpuUsage) System() float64 {
func (u *CPUUsage) System() float64 {
return u.calculatePercentage(u.Stats.CPUStats.SystemUsage, u.Stats.PreCPUStats.SystemUsage, u.CPUs())
}

// SystemNormalized calculates percentage of total CPU time in the system, normalized by the number of CPU cores.
func (u *cpuUsage) SystemNormalized() float64 {
func (u *CPUUsage) SystemNormalized() float64 {
return u.calculatePercentage(u.Stats.CPUStats.SystemUsage, u.Stats.PreCPUStats.SystemUsage, 1)
}

// This function is meant to calculate the % CPU time change between two successive readings.
// The "oldValue" refers to the CPU statistics of the last read.
// Time here is expressed by second and not by nanoseconde.
// The main goal is to expose the %, in the same way, it's displayed by docker Client.
func (u *cpuUsage) calculatePercentage(newValue uint64, oldValue uint64, numCPUS uint32) float64 {
func (u *CPUUsage) calculatePercentage(newValue uint64, oldValue uint64, numCPUS uint32) float64 {
if newValue < oldValue {
logp.Err("Error calculating CPU time change for docker module: new stats value (%v) is lower than the old one(%v)", newValue, oldValue)
return -1
Expand Down
2 changes: 2 additions & 0 deletions x-pack/metricbeat/include/list.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions x-pack/metricbeat/metricbeat.reference.yml
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,12 @@ metricbeat.modules:
- usage
- vpn

#----------------------------- AWS Fargate Module -----------------------------
- module: awsfargate
period: 10s
metricsets:
- task_stats

#-------------------------------- Azure Module --------------------------------
- module: azure
metricsets:
Expand Down
4 changes: 4 additions & 0 deletions x-pack/metricbeat/module/awsfargate/_meta/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
- module: awsfargate
period: 10s
metricsets:
- task_stats
7 changes: 7 additions & 0 deletions x-pack/metricbeat/module/awsfargate/_meta/docs.asciidoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Amazon ECS on Fargate provides a method to retrieve various metadata, network
metrics, and Docker stats about tasks and containers. This is referred to as the
https://docs.aws.amazon.com/AmazonECS/latest/userguide/task-metadata-endpoint-v4-fargate.html[task metadata endpoint]
and this endpoint is available per container.

The awsfargate module is a Metricbeat module which collects AWS fargate metrics
from task metadata endpoint.
6 changes: 6 additions & 0 deletions x-pack/metricbeat/module/awsfargate/_meta/fields.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
- key: awsfargate
title: "AWS Fargate"
description: >
`awsfargate` module collects AWS fargate metrics from task metadata endpoint.
release: experimental
fields:
54 changes: 54 additions & 0 deletions x-pack/metricbeat/module/awsfargate/awsfargate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
// or more contributor license agreements. Licensed under the Elastic License;
// you may not use this file except in compliance with the Elastic License.

package awsfargate

import (
"time"

"github.com/elastic/beats/v7/metricbeat/mb"
)

// Config defines all required and optional parameters for awsfargate metricsets
type Config struct {
Period time.Duration `config:"period" validate:"nonzero,required"`
}

// MetricSet is the base metricset for all aws metricsets
type MetricSet struct {
mb.BaseMetricSet
Period time.Duration
}

// ModuleName is the name of this module.
const ModuleName = "awsfargate"

func init() {
if err := mb.Registry.AddModule(ModuleName, newModule); err != nil {
panic(err)
}
}

func newModule(base mb.BaseModule) (mb.Module, error) {
var config Config
if err := base.UnpackConfig(&config); err != nil {
return nil, err
}
return &base, nil
}

// NewMetricSet creates a base metricset for awsfargate metricsets
func NewMetricSet(base mb.BaseMetricSet) (*MetricSet, error) {
var config Config
err := base.Module().UnpackConfig(&config)
if err != nil {
return nil, err
}

metricSet := MetricSet{
BaseMetricSet: base,
Period: config.Period,
}
return &metricSet, nil
}
Loading