Skip to content

Commit 6e2d85d

Browse files
committed
improved
1 parent 99bb7e5 commit 6e2d85d

File tree

14 files changed

+198
-78
lines changed

14 files changed

+198
-78
lines changed

.github/workflows/master.yml

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ on:
1414
- '**.md'
1515

1616
env:
17-
DOCKER_HUB_REPO: docker.io/slashdevops
17+
DOCKER_HUB_REPO: "docker.io/slashdevops"
18+
DOCKER_BUILD_ARCHS: "amd64 armv7 arm64"
1819

1920
jobs:
2021

@@ -113,10 +114,10 @@ jobs:
113114
run: ls -la .build
114115

115116
- name: Build Docker Images
116-
run: make docker DOCKER_REPO=docker.io/slashdevops
117+
run: make docker DOCKER_REPO=$DOCKER_HUB_REPO DOCKER_ARCHS=$DOCKER_BUILD_ARCHS
117118

118119
- name: Docker Tag Images Latest
119-
run: make docker-tag-latest DOCKER_REPO=docker.io/slashdevops
120+
run: make docker-tag-latest DOCKER_REPO=$DOCKER_HUB_REPO DOCKER_ARCHS=$DOCKER_BUILD_ARCHS
120121

121122
- name: Show Local Docker Images
122123
run: docker images
@@ -125,7 +126,7 @@ jobs:
125126
run: echo ${{ secrets.DOCKER_HUB_PASSWORD }} | docker login -u ${{ secrets.DOCKER_HUB_USER }} --password-stdin
126127

127128
- name: Publish Images in Docker Hub
128-
run: make docker-publish DOCKER_REPO=$DOCKER_HUB_REPO
129+
run: make docker-publish DOCKER_REPO=$DOCKER_HUB_REPO DOCKER_ARCHS=$DOCKER_BUILD_ARCHS
129130

130131
- name: Publish Manifest in Docker Hub
131-
run: make docker-manifest DOCKER_REPO=$DOCKER_HUB_REPO
132+
run: make docker-manifest DOCKER_REPO=$DOCKER_HUB_REPO DOCKER_ARCHS=$DOCKER_BUILD_ARCHS

.github/workflows/release.yml

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ on:
66
- v[012].[0-9]+.[0-9]+ # https://help.github.com/es/actions/reference/workflow-syntax-for-github-actions#filter-pattern-cheat-sheet
77

88
env:
9-
DOCKER_HUB_REPO: docker.io/slashdevops
9+
DOCKER_HUB_REPO: "docker.io/slashdevops"
10+
DOCKER_BUILD_ARCHS: "amd64 armv7 arm64"
1011

1112
jobs:
1213

@@ -109,10 +110,10 @@ jobs:
109110
run: echo $RELEASE_VERSION
110111

111112
- name: Build Docker Images
112-
run: make docker DOCKER_IMAGE_TAG=$RELEASE_VERSION DOCKER_REPO=docker.io/slashdevops
113+
run: make docker DOCKER_IMAGE_TAG=$RELEASE_VERSION DOCKER_REPO=$DOCKER_HUB_REPO DOCKER_ARCHS=$DOCKER_BUILD_ARCHS
113114

114115
- name: Docker Tag Images Latest
115-
run: make docker-tag-latest DOCKER_IMAGE_TAG=$RELEASE_VERSION DOCKER_REPO=docker.io/slashdevops
116+
run: make docker-tag-latest DOCKER_IMAGE_TAG=$RELEASE_VERSION DOCKER_REPO=$DOCKER_HUB_REPO DOCKER_ARCHS=$DOCKER_BUILD_ARCHS
116117

117118
- name: Show Local Docker Images
118119
run: docker images
@@ -121,10 +122,10 @@ jobs:
121122
run: echo ${{ secrets.DOCKER_HUB_PASSWORD }} | docker login -u ${{ secrets.DOCKER_HUB_USER }} --password-stdin
122123

123124
- name: Publish Images in Docker Hub
124-
run: make docker-publish DOCKER_IMAGE_TAG=$RELEASE_VERSION DOCKER_REPO=$DOCKER_HUB_REPO
125+
run: make docker-publish DOCKER_IMAGE_TAG=$RELEASE_VERSION DOCKER_REPO=$DOCKER_HUB_REPO DOCKER_ARCHS=$DOCKER_BUILD_ARCHS
125126

