Skip to content

Commit

Permalink
added prometeus exporter
Browse files Browse the repository at this point in the history
  • Loading branch information
jaytaph committed Mar 10, 2021
1 parent 93e405a commit fdeed92
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 36 deletions.
45 changes: 9 additions & 36 deletions cmd/lambda/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,11 @@ package main
import (
"encoding/json"
"math/rand"
"strconv"
"strings"
"time"

"github.com/aws/aws-lambda-go/events"
"github.com/aws/aws-lambda-go/lambda"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/dynamodb"
"github.com/bitmaelum/bitmaelum-suite/pkg/hash"
"github.com/bitmaelum/key-resolver-go/internal"
"github.com/bitmaelum/key-resolver-go/internal/apigateway"
Expand Down Expand Up @@ -61,20 +57,25 @@ var handlerMapping = map[string]HandlerFunc{
// HandleRequest checks the incoming route and calls the correct handler for it
func HandleRequest(req events.APIGatewayV2HTTPRequest) (*events.APIGatewayV2HTTPResponse, error) {
if req.RouteKey == "GET /" {
logMetric(req.RouteKey, 200)
internal.LogMetric(req.RouteKey, 200)
return getIndex(req), nil
}

if req.RouteKey == "GET /config.json" {
logMetric(req.RouteKey, 200)
internal.LogMetric(req.RouteKey, 200)
return getConfig(req), nil
}

if req.RouteKey == "GET /prometheus-export" {
internal.LogMetric(req.RouteKey, 200)
return getConfig(req), nil
}

h, err := hash.NewFromHash(req.PathParameters["hash"])
if err != nil {
resp := http.CreateError("Incorrect hash address", 400)

logMetric(req.RouteKey, 400)
internal.LogMetric(req.RouteKey, 400)
return apigateway.HTTPToResp(resp), nil
}

Expand All @@ -91,38 +92,10 @@ func HandleRequest(req events.APIGatewayV2HTTPRequest) (*events.APIGatewayV2HTTP
httpResp = http.CreateError("Forbidden", 403)
}

logMetric(req.RouteKey, httpResp.StatusCode)
internal.LogMetric(req.RouteKey, httpResp.StatusCode)
return apigateway.HTTPToResp(httpResp), nil
}

/**
* Increase metrics
*/
func logMetric(path string, statusCode int) {
input := &dynamodb.UpdateItemInput{
ExpressionAttributeNames: map[string]*string{
"#hits": aws.String("hits"),
},
ExpressionAttributeValues: map[string]*dynamodb.AttributeValue{
":inc": {N: aws.String("1")},
":zero": {N: aws.String("0")},
},
TableName: aws.String("prometheus"),
UpdateExpression: aws.String("SET #hits = if_not_exists(#hits, :zero) + :inc"),
Key: map[string]*dynamodb.AttributeValue{
"path_code": {S: aws.String(path + " " + strconv.Itoa(statusCode))},
},
}

sess := session.Must(session.NewSessionWithOptions(session.Options{
SharedConfigState: session.SharedConfigEnable,
}))
dyna := dynamodb.New(sess)

// Update logging
_, _ = dyna.UpdateItem(input)
}

func getIndex(_ events.APIGatewayV2HTTPRequest) *events.APIGatewayV2HTTPResponse {
headers := map[string]string{}
headers["Content-Type"] = "text/html"
Expand Down
79 changes: 79 additions & 0 deletions internal/prometheus.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package internal

import (
"fmt"
"strconv"
"strings"

"github.com/aws/aws-lambda-go/events"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/dynamodb"
)

// LogMetric will log the given metric to the DynamoDB
func LogMetric(path string, statusCode int) {
input := &dynamodb.UpdateItemInput{
ExpressionAttributeNames: map[string]*string{
"#hits": aws.String("hits"),
},
ExpressionAttributeValues: map[string]*dynamodb.AttributeValue{
":inc": {N: aws.String("1")},
":zero": {N: aws.String("0")},
},
TableName: aws.String("prometheus"),
UpdateExpression: aws.String("SET #hits = if_not_exists(#hits, :zero) + :inc"),
Key: map[string]*dynamodb.AttributeValue{
"path_code": {S: aws.String(path + " " + strconv.Itoa(statusCode))},
},
}

dyna := getDyna()

// Update logging
_, _ = dyna.UpdateItem(input)
}

// ExportMetric will return a JSON output with the exported JSON log
func ExportMetric() *events.APIGatewayV2HTTPResponse {
headers := map[string]string{}

body := ""

input := &dynamodb.ScanInput{
ExpressionAttributeNames: map[string]*string{
"#path_code": aws.String("path_code"),
"#hits": aws.String("hits"),
},
ProjectionExpression: aws.String("#path_code, #hits"),
TableName: aws.String("prometheus"),
}

dyna := getDyna()
result, err := dyna.Scan(input)
if err == nil {
for i := range result.Items {

s := result.Items[i]["path_code"].S
parts := strings.Split(*s, " ")

hits := result.Items[i]["hits"].N
body += fmt.Sprintf("keyresolver_request{method=\"%s\" path=\"%s\", code=%s} = %s\n", parts[0], parts[1], parts[2], *hits)
}
}

resp := &events.APIGatewayV2HTTPResponse{
StatusCode: 200,
Headers: headers,
Body: string(body),
}

return resp
}

func getDyna() *dynamodb.DynamoDB {
sess := session.Must(session.NewSessionWithOptions(session.Options{
SharedConfigState: session.SharedConfigEnable,
}))
return dynamodb.New(sess)
}

0 comments on commit fdeed92

Please sign in to comment.