Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

0.8.1 #109

Merged
merged 17 commits into from
Feb 10, 2024
Next Next commit
Ping pong server update1 (#99)
  • Loading branch information
ViktorUJ authored Jan 31, 2024
commit f19a3b94f468a6d96d82b23631a1bfa067c824c5
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,9 @@ output_eks_task:
lint:
pre-commit run --all-files -c .hooks/.pre-commit-config.yaml

lint_go:
cd docker/ping_pong/app ; go fmt ./...

install_git_hooks:
$(VENV_BIN_PATH)/pre-commit install
@echo 'Pre-commit hooks installed'
Expand Down
12 changes: 12 additions & 0 deletions docker/ping_pong/Dockerfile_alpine
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
FROM golang:alpine AS builder

RUN apk update && apk add --no-cache git
WORKDIR $GOPATH/src/mypackage/myapp/
COPY app/ .
RUN go mod tidy
RUN go build -ldflags="-w -s" -o app app.go

FROM alpine:3.19.1
RUN apk add --update --no-cache curl netcat-openbsd bash jq
COPY --from=builder /go/src/mypackage/myapp/app app
ENTRYPOINT ["/app"]
28 changes: 28 additions & 0 deletions docker/ping_pong/README.MD
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,35 @@ This is a small HTTP server that sends back the incoming request with all the me
- `METRIC_PORT`: The port where server metrics are available in Prometheus format.
- `ENABLE_OUTPUT`: log to stdout (default = "true")
- `LOG_PATH`: write logs to file ${LOG_PATH} (default="" without file output)
- `ENABLE_LOAD_MEMORY` : enable memory usage (default=false)
- `MEMORY_USAGE_PROFILE`: additional memory usage and time for usage . example `5=10 7=60 1024=360 ` - 5 Mb 10sec 7 Mb 60sec 1024Mb 360sec
- `ENABLE_LOG_LOAD_MEMORY`: logs LOAD_MEMORY function
- `ENABLE_LOAD_CPU` : enable cpu usage (default=false)
- `ENABLE_LOG_LOAD_CPU`: logs LOAD_CPU function
- `CPU_USAGE_PROFILE`: additional CPU usage `iteraction_milion=wait_msec=gorutins=time_sec` . example `10=1=1=30 1=400=1=60`
- `CPU_MAXPROC`: GOMAXPROCS (default = 1)

You can view the current metrics at `{server_address}:{METRIC_PORT}/metrics`.

`docker pull viktoruj/ping_pong`

## examples

### run http pingPong server
```
kubectl run test -n circleci --image viktoruj/ping_pong
```

### run http pingPong server with serverName
```
kubectl run test -n circleci --image viktoruj/ping_pong --env SERVER_NAME=pingPongServer
```

### run http pingPong server with MEMORY_USAGE
```
kubectl run test -n circleci --image viktoruj/ping_pong --env MEMORY_USAGE_PROFILE='5=60 20=60 1024=360 ' --env ENABLE_LOAD_MEMORY=true
```
### run http pingPong server with MEMORY_USAGE and CPU_USAGE and enable cpu and memory loging . It uses CPU_MAXPROC =2 .
```
kubectl run test --image viktoruj/ping_pong --env CPU_USAGE_PROFILE='1=400=1=60 1=4=1=60 10=1=4=60' --env ENABLE_LOAD_CPU=true --env ENABLE_LOG_LOAD_CPU=true --env CPU_MAXPROC=2 --env MEMORY_USAGE_PROFILE='5=60 20=60 1024=360 ' --env ENABLE_LOAD_MEMORY=true --env ENABLE_LOG_LOAD_MEMORY=true
```
182 changes: 168 additions & 14 deletions docker/ping_pong/app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ package main

import (
"fmt"
"math/rand"
"net"
"net/http"
"os"
"path/filepath"
"path/filepath"
"runtime"
"strconv"
"strings"
"sync/atomic"
"time"
Expand All @@ -15,14 +17,33 @@ import (
"github.com/prometheus/client_golang/prometheus/promhttp"
)

type MemoryUsageProfile struct {
Megabytes int
Seconds int
}

type CpuUsageProfile struct {
IterationsMillion int
WaitMilliseconds int
Goroutines int
TimeSeconds int
}

var (
requestsPerSecond float64
requestsPerMinute float64
lastRequestTime time.Time
requestsCount uint64
serverName string
logPath string
enableOutput string
requestsPerSecond float64
requestsPerMinute float64
lastRequestTime time.Time
requestsCount uint64
serverName string
logPath string
enableOutput string
enableLoadCpu string
enableLoadMemory string
enableLogLoadMemory string
enableLogLoadCpu string
memoryProfiles []MemoryUsageProfile
cpuProfiles []CpuUsageProfile
cpuMaxProc int
)

func init() {
Expand All @@ -31,11 +52,38 @@ func init() {
serverName = "ping_pong_server"
}
logPath = os.Getenv("LOG_PATH")

enableOutput = os.Getenv("ENABLE_OUTPUT")
if enableOutput == "" {
enableOutput = "true"
}

enableLoadCpu = os.Getenv("ENABLE_LOAD_CPU")
if enableLoadCpu == "" {
enableLoadCpu = "false"
}

enableLoadMemory = os.Getenv("ENABLE_LOAD_MEMORY")
if enableLoadMemory == "" {
enableLoadMemory = "false"
}
enableLogLoadMemory = os.Getenv("ENABLE_LOG_LOAD_MEMORY")
if enableLogLoadMemory == "" {
enableLogLoadMemory = "false"
}

enableLogLoadCpu = os.Getenv("ENABLE_LOG_LOAD_CPU")
if enableLogLoadCpu == "" {
enableLogLoadCpu = "false"
}

cpuMaxProc = func() int {
if value, err := strconv.Atoi(os.Getenv("CPU_MAXPROC")); err == nil && value > 0 {
return value
}
return 1
}()

if logPath != "" {
dir := filepath.Dir(logPath)
if _, err := os.Stat(dir); os.IsNotExist(err) {
Expand All @@ -51,12 +99,112 @@ func init() {
}
file.Close()
}

}
func cpuUsage() {

cpuProfileStr := os.Getenv("CPU_USAGE_PROFILE")
profiles := strings.Split(cpuProfileStr, " ")
for _, p := range profiles {
parts := strings.Split(p, "=")
if len(parts) == 4 {
iterationsMillion, err1 := strconv.Atoi(parts[0])
waitMilliseconds, err2 := strconv.Atoi(parts[1])
goroutines, err3 := strconv.Atoi(parts[2])
timeSeconds, err4 := strconv.Atoi(parts[3])

if err1 == nil && err2 == nil && err3 == nil && err4 == nil {
cpuProfiles = append(cpuProfiles, CpuUsageProfile{
IterationsMillion: iterationsMillion,
WaitMilliseconds: waitMilliseconds,
Goroutines: goroutines,
TimeSeconds: timeSeconds,
})
}
}
}

for {
for _, profile := range cpuProfiles {
if enableLogLoadCpu == "true" {
sendLog(fmt.Sprintf("LoadCpu => IterationsMillion: %d, WaitMilliseconds: %d, Goroutines: %d, TimeSeconds: %d, cpuMaxProc:%d\n ",
profile.IterationsMillion, profile.WaitMilliseconds, profile.Goroutines, profile.TimeSeconds, cpuMaxProc))
}

for i := 0; i < profile.Goroutines; i++ {
go cpuLoad(profile.IterationsMillion, profile.WaitMilliseconds, profile.TimeSeconds)
}
time.Sleep(time.Duration(profile.TimeSeconds) * time.Second)
}

}
}

func cpuLoad(iterationsMillion int, waitMilliseconds int, timeSeconds int) {
totalIterations := iterationsMillion * 1000000
var sum int

deadline := time.Now().Add(time.Duration(timeSeconds) * time.Second)

for time.Now().Before(deadline) {
for i := 0; i < totalIterations; i++ {
sum += rand.Intn(256)
}

if time.Now().Add(time.Duration(waitMilliseconds) * time.Millisecond).Before(deadline) {
time.Sleep(time.Duration(waitMilliseconds) * time.Millisecond)
}
}
}

func memoryUsage() {
for {
memoryProfileStr := os.Getenv("MEMORY_USAGE_PROFILE")

if memoryProfileStr != "" {
// split "Mb=sec"
memoryProfilePairs := strings.Split(memoryProfileStr, " ")

for _, pair := range memoryProfilePairs {
parts := strings.Split(pair, "=")
if len(parts) == 2 {
mb, errMb := strconv.Atoi(parts[0])
sec, errSec := strconv.Atoi(parts[1])
if errMb == nil && errSec == nil {
memoryProfiles = append(memoryProfiles, MemoryUsageProfile{
Megabytes: mb,
Seconds: sec,
})
}
}
}
}

for _, profile := range memoryProfiles {
if enableLogLoadMemory == "true" {
sendLog(fmt.Sprintf("LoadMemory => Megabytes: %d, Seconds: %d\n", profile.Megabytes, profile.Seconds))
}
size := profile.Megabytes * 1024 * 1024
slice := make([]byte, size)

for i := range slice {
slice[i] = 0xFF
}
time.Sleep(time.Duration(profile.Seconds) * time.Second)
slice = nil
runtime.GC()
time.Sleep(20 * time.Second) // wait GCC

}

}

}

func requestHandler(w http.ResponseWriter, r *http.Request) {
var response strings.Builder
response.WriteString(fmt.Sprintf("Server Name: %s\n", serverName))
response.WriteString(fmt.Sprintf("URL: http://%s%s\n", r.Host, r.URL.String()))
response.WriteString(fmt.Sprintf("URL: http://%s%s\n", r.Host, r.URL.String()))
response.WriteString(fmt.Sprintf("Client IP: %s\n", getIP(r)))
response.WriteString(fmt.Sprintf("Method: %s\n", r.Method))
response.WriteString(fmt.Sprintf("Protocol: %s\n", r.Proto))
Expand Down Expand Up @@ -136,7 +284,7 @@ func metricsHandler() {
}

http.Handle("/metrics", promhttp.Handler())
http.ListenAndServe(":" + metricPort, nil)
http.ListenAndServe(":"+metricPort, nil)
}

func sendLog(message string) {
Expand All @@ -162,17 +310,23 @@ func main() {
for _, env := range os.Environ() {
sendLog(env)
}

http.HandleFunc("/", requestHandler)
go metricsHandler()

sendLog(fmt.Sprintf("enableLoadCpu: %v, cpuMaxProc: %d", enableLoadCpu, cpuMaxProc))
runtime.GOMAXPROCS(cpuMaxProc)
if enableLoadMemory == "true" {
go memoryUsage()
}
if enableLoadCpu == "true" {
go cpuUsage()
}
port := os.Getenv("SRV_PORT")
if port == "" {
sendLog("SRV_PORT is not set, defaulting to 8080")
sendLog("SRV_PORT is not set, default port : 8080")
port = "8080"
}

err := http.ListenAndServe(":" + port, nil)
err := http.ListenAndServe(":"+port, nil)
if err != nil {
sendLog(fmt.Sprintf("Server failed: %v", err))
}
Expand Down
66 changes: 60 additions & 6 deletions docker/ping_pong/build.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,60 @@
docker buildx build --platform linux/arm64 --load -t viktoruj/ping_pong:arm64 .
docker buildx build --platform linux/amd64 --load -t viktoruj/ping_pong:amd64 .
docker push viktoruj/ping_pong:arm64
docker push viktoruj/ping_pong:amd64
docker manifest create viktoruj/ping_pong:latest viktoruj/ping_pong:arm64 viktoruj/ping_pong:amd64
docker manifest push viktoruj/ping_pong:latest
latest_commit_hash=$(git rev-parse --short HEAD)

while [[ $# > 0 ]]; do
key="$1"
case "$key" in
--release)
release="$2"
shift
;;

*)
;;
esac
shift
done

if [ -z "$release" ]; then
release="dev"
fi

echo "*** release = $release"

case $release in
scratch)
docker buildx build --platform linux/arm64 --load -t viktoruj/ping_pong:${latest_commit_hash}-arm64 .
docker buildx build --platform linux/amd64 --load -t viktoruj/ping_pong:${latest_commit_hash}-amd64 .
docker push viktoruj/ping_pong:${latest_commit_hash}-arm64
docker push viktoruj/ping_pong:${latest_commit_hash}-amd64
docker manifest create viktoruj/ping_pong:${latest_commit_hash} viktoruj/ping_pong:${latest_commit_hash}-arm64 viktoruj/ping_pong:${latest_commit_hash}-amd64
docker manifest push viktoruj/ping_pong:${latest_commit_hash}
echo "*** do release"
docker manifest rm viktoruj/ping_pong:latest
docker manifest create viktoruj/ping_pong:latest viktoruj/ping_pong:${latest_commit_hash}-arm64 viktoruj/ping_pong:${latest_commit_hash}-amd64
docker manifest push viktoruj/ping_pong:latest
;;
alpine)
echo "*** do release alpine"
docker buildx build --platform linux/arm64 --load -t viktoruj/ping_pong:${latest_commit_hash}-arm64-alpine -f Dockerfile_alpine .
docker buildx build --platform linux/amd64 --load -t viktoruj/ping_pong:${latest_commit_hash}-amd64-alpine -f Dockerfile_alpine .
docker push viktoruj/ping_pong:${latest_commit_hash}-arm64-alpine
docker push viktoruj/ping_pong:${latest_commit_hash}-amd64-alpine
docker manifest create viktoruj/ping_pong:${latest_commit_hash}-alpine viktoruj/ping_pong:${latest_commit_hash}-arm64-alpine viktoruj/ping_pong:${latest_commit_hash}-amd64-alpine
docker manifest push viktoruj/ping_pong:${latest_commit_hash}-alpine

docker manifest rm viktoruj/ping_pong:alpine
docker manifest create viktoruj/ping_pong:alpine viktoruj/ping_pong:${latest_commit_hash}-arm64-alpine viktoruj/ping_pong:${latest_commit_hash}-amd64-alpine
docker manifest push viktoruj/ping_pong:alpine

;;
dev)
docker buildx build --platform linux/arm64 --load -t viktoruj/ping_pong:${latest_commit_hash}-arm64 .
docker buildx build --platform linux/amd64 --load -t viktoruj/ping_pong:${latest_commit_hash}-amd64 .
docker push viktoruj/ping_pong:${latest_commit_hash}-arm64
docker push viktoruj/ping_pong:${latest_commit_hash}-amd64
docker manifest create viktoruj/ping_pong:${latest_commit_hash} viktoruj/ping_pong:${latest_commit_hash}-arm64 viktoruj/ping_pong:${latest_commit_hash}-amd64
docker manifest push viktoruj/ping_pong:${latest_commit_hash}
echo "*** not need release"
;;

esac
9 changes: 9 additions & 0 deletions docs/tips_and_tricks.MD
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,12 @@ The Vim editor is used by default, which means you should be aware how to use sh
`w` - jump to the start of the next word

`:25` - go to the 25th row in the file

## aliases

`export do="--dry-run=client -o yaml" `
````
# usage fo create pod template

k run test --image nginx $do
````
2 changes: 1 addition & 1 deletion tasks/eks/labs/01/eks/terragrunt.hcl
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ inputs = {
resolve_conflicts = "OVERWRITE"
}
kube-proxy = {
# related table https://docs.aws.amazon.com/eks/latest/userguide/managing-kube-proxy.html
# related table https://docs.aws.amazon.com/eks/latest/userguide/managing-kube-proxy.html
version = "v1.24.10-eksbuild.2"
resolve_conflicts = "OVERWRITE"
}
Expand Down