126127
- name: Publish Manifest in Docker Hub
127-
run: make docker-manifest DOCKER_IMAGE_TAG=$RELEASE_VERSION DOCKER_REPO=$DOCKER_HUB_REPO
128+
run: make docker-manifest DOCKER_IMAGE_TAG=$RELEASE_VERSION DOCKER_REPO=$DOCKER_HUB_REPO DOCKER_ARCHS=$DOCKER_BUILD_ARCHS
128129

129130
create_release:
130131
name: Create Release

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
## 0.0.1 / 2020-06-14
1+
## 0.0.1 / 2020-06-20
22

33
* [ENHANCEMENT] First Alpha Version

Dockerfile

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,14 @@ ARG ARCH="amd64"
1515
ARG OS="linux"
1616
COPY .build/${OS}-${ARCH}/aws_cloudwatch_exporter /bin/aws_cloudwatch_exporter
1717

18-
EXPOSE 9690
19-
USER nobody
18+
ARG PORT="9690"
19+
EXPOSE ${PORT}
2020

21-
HEALTHCHECK CMD wget --spider -S "http://localhost:9690/health" -T 60 2>&1 || exit 1
21+
USER nobody
2222

23-
VOLUME "/etc/aws_cloudwatch_exporter"
23+
HEALTHCHECK CMD wget --spider -S "http://localhost:${PORT}/health" -T 60 2>&1 || exit 1
2424

25-
ENTRYPOINT [ "/bin/aws_cloudwatch_exporter" ]
25+
VOLUME ["/metrics","/home/nobody"]
26+
27+
ENTRYPOINT [ "/bin/aws_cloudwatch_exporter" ]
28+
# CMD [ "/bin/aws_cloudwatch_exporter" ]

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
# limitations under the License.
1313

1414
# Needs to be defined before including Makefile.common to auto-generate targets
15-
DOCKER_ARCHS ?= amd64 armv7 arm64
15+
DOCKER_ARCHS ?= amd64
1616

1717
include Makefile.common
1818

README.md

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,65 @@ The configuration could be set using 3 ways:
2020
The precedence is in the same order of the list, so, if you define values into `server.yaml` and then
2121
the same configuration key is defined as a `Env Var` this last will replace the file value.
2222

23+
### Running
24+
25+
#### Docker
26+
27+
```bash
28+
make && \
29+
make promu && \
30+
promu build --prefix .build/darwin-amd64 && \
31+
make docker DOCKER_REPO=docker.io/slashdevops
32+
33+
docker run --rm \
34+
-v ~/tmp/queries/m1.yaml:/metrics/m1.yaml \
35+
-v ~/.aws:/credentials \
36+
-v ~/.aws:/credentials \
37+
-e "AWS_SDK_LOAD_CONFIG=1" \
38+
-e "AWS_CONFIG_FILE=/credentials/.aws/config" \
39+
-e "AWS_SHARED_CREDENTIALS_FILE=/credentials/.aws/credentials" \
40+
-e "AWS_PROFILE=slashdevops" \
41+
slashdevops/aws-cloudwatch-exporter-linux-amd64:develop metrics get --metricsFiles /metrics/m1.yaml \
42+
--debug
43+
44+
docker run --rm \
45+
-v ~/tmp/queries/m1.yaml:/metrics/m1.yaml \
46+
-v ~/.aws/credentials:/home/.aws/credentials:ro \
47+
-v ~/.aws/config:/home/.aws/config:ro \
48+
-e "AWS_PROFILE=slashdevops" \
49+
slashdevops/aws-cloudwatch-exporter-linux-amd64:develop metrics get --metricsFiles /metrics/m1.yaml \
50+
--debug
51+
52+
docker run --rm \
53+
-v ~/tmp/queries/m1.yaml:/metrics/m1.yaml \
54+
-e "AWS_REGION=eu-west-1" \
55+
slashdevops/aws-cloudwatch-exporter-linux-amd64:develop metrics get --metricsFiles /metrics/m1.yaml \
56+
--debug
57+
58+
docker run --rm \
59+
-v ~/tmp/queries/m1.yaml:/metrics/m1.yaml \
60+
-v $HOME/.aws/credentials:/home/nobody/.aws/credentials -u nobody \
61+
-v $HOME/.aws/config:/home/nobody/.aws/config -u nobody \
62+
slashdevops/aws-cloudwatch-exporter-linux-amd64:develop ls -la /home/nobody/
63+
```
64+
65+
#### Binary
66+
67+
```bash
68+
make
69+
70+
AWS_SDK_LOAD_CONFIG="true" \
71+
AWS_PROFILE="slashdevops" \
72+
./aws_cloudwatch_exporter metrics get --metricsFiles ~/tmp/queries/m1.yaml \
73+
--debug
74+
```
75+
76+
```bash
77+
./aws_cloudwatch_exporter metrics get --metricsFiles ~/tmp/queries/m1.yaml \
78+
--profile slashdevops \
79+
--debug
80+
```
81+
2382
### Configuration Files
2483

