Skip to content

Commit

Permalink
Monitoring client proxy (#5)
Browse files Browse the repository at this point in the history
* Adding the proxy client code base + dockerfile

* Add the Helm chart for proxy client

* Delete workflows

* Changes on global variables,
metric type,
error handling, and channels for graceful shutdown

* Change checkProxy function to accept context,
Changes on ticker function

* Mostly change on ticker loop

* Final changes for client proxy

* Changes on checkproxy func client,
Add log for successMetric.Inc()

* Fix doecker image tag issue on image workflow

* Delete workflows

---------

Co-authored-by: Mahsa <[email protected]>
  • Loading branch information
divergentluna and Mahsa authored Jan 23, 2024
1 parent c0b7e20 commit bbf0040
Show file tree
Hide file tree
Showing 9 changed files with 294 additions and 0 deletions.
19 changes: 19 additions & 0 deletions clients/proxy-client/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
FROM golang:alpine AS builder

WORKDIR /go/src/app

COPY . .

RUN go build -o app

FROM alpine:latest

WORKDIR /app

COPY --from=builder /go/src/app/app .

ENV PROXY_URL="The proxy URL goes here."

EXPOSE 8080

CMD ["./app"]
7 changes: 7 additions & 0 deletions clients/proxy-client/deploy/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
apiVersion: v2
name: snappcloud-proxy-client
description: A Helm chart for Kubernetes

type: application
version: 0.1.0
appVersion: "0.0.1"
46 changes: 46 additions & 0 deletions clients/proxy-client/deploy/templates/deployment.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "snappcloud-proxy-client.fullname" . }}
labels:
{{- include "snappcloud-proxy-client.labels" . | nindent 4 }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
{{- include "snappcloud-proxy-client.selectorLabels" . | nindent 6 }}
template:
metadata:
labels:
{{- include "snappcloud-proxy-client.selectorLabels" . | nindent 8 }}
annotations:
{{- .Values.podAnnotations | toYaml | nindent 8 }}
spec:
serviceAccountName: {{ include "snappcloud-proxy-client.serviceAccountName" . }}
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 8 }}
containers:
- name: {{ .Chart.Name }}
securityContext:
{{- toYaml .Values.securityContext | nindent 12 }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
ports:
- name: http
containerPort: 80
protocol: TCP
env:
- name: PROXY_URL
valueFrom:
secretKeyRef:
name: {{ .Values.configSecretName }}
key: PROXY_URL
{{ .Values.nodeSelector | toYaml | nindent 8 }}
tolerations:
{{- with .Values.tolerations }}
{{- toYaml . | nindent 8 }}
{{- end }}
affinity:
{{- with .Values.affinity }}
{{- toYaml . | nindent 8 }}
{{- end }}
9 changes: 9 additions & 0 deletions clients/proxy-client/deploy/templates/secret.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
apiVersion: v1
kind: Secret
metadata:
name: {{ .Values.configSecretName }}
labels:
{{- include "snappcloud-proxy-client.labels" . | nindent 4 }}
type: Opaque
stringData:
PROXY_URL: "The proxy address."
14 changes: 14 additions & 0 deletions clients/proxy-client/deploy/templates/service.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
apiVersion: v1
kind: Service
metadata:
name: {{ include "snappcloud-proxy-client.fullname" . }}
labels:
{{- include "snappcloud-proxy-client.labels" . | nindent 4 }}
spec:
type: {{ .Values.service.type }}
ports:
- port: {{ .Values.service.port }}
targetPort: http
protocol: TCP
selector:
{{- include "snappcloud-proxy-client.selectorLabels" . | nindent 4 }}
37 changes: 37 additions & 0 deletions clients/proxy-client/deploy/values.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
replicaCount: 1

image:
repository: ghcr.io/snapp-incubator/snappcloud-status-backend
pullPolicy: Always
tag: "0.0.1"

imagePullSecrets: []
nameOverride: ""
fullnameOverride: ""

serviceAccount:
create: false
automount: true
annotations: {}
name: ""

service:
type: ClusterIP
port: 8080

resources:
limits:
cpu: 100m
memory: 128Mi
requests:
cpu: 100m
memory: 128Mi

autoscaling:
enabled: false
minReplicas: 1
maxReplicas: 100
targetCPUUtilizationPercentage: 80
# targetMemoryUtilizationPercentage: 80

configSecretName: spcld-proxy-health-client
16 changes: 16 additions & 0 deletions clients/proxy-client/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
module github.com/snapp-incubator/snappcloud-status-backend/clients/proxy-client

go 1.21.0

require github.com/prometheus/client_golang v1.18.0

require (
github.com/beorn7/perks v1.0.1 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect
github.com/prometheus/client_model v0.5.0 // indirect
github.com/prometheus/common v0.45.0 // indirect
github.com/prometheus/procfs v0.12.0 // indirect
golang.org/x/sys v0.15.0 // indirect
google.golang.org/protobuf v1.31.0 // indirect
)
26 changes: 26 additions & 0 deletions clients/proxy-client/go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 h1:jWpvCLoY8Z/e3VKvlsiIGKtc+UG6U5vzxaoagmhXfyg=
github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k=
github.com/prometheus/client_golang v1.18.0 h1:HzFfmkOzH5Q8L8G+kSJKUx5dtG87sewO+FoDDqP5Tbk=
github.com/prometheus/client_golang v1.18.0/go.mod h1:T+GXkCk5wSJyOqMIzVgvvjFDlkOQntgjkJWKrN5txjA=
github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw=
github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI=
github.com/prometheus/common v0.45.0 h1:2BGz0eBc2hdMDLnO/8n0jeB3oPrt2D08CekT0lneoxM=
github.com/prometheus/common v0.45.0/go.mod h1:YJmSTw9BoKxJplESWWxlbyttQR4uaEcGyv9MZjVOJsY=
github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo=
github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo=
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
120 changes: 120 additions & 0 deletions clients/proxy-client/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
package main

import (
"context"
"log"
"net/http"
"net/url"
"os"
"os/signal"
"sync"
"syscall"
"time"

"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
)

var (
successMetric = prometheus.NewCounter(prometheus.CounterOpts{
Name: "proxy_check_success",
Help: "Indicates the number of successful proxy checks",
})
)

func init() {
prometheus.MustRegister(successMetric)
}

func checkProxy(ctx context.Context, proxyURL, targetURL string) {
transport, _ := http.DefaultTransport.(*http.Transport)
transport.Proxy = http.ProxyURL(mustParseURL(proxyURL))

client := &http.Client{
Transport: transport,
}

req, err := http.NewRequestWithContext(ctx, "GET", targetURL, nil)
if err != nil {
log.Printf("Error creating HTTP request: %s\n", err)
return
}

resp, err := client.Do(req)
if err != nil {
log.Printf("Error performing HTTP request: %s\n", err)
return
}
defer resp.Body.Close()

if resp.StatusCode == http.StatusOK {
successMetric.Inc()
log.Printf("Proxy check succeed, Healthy status.")
} else {
log.Printf("Proxy check failed. Status code: %d\n", resp.StatusCode)
}
}

func mustParseURL(rawURL string) *url.URL {
u, err := url.Parse(rawURL)
if err != nil {
panic(err)
}
return u
}

func main() {
proxyURL := os.Getenv("PROXY_URL")
if proxyURL == "" {
log.Fatal("PROXY_URL environment variable not set")
}
targetURL := "https://ifconfig.me"

http.Handle("/metrics", promhttp.Handler())

server := &http.Server{
Addr: ":9090",
}

var wg sync.WaitGroup

ctx, cancel := context.WithCancel(context.Background())
defer cancel()

signalCh := make(chan os.Signal, 1)
signal.Notify(signalCh, syscall.SIGINT, syscall.SIGTERM)

go func() {
<-signalCh
log.Println("Received signal, shutting down gracefully...")
cancel()
server.Shutdown(ctx)
}()

wg.Add(1)
go func() {
defer wg.Done()
ticker := time.NewTicker(5 * time.Minute)
defer ticker.Stop()

for {
select {
case <-ctx.Done():
log.Println("Ticker routine shutting down...")
return
case <-ticker.C:
checkProxy(ctx, proxyURL, targetURL)
}
}
}()

wg.Add(1)
go func() {
defer wg.Done()
log.Fatal(server.ListenAndServe())
}()

log.Println("Waiting for the HTTP server to finish...")
wg.Wait()
log.Println("All goroutines shut down. Exiting.")
}

0 comments on commit bbf0040

Please sign in to comment.