diff --git a/Dockerfile b/Dockerfile index 46d7bf0..71a0ae8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,20 +1,20 @@ -FROM golang:1.10 +FROM golang:1.13.3 -WORKDIR /go/src/github.com/ashiddo11/sqs-exporter/ - -RUN go get github.com/aws/aws-sdk-go +WORKDIR /go/src/github.com/nadeemjamali/sqs-prometheus-exporter/ COPY . . -RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o sqs-exporter . +RUN go get -d ./... + +RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o sqs-prometheus-exporter . FROM alpine -COPY --from=0 /go/src/github.com/ashiddo11/sqs-exporter/sqs-exporter / +COPY --from=0 /go/src/github.com/nadeemjamali/sqs-prometheus-exporter / RUN apk --update add ca-certificates && \ rm -rf /var/cache/apk/* EXPOSE 9434 -CMD ["/sqs-exporter"] +CMD ["/sqs-prometheus-exporter"] diff --git a/README.md b/README.md index 4d8f4ed..04f9fd1 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ -# Simple AWS SQS exporter +# AWS SQS Prometheus Exporter -A Prometheus SQS metrics exporter +A Prometheus metrics exporter for AWS SQS queues + +> **A few words of Thanks:** Most of the code in this repo is borrowed from [ashiddo11/sqs-exporter](https://github.com/ashiddo11/sqs-exporter) with bundle of thanks and love :pray: :heart:. I didn't submit this as a pull request to the original repository, since I have added Prometheus client. Whereas, some users of the original repository may not be using Prometheus at all. ## Metrics @@ -47,11 +49,19 @@ The app needs sqs list and read access to the sqs policies } ``` +## Environment Variables +| Variable | Default Value | Description | +|---------------|:---------|:-------------------------------------------------------------| +| PORT | 9434 | The port for metrics server | +| INTERVAL | 1 | The interval in minutes to get the status of SQS queues | +| ENDPOINT | metrics | The metrics endpoint | +| KEEP_RUNNING | true | The flag to terminate the service in case of monitoring error | + + ## Running -**You need to specify the region you to connect to** -Running on an ec2 machine using IAM roles: -`docker run -e AWS_REGION= -d -p 9434:9434 ashiddo11/sqs-exporter` +```docker run -e INTERVAL=5 -e KEEP_RUNNING=false -d -p 9434:9434 nadeemjamali/sqs-prometheus-exporter``` + +You can provide the AWS credentials as environment variables depending upon your security rules configured in AWS; -Or running it externally: -`docker run -d -p 9384:9384 -e AWS_ACCESS_KEY_ID= -e AWS_SECRET_ACCESS_KEY= -e AWS_REGION= ashiddo11/sqs-exporter` \ No newline at end of file +```docker run -d -p 9384:9384 -e AWS_ACCESS_KEY_ID= -e AWS_SECRET_ACCESS_KEY= -e AWS_REGION= nadeemjamali/sqs-prometheus-exporter``` \ No newline at end of file diff --git a/go.mod b/go.mod index 3f9686e..da848ed 100644 --- a/go.mod +++ b/go.mod @@ -1,10 +1,9 @@ -module github.com/nadeemjamali/sqs-exporter +module github.com/nadeemjamali/sqs-prometheus-exporter go 1.13 require ( - github.com/ashiddo11/sqs-exporter v0.0.1 - github.com/aws/aws-sdk-go v1.30.5 + github.com/aws/aws-sdk-go v1.30.6 github.com/go-co-op/gocron v0.1.0 github.com/prometheus/client_golang v1.5.1 ) diff --git a/go.sum b/go.sum index 27c2cea..012c786 100644 --- a/go.sum +++ b/go.sum @@ -2,10 +2,8 @@ github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuy github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/ashiddo11/sqs-exporter v0.0.1 h1:D8w6ZtnLNlG19aa35hbMDa7XRVwvRr6oVHlmPCbQSO8= -github.com/ashiddo11/sqs-exporter v0.0.1/go.mod h1:i24T5gi/rIPwWLN9ME0a+d5mH/hQzcR2G+gokt6Xpqc= -github.com/aws/aws-sdk-go v1.30.5 h1:i+sSesaMrSxiUt3NJddOApe2mXK+VNBgfcmRTvNFrXM= -github.com/aws/aws-sdk-go v1.30.5/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0= +github.com/aws/aws-sdk-go v1.30.6 h1:GuWgFWWR9CF8mO9SM6N9oZt0vM0yzgPCMDDZOEQb8l4= +github.com/aws/aws-sdk-go v1.30.6/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -80,6 +78,7 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= @@ -99,6 +98,7 @@ golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82 h1:ywK/j/KkyTHcdyYSZNXGjMwgmDSfjglYZ3vStQ/gSCU= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/main.go b/main.go index e7e2842..5c525aa 100644 --- a/main.go +++ b/main.go @@ -7,8 +7,11 @@ import ( "net/http" "os" "strconv" + "strings" "time" + collector "github.com/nadeemjamali/sqs-prometheus-exporter/pkg/collector" + "github.com/go-co-op/gocron" "github.com/prometheus/client_golang/prometheus/promhttp" ) @@ -17,6 +20,7 @@ var ( port = getEnv("PORT", "9434") intervalStr = getEnv("INTERVAL", "1") endpoint = getEnv("ENDPOINT", "metrics") + keepRunningOnErrorStr = getEnv("KEEP_RUNNING", "true") ) func main() { @@ -45,8 +49,23 @@ func main() { scheduler.Start() fmt.Println(fmt.Sprintf("metrics server listening at port %v with monitoring interval of %v minute(s).", httpServer.Addr, interval)) - err = <- errChanel - fmt.Println(err) + + keepRunningOnError, _ := strconv.ParseBool(keepRunningOnErrorStr) + if keepRunningOnError { + for { + err = <- errChanel + fmt.Println(err) + + index := strings.Index(err.Error(), "[MONITORING ERROR]") + if index == -1 { + break + } + } + } else { + err = <- errChanel + fmt.Println(err) + } + fmt.Println("Terminating the server and monitoring") httpServer.Shutdown(ctx) scheduler.Clear() diff --git a/pkg/collector.go b/pkg/collector/collector.go similarity index 83% rename from pkg/collector.go rename to pkg/collector/collector.go index 67e74ae..08d3621 100644 --- a/pkg/collector.go +++ b/pkg/collector/collector.go @@ -27,16 +27,16 @@ var ( ) func init() { - prometheus.MustRegister(visibleMessageCounter) - prometheus.MustRegister(delayedMessageCounter) - prometheus.MustRegister(invisibleMessageCounter) + prometheus.MustRegister(visibleMessageGauge) + prometheus.MustRegister(delayedMessageGauge) + prometheus.MustRegister(invisibleMessageGauge) } // MonitorSQS Retrieves the attributes of all allowed queues from SQS and appends the metrics func MonitorSQS() error { - queues,listQueueTags, err := getQueues() + queues, _ , err := getQueues() if err != nil { - return err + return fmt.Errorf("[MONITORING ERROR]: Error occurred while retrieve queues info from SQS: %v", err) } for queue, attr := range queues { @@ -44,8 +44,19 @@ func MonitorSQS() error { msgDelayed, delayError := strconv.ParseFloat(*attr.Attributes["ApproximateNumberOfMessagesDelayed"], 64) msgNotVisible, invisibleError := strconv.ParseFloat(*attr.Attributes["ApproximateNumberOfMessagesNotVisible"], 64) + if msgError != nil { + return fmt.Errorf("Error in converting ApproximateNumberOfMessages: %v", msgError) + } visibleMessageGauge.WithLabelValues(queue).Add(msgAvailable) + + if delayError != nil { + return fmt.Errorf("Error in converting ApproximateNumberOfMessagesDelayed: %v", delayError) + } delayedMessageGauge.WithLabelValues(queue).Add(msgDelayed) + + if invisibleError != nil { + return fmt.Errorf("Error in converting ApproximateNumberOfMessagesNotVisible: %v", invisibleError) + } invisibleMessageGauge.WithLabelValues(queue).Add(msgNotVisible) } return nil @@ -64,14 +75,15 @@ func getQueues() (queues map[string]*sqs.GetQueueAttributesOutput, tags map[stri if err != nil { return nil, nil, err } - - queues = make(map[string]*sqs.GetQueueAttributesOutput) - tags = make(map[string]*sqs.ListQueueTagsOutput) - + fmt.Println(result) if result.QueueUrls == nil { err = fmt.Errorf("SQS did not return any QueueUrls") return nil, nil, err } + + queues = make(map[string]*sqs.GetQueueAttributesOutput) + tags = make(map[string]*sqs.ListQueueTagsOutput) + for _, urls := range result.QueueUrls { params := &sqs.GetQueueAttributesInput{ QueueUrl: aws.String(*urls),