2584
* [server.yaml](docs/server.md)

cmd/metrics.go

Lines changed: 74 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ import (
2020
"fmt"
2121
"io/ioutil"
2222
"net/http"
23+
"net/http/pprof"
24+
"os"
2325
"time"
2426

2527
"github.com/aws/aws-sdk-go/service/cloudwatch"
@@ -37,32 +39,38 @@ import (
3739
var (
3840
metricsCmd = &cobra.Command{
3941
Use: "metrics [commands]",
40-
Short: "Useful to debug your metrics",
41-
Long: `metrics commands`,
42+
Short: "Useful to debug your metrics defined into the queries files.",
43+
Long: `The set of commands defined here are usefully to check and test the metrics
44+
defined into your metrics queries files.`,
4245
}
4346

4447
metricsGetCmd = &cobra.Command{
45-
Use: "get [options] [args]",
46-
Short: "get metrics",
47-
Long: `Get metrics from AWS CloudWatch using the metrics queries defined in the [yaml|json] files`,
48+
Use: "get",
49+
Short: "Execute a call to AWS CloudWatch API to get metrics defined into the metrics queries files.",
50+
Long: `Using this command you can execute a call to AWS CloudWatch API to get metrics
51+
defined into the metrics queries files.`,
4852
Run: func(cmd *cobra.Command, args []string) {
4953
getCmd(cmd, args)
5054
},
5155
}
5256

5357
metricsDisplayPromDescCmd = &cobra.Command{
54-
Use: "display [options] [args]",
55-
Short: "display promDesc",
56-
Long: `Display prometheus metrics definitions`,
58+
Use: "display",
59+
Short: "Display prometheus metrics description build from metrics queries files.",
60+
Long: `Using this command you can display prometheus metrics description build from metrics queries files
61+
into prometheus format, will be the exactly information you will see as a metric name, help string and dimensions.`,
5762
Run: func(cmd *cobra.Command, args []string) {
5863
displayPromDescCmd(cmd, args)
5964
},
6065
}
6166

6267
metricsCollectCmd = &cobra.Command{
63-
Use: "collect [options] [args]",
64-
Short: "collect metrics",
65-
Long: `Collect metrics from AWS CloudWatch using prometheus collector`,
68+
Use: "collect",
69+
Short: "Start a basic web server with the collector working and every request is sent to AWS CloudWatch API to collect metrics.",
70+
Long: `Using this command you can start a basic web server with the collector working and every request is sent
71+
to AWS CloudWatch API to collect metrics, this work as the command "server start", but you don't
72+
need to use it as a replacement of the last command, this will be used only to test the result
73+
before moving to production state.`,
6674
Run: func(cmd *cobra.Command, args []string) {
6775
collectCmd(cmd, args)
6876
},
@@ -76,7 +84,7 @@ func init() {
7684
metricsCmd.AddCommand(metricsCollectCmd)
7785

7886
// Behavior parameters
79-
metricsGetCmd.PersistentFlags().StringVar(&conf.Application.MetricStatPeriod, "metricStatPeriod", "5m", "The AWS Cloudwatch metrics query stats period")
87+
metricsGetCmd.PersistentFlags().StringVar(&conf.Application.MetricStatPeriod, "metricStatPeriod", "5m", "The AWS CloudWatch metrics query stats period")
8088
if err := viper.BindPFlag("application.metricStatPeriod", metricsGetCmd.PersistentFlags().Lookup("metricStatPeriod")); err != nil {
8189
log.Error(err)
8290
}
@@ -89,18 +97,17 @@ func init() {
8997
metricsGetCmd.Flags().StringP("outFormat", "", "yaml", "Output format for results, possible values: [yaml|json]")
9098
metricsGetCmd.Flags().StringP("outFile", "", "", "Output file where to store the results.")
9199

92-
metricsCollectCmd.Flags().StringP("address", "", "127.0.0.1", "Test server address, empty means all addresses")
93-
metricsCollectCmd.Flags().StringP("port", "", "8080", "Test server port")
100+
metricsCollectCmd.Flags().StringP("address", "", "127.0.0.1", "Server address, empty means all addresses")
101+
metricsCollectCmd.Flags().StringP("port", "", "8080", "Server port")
94102
}
95103

96104
func getCmd(cmd *cobra.Command, args []string) {
97105

98106
loadFromMetricsFiles(&conf)
99107
validateMetricsQueries(&conf)
100108

101-
if conf.Server.Debug {
102-
log.Debug(conf.ToJSON())
103-
}
109+
log.Debugf("Available configuration: %s", conf.ToJSON())
110+
log.Debugf("Available Env Vars: %s", os.Environ())
104111

105112
startTime, endTime, period := metrics.GetTimeStamps(time.Now(), conf.Application.MetricStatPeriod, conf.Application.MetricTimeWindow)
106113
log.Debugf("Start Time: %s", startTime.Format(time.RFC3339))
@@ -110,6 +117,8 @@ func getCmd(cmd *cobra.Command, args []string) {
110117
m := metrics.New(&conf)
111118
mdi := m.GetMetricDataInput(startTime, endTime, period, "")
112119

120+
log.Debugf("Metrics queries: %s", mdi.String())
121+
113122
sess := awshelper.NewSession(&conf.AWS)
114123
svc := cloudwatch.New(sess)
115124
mdo, err := svc.GetMetricData(mdi)
@@ -151,9 +160,8 @@ func displayPromDescCmd(cmd *cobra.Command, args []string) {
151160
loadFromMetricsFiles(&conf)
152161
validateMetricsQueries(&conf)
153162

154-
if conf.Server.Debug {
155-
log.Debug(conf.ToJSON())
156-
}
163+
log.Debugf("Available configuration: %s", conf.ToJSON())
164+
log.Debugf("Available Env Vars: %s", os.Environ())
157165

158166
m := metrics.New(&conf)
159167

@@ -167,9 +175,8 @@ func collectCmd(cmd *cobra.Command, args []string) {
167175
loadFromMetricsFiles(&conf)
168176
validateMetricsQueries(&conf)
169177

170-
if conf.Server.Debug {
171-
log.Debug(conf.ToJSON())
172-
}
178+
log.Debugf("Available configuration: %s", conf.ToJSON())
179+
log.Debugf("Available Env Vars: %s", os.Environ())
173180

174181
m := metrics.New(&conf)
175182
sess := awshelper.NewSession(&conf.AWS)
@@ -178,11 +185,53 @@ func collectCmd(cmd *cobra.Command, args []string) {
178185
c := collector.New(&conf, m, cwc)
179186

180187
prometheus.MustRegister(c)
181-
http.Handle("/metrics", promhttp.Handler())
188+
mux := http.NewServeMux()
189+
190+
// metrics path
191+
mux.Handle("/metrics", promhttp.Handler())
192+
193+
// Debug & Profiling
194+
mux.HandleFunc("/debug/pprof/", pprof.Index)
195+
mux.HandleFunc("/debug/pprof/heap", pprof.Index)
196+
mux.HandleFunc("/debug/pprof/mutex", pprof.Index)
197+
mux.HandleFunc("/debug/pprof/goroutine", pprof.Index)
198+
mux.HandleFunc("/debug/pprof/threadcreate", pprof.Index)
199+
mux.HandleFunc("/debug/pprof/block", pprof.Index)
200+
mux.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline)
201+
mux.HandleFunc("/debug/pprof/profile", pprof.Profile)
202+
mux.HandleFunc("/debug/pprof/symbol", pprof.Symbol)
203+
mux.HandleFunc("/debug/pprof/trace", pprof.Trace)
204+
205+
// default root path
206+
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
207+
_, err := w.Write([]byte(`<html>
208+
<head><title>` + appName + ` Exporter</title></head>
209+
<body>
210+
<h1>` + appName + ` Exporter</h1>
211+
<p><a href='/metrics'>Metrics</a></p>
212+
<h2>Debug and profile</h2>
213+
<p><a href='/debug/pprof/'>/debug/pprof</a></p>
214+
<p><a href='/debug/pprof/heap'>/debug/pprof/heap</a></p>
215+
<p><a href='/debug/pprof/mutex'>/debug/pprof/mutex</a></p>
216+
<p><a href='/debug/pprof/goroutine'>/debug/pprof/goroutine</a></p>
217+
<p><a href='/debug/pprof/threadcreate'>/debug/pprof/threadcreate</a></p>
218+
<p><a href='/debug/pprof/block'>/debug/pprof/block</a></p>
219+
<p><a href='/debug/pprof/cmdline'>/debug/pprof/cmdline</a></p>
220+
<p><a href='/debug/pprof/profile'>/debug/pprof/profile</a></p>
221+
<p><a href='/debug/pprof/symbol'>/debug/pprof/symbol</a></p>
222+
<p><a href='/debug/pprof/trace'>/debug/pprof/trace</a></p>
223+
</body>
224+
</html>`))
225+
if err != nil {
226+
log.Error(err)
227+
}
228+
})
182229

183230
a, _ := cmd.Flags().GetString("address")
184231
p, _ := cmd.Flags().GetString("port")
185232
soc := fmt.Sprintf("%s:%v", a, p)
233+
186234
log.Infof("Starting test server on %s", soc)
187-
log.Fatal(http.ListenAndServe(soc, nil))
235+
log.Warn("Don't use this server as your default server used for prometheus exporter, instead use 'server start' command.")
236+
log.Fatal(http.ListenAndServe(soc, mux))
188237
}

cmd/root.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ This exporter use GetMetricData API to get the metrics from AWS CloudWatch`
4141
appGitRepository = "https://github.com/slashdevops/aws_cloudwatch_exporter"
4242
appMetricsPath = "/metrics"
4343
appHealthPath = "/health"
44+
appIP = "127.0.0.1"
45+
appPort = 9690
4446
)
4547

4648
// rootCmd represents the base command when called without any subcommands
@@ -67,7 +69,7 @@ func init() {
6769
cobra.OnInitialize(initConfig)
6870

6971
// Debug
70-
rootCmd.PersistentFlags().BoolVar(&conf.Server.Debug, "debug", false, "If this is enabled, the log debug messages are visible in the log output")
72+
rootCmd.PersistentFlags().BoolVar(&conf.Server.Debug, "debug", false, "If enabled, the log debug messages are visible in the log output")
7173
if err := viper.BindPFlag("server.debug", rootCmd.PersistentFlags().Lookup("debug")); err != nil {
7274
log.Error(err)
7375
}
@@ -83,7 +85,7 @@ func init() {
8385
log.Error(err)
8486
}
8587

86-
rootCmd.PersistentFlags().StringSliceVar(&conf.Application.MetricsFiles, "metricsFiles", []string{"metrics.yaml"}, "Metrics files, example: --metricsFiles ~/tmp/queries/m1.yaml --metricsFiles ~/tmp/queries/m2.yml")
88+
rootCmd.PersistentFlags().StringSliceVar(&conf.Application.MetricsFiles, "metricsFiles", []string{"metrics.yaml"}, "Metrics queries files, the file or files with the metrics queries. example: --metricsFiles ~/tmp/queries/m1.yaml --metricsFiles ~/tmp/queries/m2.yml")
8789
if err := viper.BindPFlag("application.metricsFiles", rootCmd.PersistentFlags().Lookup("metricsFiles")); err != nil {
8890
log.Error(err)
8991
}
@@ -170,6 +172,8 @@ func loadFromConfigFiles(fileName string, c *config.All) {
170172
viper.AutomaticEnv()
171173
viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
172174

175+
log.Debugf("Available Env Vars: %s", os.Environ())
176+
173177
log.Debugf("Loading configuration from file: %s", fileName)
174178
if err := viper.ReadInConfig(); err != nil {
175179
log.Fatalf("Error reading config file, %s", err)
@@ -257,7 +261,7 @@ func validateMetricsQueries(c *config.All) {
257261
if len(c.MetricDataQueries) > 0 {
258262
log.Infof("Total metrics queries: %v", len(c.MetricDataQueries))
259263
} else {
260-
log.Fatal("Metrics Queries are empty, you need to defined at least one metric in metrics file")
264+
log.Fatal("Metrics Queries are empty, you need to define at least one metric in metrics file")
261265
}
262266
}
263267

0 commit comments

Comments
 (0)