Skip to content

Commit 8e0df6f

Browse files
authored
Initial commit (#2)
This change introduces a Prometheus exporter to publish ECS metrics in the Prometheus exposition format. The ecs_exporter reads the ECS metadata server to read ECS task and container stats. This is why the exporter needs to run as a sidecar container in an ECS task, or it should be included as a binary in a container deployed to be able to fetch from the metadata server. The exporter publishes metrics from the container runtime related to CPU usage, networking and more. Users still need to publish their custom application metrics from their own containers if they have any. Currently, these metrics are available from CloudWatch and can be ingested into Prometheus by using the cloudwatch_exporter, but there are various users who want to be able to directly export them to Prometheus to avoid delay in data collection. In the future, the exporter will report more CPU, memory, and I/O metrics. Fixes prometheus-community/community#36. Signed-off-by: JBD <[email protected]>
1 parent a4c2c60 commit 8e0df6f

File tree

10 files changed

+1154
-0
lines changed

10 files changed

+1154
-0
lines changed

Dockerfile

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
ARG ARCH="amd64"
2+
ARG OS="linux"
3+
FROM quay.io/prometheus/busybox-${OS}-${ARCH}:latest
4+
LABEL maintainer="The Prometheus Authors <[email protected]>"
5+
6+
ARG ARCH="amd64"
7+
ARG OS="linux"
8+
COPY .build/${OS}-${ARCH}/ecs_exporter /bin/ecs_exporter
9+
10+
EXPOSE 9779
11+
USER nobody
12+
ENTRYPOINT [ "/bin/ecs_exporter" ]

Makefile

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Ensure that 'all' is the default target otherwise it will be the first target from Makefile.common.
2+
all::
3+
4+
# Needs to be defined before including Makefile.common to auto-generate targets
5+
DOCKER_ARCHS ?= amd64 arm64
6+
DOCKER_REPO ?= prometheuscommunity
7+
8+
include Makefile.common
9+
10+
DOCKER_IMAGE_NAME ?= ecs-exporter

Makefile.common

Lines changed: 317 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,317 @@
1+
# Copyright 2018 The Prometheus Authors
2+
# Licensed under the Apache License, Version 2.0 (the "License");
3+
# you may not use this file except in compliance with the License.
4+
# You may obtain a copy of the License at
5+
#
6+
# http://www.apache.org/licenses/LICENSE-2.0
7+
#
8+
# Unless required by applicable law or agreed to in writing, software
9+
# distributed under the License is distributed on an "AS IS" BASIS,
10+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
# See the License for the specific language governing permissions and
12+
# limitations under the License.
13+
14+
15+
# A common Makefile that includes rules to be reused in different prometheus projects.
16+
# !!! Open PRs only against the prometheus/prometheus/Makefile.common repository!
17+
18+
# Example usage :
19+
# Create the main Makefile in the root project directory.
20+
# include Makefile.common
21+
# customTarget:
22+
# @echo ">> Running customTarget"
23+
#
24+
25+
# Ensure GOBIN is not set during build so that promu is installed to the correct path
26+
unexport GOBIN
27+
28+
GO ?= go
29+
GOFMT ?= $(GO)fmt
30+
FIRST_GOPATH := $(firstword $(subst :, ,$(shell $(GO) env GOPATH)))
31+
GOOPTS ?=
32+
GOHOSTOS ?= $(shell $(GO) env GOHOSTOS)
33+
GOHOSTARCH ?= $(shell $(GO) env GOHOSTARCH)
34+
35+
GO_VERSION ?= $(shell $(GO) version)
36+
GO_VERSION_NUMBER ?= $(word 3, $(GO_VERSION))
37+
PRE_GO_111 ?= $(shell echo $(GO_VERSION_NUMBER) | grep -E 'go1\.(10|[0-9])\.')
38+
39+
GOVENDOR :=
40+
GO111MODULE :=
41+
ifeq (, $(PRE_GO_111))
42+
ifneq (,$(wildcard go.mod))
43+
# Enforce Go modules support just in case the directory is inside GOPATH (and for Travis CI).
44+
GO111MODULE := on
45+
46+
ifneq (,$(wildcard vendor))
47+
# Always use the local vendor/ directory to satisfy the dependencies.
48+
GOOPTS := $(GOOPTS) -mod=vendor
49+
endif
50+
endif
51+
else
52+
ifneq (,$(wildcard go.mod))
53+
ifneq (,$(wildcard vendor))
54+
$(warning This repository requires Go >= 1.11 because of Go modules)
55+
$(warning Some recipes may not work as expected as the current Go runtime is '$(GO_VERSION_NUMBER)')
56+
endif
57+
else
58+
# This repository isn't using Go modules (yet).
59+
GOVENDOR := $(FIRST_GOPATH)/bin/govendor
60+
endif
61+
endif
62+
PROMU := $(FIRST_GOPATH)/bin/promu
63+
pkgs = ./...
64+
65+
ifeq (arm, $(GOHOSTARCH))
66+
GOHOSTARM ?= $(shell GOARM= $(GO) env GOARM)
67+
GO_BUILD_PLATFORM ?= $(GOHOSTOS)-$(GOHOSTARCH)v$(GOHOSTARM)
68+
else
69+
GO_BUILD_PLATFORM ?= $(GOHOSTOS)-$(GOHOSTARCH)
70+
endif
71+
72+
GOTEST := $(GO) test
73+
GOTEST_DIR :=
74+
ifneq ($(CIRCLE_JOB),)
75+
ifneq ($(shell which gotestsum),)
76+
GOTEST_DIR := test-results
77+
GOTEST := gotestsum --junitfile $(GOTEST_DIR)/unit-tests.xml --
78+
endif
79+
endif
80+
81+
PROMU_VERSION ?= 0.12.0
82+
PROMU_URL := https://github.com/prometheus/promu/releases/download/v$(PROMU_VERSION)/promu-$(PROMU_VERSION).$(GO_BUILD_PLATFORM).tar.gz
83+
84+
GOLANGCI_LINT :=
85+
GOLANGCI_LINT_OPTS ?=
86+
GOLANGCI_LINT_VERSION ?= v1.42.0
87+
# golangci-lint only supports linux, darwin and windows platforms on i386/amd64.
88+
# windows isn't included here because of the path separator being different.
89+
ifeq ($(GOHOSTOS),$(filter $(GOHOSTOS),linux darwin))
90+
ifeq ($(GOHOSTARCH),$(filter $(GOHOSTARCH),amd64 i386))
91+
# If we're in CI and there is an Actions file, that means the linter
92+
# is being run in Actions, so we don't need to run it here.
93+
ifeq (,$(CIRCLE_JOB))
94+
GOLANGCI_LINT := $(FIRST_GOPATH)/bin/golangci-lint
95+
else ifeq (,$(wildcard .github/workflows/golangci-lint.yml))
96+
GOLANGCI_LINT := $(FIRST_GOPATH)/bin/golangci-lint
97+
endif
98+
endif
99+
endif
100+
101+
PREFIX ?= $(shell pwd)
102+
BIN_DIR ?= $(shell pwd)
103+
DOCKER_IMAGE_TAG ?= $(subst /,-,$(shell git rev-parse --abbrev-ref HEAD))
104+
DOCKERFILE_PATH ?= ./Dockerfile
105+
DOCKERBUILD_CONTEXT ?= ./
106+
DOCKER_REPO ?= prom
107+
108+
DOCKER_ARCHS ?= amd64
109+
110+
BUILD_DOCKER_ARCHS = $(addprefix common-docker-,$(DOCKER_ARCHS))
111+
PUBLISH_DOCKER_ARCHS = $(addprefix common-docker-publish-,$(DOCKER_ARCHS))
112+
TAG_DOCKER_ARCHS = $(addprefix common-docker-tag-latest-,$(DOCKER_ARCHS))
113+
114+
ifeq ($(GOHOSTARCH),amd64)
115+
ifeq ($(GOHOSTOS),$(filter $(GOHOSTOS),linux freebsd darwin windows))
116+
# Only supported on amd64
117+
test-flags := -race
118+
endif
119+
endif
120+
121+
# This rule is used to forward a target like "build" to "common-build". This
122+
# allows a new "build" target to be defined in a Makefile which includes this
123+
# one and override "common-build" without override warnings.
124+
%: common-% ;
125+
126+
.PHONY: common-all
127+
common-all: precheck style check_license lint yamllint unused build test
128+
129+
.PHONY: common-style
130+
common-style:
131+
@echo ">> checking code style"
132+
@fmtRes=$$($(GOFMT) -d $$(find . -path ./vendor -prune -o -name '*.go' -print)); \
133+
if [ -n "$${fmtRes}" ]; then \
134+
echo "gofmt checking failed!"; echo "$${fmtRes}"; echo; \
135+
echo "Please ensure you are using $$($(GO) version) for formatting code."; \
136+
exit 1; \
137+
fi
138+
139+
.PHONY: common-check_license
140+
common-check_license:
141+
@echo ">> checking license header"
142+
@licRes=$$(for file in $$(find . -type f -iname '*.go' ! -path './vendor/*') ; do \
143+
awk 'NR<=3' $$file | grep -Eq "(Copyright|generated|GENERATED)" || echo $$file; \
144+
done); \
145+
if [ -n "$${licRes}" ]; then \
146+
echo "license header checking failed:"; echo "$${licRes}"; \
147+
exit 1; \
148+
fi
149+
150+
.PHONY: common-deps
151+
common-deps:
152+
@echo ">> getting dependencies"
153+
ifdef GO111MODULE
154+
GO111MODULE=$(GO111MODULE) $(GO) mod download
155+
else
156+
$(GO) get $(GOOPTS) -t ./...
157+
endif
158+
159+
.PHONY: update-go-deps
160+
update-go-deps:
161+
@echo ">> updating Go dependencies"
162+
@for m in $$($(GO) list -mod=readonly -m -f '{{ if and (not .Indirect) (not .Main)}}{{.Path}}{{end}}' all); do \
163+
$(GO) get $$m; \
164+
done
165+
GO111MODULE=$(GO111MODULE) $(GO) mod tidy
166+
ifneq (,$(wildcard vendor))
167+
GO111MODULE=$(GO111MODULE) $(GO) mod vendor
168+
endif
169+
170+
.PHONY: common-test-short
171+
common-test-short: $(GOTEST_DIR)
172+
@echo ">> running short tests"
173+
GO111MODULE=$(GO111MODULE) $(GOTEST) -short $(GOOPTS) $(pkgs)
174+
175+
.PHONY: common-test
176+
common-test: $(GOTEST_DIR)
177+
@echo ">> running all tests"
178+
GO111MODULE=$(GO111MODULE) $(GOTEST) $(test-flags) $(GOOPTS) $(pkgs)
179+
180+
$(GOTEST_DIR):
181+
@mkdir -p $@
182+
183+
.PHONY: common-format
184+
common-format:
185+
@echo ">> formatting code"
186+
GO111MODULE=$(GO111MODULE) $(GO) fmt $(pkgs)
187+
188+
.PHONY: common-vet
189+
common-vet:
190+
@echo ">> vetting code"
191+
GO111MODULE=$(GO111MODULE) $(GO) vet $(GOOPTS) $(pkgs)
192+
193+
.PHONY: common-lint
194+
common-lint: $(GOLANGCI_LINT)
195+
ifdef GOLANGCI_LINT
196+
@echo ">> running golangci-lint"
197+
ifdef GO111MODULE
198+
# 'go list' needs to be executed before staticcheck to prepopulate the modules cache.
199+
# Otherwise staticcheck might fail randomly for some reason not yet explained.
200+
GO111MODULE=$(GO111MODULE) $(GO) list -e -compiled -test=true -export=false -deps=true -find=false -tags= -- ./... > /dev/null
201+
GO111MODULE=$(GO111MODULE) $(GOLANGCI_LINT) run $(GOLANGCI_LINT_OPTS) $(pkgs)
202+
else
203+
$(GOLANGCI_LINT) run $(pkgs)
204+
endif
205+
endif
206+
207+
.PHONY: common-yamllint
208+
common-yamllint:
209+
@echo ">> running yamllint on all YAML files in the repository"
210+
ifeq (, $(shell which yamllint))
211+
@echo "yamllint not installed so skipping"
212+
else
213+
yamllint .
214+
endif
215+
216+
# For backward-compatibility.
217+
.PHONY: common-staticcheck
218+
common-staticcheck: lint
219+
220+
.PHONY: common-unused
221+
common-unused: $(GOVENDOR)
222+
ifdef GOVENDOR
223+
@echo ">> running check for unused packages"
224+
@$(GOVENDOR) list +unused | grep . && exit 1 || echo 'No unused packages'
225+
else
226+
ifdef GO111MODULE
227+
@echo ">> running check for unused/missing packages in go.mod"
228+
GO111MODULE=$(GO111MODULE) $(GO) mod tidy
229+
ifeq (,$(wildcard vendor))
230+
@git diff --exit-code -- go.sum go.mod
231+
else
232+
@echo ">> running check for unused packages in vendor/"
233+
GO111MODULE=$(GO111MODULE) $(GO) mod vendor
234+
@git diff --exit-code -- go.sum go.mod vendor/
235+
endif
236+
endif
237+
endif
238+
239+
.PHONY: common-build
240+
common-build: promu
241+
@echo ">> building binaries"
242+
GO111MODULE=$(GO111MODULE) $(PROMU) build --prefix $(PREFIX) $(PROMU_BINARIES)
243+
244+
.PHONY: common-tarball
245+
common-tarball: promu
246+
@echo ">> building release tarball"
247+
$(PROMU) tarball --prefix $(PREFIX) $(BIN_DIR)
248+
249+
.PHONY: common-docker $(BUILD_DOCKER_ARCHS)
250+
common-docker: $(BUILD_DOCKER_ARCHS)
251+
$(BUILD_DOCKER_ARCHS): common-docker-%:
252+
docker build -t "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(DOCKER_IMAGE_TAG)" \
253+
-f $(DOCKERFILE_PATH) \
254+
--build-arg ARCH="$*" \
255+
--build-arg OS="linux" \
256+
$(DOCKERBUILD_CONTEXT)
257+
258+
.PHONY: common-docker-publish $(PUBLISH_DOCKER_ARCHS)
259+
common-docker-publish: $(PUBLISH_DOCKER_ARCHS)
260+
$(PUBLISH_DOCKER_ARCHS): common-docker-publish-%:
261+
docker push "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(DOCKER_IMAGE_TAG)"
262+
263+
DOCKER_MAJOR_VERSION_TAG = $(firstword $(subst ., ,$(shell cat VERSION)))
264+
.PHONY: common-docker-tag-latest $(TAG_DOCKER_ARCHS)
265+
common-docker-tag-latest: $(TAG_DOCKER_ARCHS)
266+
$(TAG_DOCKER_ARCHS): common-docker-tag-latest-%:
267+
docker tag "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(DOCKER_IMAGE_TAG)" "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:latest"
268+
docker tag "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(DOCKER_IMAGE_TAG)" "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:v$(DOCKER_MAJOR_VERSION_TAG)"
269+
270+
.PHONY: common-docker-manifest
271+
common-docker-manifest:
272+
DOCKER_CLI_EXPERIMENTAL=enabled docker manifest create -a "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME):$(DOCKER_IMAGE_TAG)" $(foreach ARCH,$(DOCKER_ARCHS),$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$(ARCH):$(DOCKER_IMAGE_TAG))
273+
DOCKER_CLI_EXPERIMENTAL=enabled docker manifest push "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME):$(DOCKER_IMAGE_TAG)"
274+
275+
.PHONY: promu
276+
promu: $(PROMU)
277+
278+
$(PROMU):
279+
$(eval PROMU_TMP := $(shell mktemp -d))
280+
curl -s -L $(PROMU_URL) | tar -xvzf - -C $(PROMU_TMP)
281+
mkdir -p $(FIRST_GOPATH)/bin
282+
cp $(PROMU_TMP)/promu-$(PROMU_VERSION).$(GO_BUILD_PLATFORM)/promu $(FIRST_GOPATH)/bin/promu
283+
rm -r $(PROMU_TMP)
284+
285+
.PHONY: proto
286+
proto:
287+
@echo ">> generating code from proto files"
288+
@./scripts/genproto.sh
289+
290+
ifdef GOLANGCI_LINT
291+
$(GOLANGCI_LINT):
292+
mkdir -p $(FIRST_GOPATH)/bin
293+
curl -sfL https://raw.githubusercontent.com/golangci/golangci-lint/$(GOLANGCI_LINT_VERSION)/install.sh \
294+
| sed -e '/install -d/d' \
295+
| sh -s -- -b $(FIRST_GOPATH)/bin $(GOLANGCI_LINT_VERSION)
296+
endif
297+
298+
ifdef GOVENDOR
299+
.PHONY: $(GOVENDOR)
300+
$(GOVENDOR):
301+
GOOS= GOARCH= $(GO) get -u github.com/kardianos/govendor
302+
endif
303+
304+
.PHONY: precheck
305+
precheck::
306+
307+
define PRECHECK_COMMAND_template =
308+
precheck:: $(1)_precheck
309+
310+
PRECHECK_COMMAND_$(1) ?= $(1) $$(strip $$(PRECHECK_OPTIONS_$(1)))
311+
.PHONY: $(1)_precheck
312+
$(1)_precheck:
313+
@if ! $$(PRECHECK_COMMAND_$(1)) 1>/dev/null 2>&1; then \
314+
echo "Execution of '$$(PRECHECK_COMMAND_$(1))' command failed. Is $(1) installed?"; \
315+
exit 1; \
316+
fi
317+
endef

0 commit comments

Comments
 (0)