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

Glog-ify logging #20

Merged
merged 27 commits into from
Nov 9, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
5b285c0
Enhancing Dockerfile
Aergonus Oct 9, 2017
3f3b0a0
minor text fixes
Aergonus Oct 9, 2017
4af1851
How to Bash
Aergonus Oct 9, 2017
0ed7ce3
Learned how to Bash
Aergonus Oct 9, 2017
80d0e51
Merge pull request #14 from Spellchaser/dockerfile-enhance
asobti Oct 10, 2017
4a605c4
Merge pull request #1 from asobti/master
Aergonus Oct 10, 2017
c8c253c
Docker Build Support for Proxies
Aergonus Oct 11, 2017
fc783ae
Merge pull request #15 from Spellchaser/proxy-support
asobti Oct 11, 2017
64984cb
Merge pull request #2 from asobti/master
Aergonus Oct 12, 2017
8c33be8
Replace spaces with tab to avoid Makefile syntax failure
chaitanyaenr Oct 19, 2017
e72ec5a
Merge pull request #16 from chaitanyaenr/fix_makefile
asobti Oct 19, 2017
2dd3667
Merge remote-tracking branch 'refs/remotes/asobti/master'
Aergonus Oct 29, 2017
b1615ef
Standardize Imports
Aergonus Oct 31, 2017
6d73184
glogify (fmt --> glog)
Aergonus Oct 31, 2017
9fff34e
Refactor Code
Aergonus Oct 31, 2017
cc77824
Update glide for glog
Aergonus Oct 31, 2017
ad1cb90
Fix Schedule Output
Aergonus Oct 31, 2017
e6f8ab5
Configuring glog level
Aergonus Oct 31, 2017
229683a
Terminations should be Info
Aergonus Nov 1, 2017
338564c
Enable file and stderr logging
Aergonus Nov 1, 2017
15cfd90
Add custom logging to file
Aergonus Nov 1, 2017
6e38d69
Remove Error
Aergonus Nov 1, 2017
d20d133
Programatically try mkdir -p
Aergonus Nov 1, 2017
da7ac82
Successfully creating custom directory is not error
Aergonus Nov 1, 2017
52ef4a8
Better Info Description
Aergonus Nov 1, 2017
e909741
Capture error and Dlog level
Aergonus Nov 1, 2017
c3aa6bc
Update to sensible example
Aergonus Nov 1, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
8 changes: 6 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
FROM ubuntu
RUN apt-get update
RUN apt-get install tzdata -y
RUN if (dpkg -l | grep -cq tzdata); then \
echo "tzdata package already installed! Skipping tzdata installation"; \
else \
echo "Installing tzdata to avoid go panic caused by missing timezone data"; \
apt-get update && apt-get install tzdata -y --no-install-recommends apt-utils; \
fi
COPY kube-monkey /kube-monkey
21 changes: 19 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,30 @@ all: build
ENVVAR = GOOS=linux GOARCH=amd64 CGO_ENABLED=0
TAG = v0.1.0

.PHONY: all build container clean

build: clean
$(ENVVAR) go build -o kube-monkey

# Supressing docker build avoids printing the env variables
container: build
ifneq ($(and $(http_proxy), $(https_proxy)),)
@echo Starting Docker build, importing both http_proxy and https_proxy env variables
@docker build --build-arg http_proxy=$(http_proxy) --build-arg https_proxy=$(https_proxy) -t kube-monkey:$(TAG) .
else
ifdef http_proxy
@echo Starting Docker build, importing http_proxy
@docker build --build-arg http_proxy=$(http_proxy) -t kube-monkey:$(TAG) .
else
ifdef https_proxy
@echo Starting Docker build, importing https_proxy
@docker build --build-arg https_proxy=$(https_proxy) -t kube-monkey:$(TAG) .
else
@echo no env proxies set, building normally
docker build -t kube-monkey:$(TAG) .
endif
endif
endif

clean:
rm -f kube-monkey

.PHONY: all build container clean
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,10 @@ in other namespaces (eg. `kube-system`).

See dir [`examples/`](https://github.com/asobti/kube-monkey/tree/master/examples) for example Kubernetes yaml files.

## Logging

kube-monkey uses glog and supports all command-line features for glog. To specify a custom v level or a custom log directory on the pod, see `args: ["-v=5", "-log_dir=/path/to/custom/log"]` in the [example deployment file](https://github.com/asobti/kube-monkey/tree/master/examples/deployment.yaml)

## Compatibility with Kubernetes

kube-monkey is built using v1.5 of [kubernetes/client-go](https://github.com/kubernetes/client-go). Refer to the
Expand Down
9 changes: 6 additions & 3 deletions calendar/calendar.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package calendar

import (
"fmt"
"math/rand"
"time"
"math/rand"

"github.com/golang/glog"
)

// Checks if specified Time is a weekday
Expand All @@ -15,7 +16,9 @@ func isWeekday(t time.Time) bool {
return false
}

panic(fmt.Sprintf("Unrecognized day of the week: %s", t.Weekday().String()))
glog.Fatalf("Unrecognized day of the week: %s", t.Weekday().String())

panic("Explicit Panic to avoid compiler error: missing return at end of function")
}

// Returns the next weekday in Location
Expand Down
23 changes: 13 additions & 10 deletions chaos/chaos.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,17 @@ package chaos

import (
"fmt"
"time"
"math/rand"

"github.com/golang/glog"

"github.com/asobti/kube-monkey/config"
"github.com/asobti/kube-monkey/deployments"
"github.com/asobti/kube-monkey/kubernetes"

kube "k8s.io/client-go/1.5/kubernetes"
"k8s.io/client-go/1.5/pkg/api/v1"
"math/rand"
"time"
)

type Chaos struct {
Expand Down Expand Up @@ -75,8 +79,7 @@ func (c *Chaos) Execute(resultchan chan<- *ChaosResult) {
// Do the termination
killAll, err := c.deployment.HasKillAll(client)
if err != nil {
fmt.Printf("Failed to check KillAll label for deployment %s. Proceeding with termination of a single pod.\n", c.deployment.Name())
fmt.Printf(err.Error())
glog.Errorf("Failed to check KillAll label for deployment %s. Proceeding with termination of a single pod. Error: %v", c.deployment.Name(), err.Error())
}

if killAll {
Expand Down Expand Up @@ -107,14 +110,14 @@ func (c *Chaos) Terminate(client *kube.Clientset) error {

targetPod := RandomPodName(pods)

fmt.Printf("Terminating pod %s for deployment %s\n", targetPod, c.deployment.Name())
glog.Errorf("Terminating pod %s for deployment %s\n", targetPod, c.deployment.Name())
return c.DeletePod(client, targetPod)
}

// Terminates ALL pods for the deployment
// Not the default, or recommended, behavior
func (c *Chaos) TerminateAll(client *kube.Clientset) error {
fmt.Printf("Terminating ALL pods for deployment %s\n", c.deployment.Name())
glog.V(1).Infof("Terminating ALL pods for deployment %s\n", c.deployment.Name())

pods, err := c.deployment.Pods(client)
if err != nil {
Expand All @@ -128,7 +131,7 @@ func (c *Chaos) TerminateAll(client *kube.Clientset) error {
for _, pod := range pods {
// In case of error, log it and move on to next pod
if err = c.DeletePod(client, pod.Name); err != nil {
fmt.Printf("Failed to delete pod %s for deployment %s", pod.Name, c.deployment.Name())
glog.Errorf("Failed to delete pod %s for deployment %s", pod.Name, c.deployment.Name())
}
}

Expand All @@ -138,7 +141,7 @@ func (c *Chaos) TerminateAll(client *kube.Clientset) error {
// Deletes a pod for a deployment
func (c *Chaos) DeletePod(client *kube.Clientset, podName string) error {
if config.DryRun() {
fmt.Printf("[DryRun Mode] Terminated pod %s for deployment %s\n", podName, c.deployment.Name())
glog.V(1).Infof("[DryRun Mode] Terminated pod %s for deployment %s\n", podName, c.deployment.Name())
return nil
} else {
return c.deployment.DeletePod(client, podName)
Expand All @@ -157,13 +160,13 @@ func (c *Chaos) NewResult(e error) *ChaosResult {
func CreateClient() (*kube.Clientset, error) {
client, err := kubernetes.NewInClusterClient()
if err != nil {
return nil, err
return nil, fmt.Errorf("Failed to generate NewInClusterClient: %v", err)
}

if kubernetes.VerifyClient(client) {
return client, nil
} else {
return nil, fmt.Errorf("Unable to verify Kubernetes client")
return nil, fmt.Errorf("Unable to verify client connectivity to Kubernetes apiserver")
}
}

Expand Down
22 changes: 15 additions & 7 deletions config/config.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
package config

import (
"fmt"
"github.com/asobti/kube-monkey/config/param"
"github.com/fsnotify/fsnotify"
"time"

"github.com/golang/glog"
"github.com/spf13/viper"
"github.com/fsnotify/fsnotify"

"github.com/asobti/kube-monkey/config/param"

"k8s.io/client-go/1.5/pkg/util/sets"
"time"
)

const (
Expand Down Expand Up @@ -46,7 +49,7 @@ func setupWatch() {
// TODO: This does not appear to be working
viper.WatchConfig()
viper.OnConfigChange(func(e fsnotify.Event) {
fmt.Println("Config change detected")
glog.V(2).Infoln("Config change detected")
ValidateConfigs()
})
}
Expand All @@ -61,7 +64,12 @@ func Init() error {
return err
}

ValidateConfigs()
if err := ValidateConfigs(); err != nil {
glog.Errorf("Failed to validate %v", err)
return err
} else {
glog.V(3).Info("Successfully validated configs")
}
setupWatch()
return nil
}
Expand All @@ -74,7 +82,7 @@ func Timezone() *time.Location {
tz := viper.GetString(param.Timezone)
location, err := time.LoadLocation(tz)
if err != nil {
panic(err.Error())
glog.Fatal(err.Error())
}
return location
}
Expand Down
12 changes: 6 additions & 6 deletions config/validations.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,37 +2,37 @@ package config

import (
"fmt"

"github.com/asobti/kube-monkey/config/param"
)

func ValidateConfigs() error {
// RunHour should be [0, 23]
runHour := RunHour()

if !IsValidHour(runHour) {
return fmt.Errorf("%s is outside valid range of [0,23]", param.RunHour)
return fmt.Errorf("RunHour: %s is outside valid range of [0,23]", param.RunHour)
}

// StartHour should be [0, 23]
startHour := StartHour()
if !IsValidHour(startHour) {
return fmt.Errorf("%s is outside valid range of [0,23]", param.StartHour)
return fmt.Errorf("StartHour: %s is outside valid range of [0,23]", param.StartHour)
}

// EndHour should be [0, 23]
endHour := EndHour()
if !IsValidHour(endHour) {
return fmt.Errorf("%s is outside valid range of [0,23]", param.EndHour)
return fmt.Errorf("EndHour: %s is outside valid range of [0,23]", param.EndHour)
}

// StartHour should be < EndHour
if !(startHour < endHour) {
return fmt.Errorf("%s must be less than %s", param.StartHour, param.EndHour)
return fmt.Errorf("StartHour: %s must be less than %s", param.StartHour, param.EndHour)
}

// RunHour should be < StartHour
if !(runHour < startHour) {
return fmt.Errorf("%s should be less than %s", param.RunHour, param.StartHour)
return fmt.Errorf("RunHour: %s should be less than %s", param.RunHour, param.StartHour)
}

return nil
Expand Down
4 changes: 3 additions & 1 deletion deployments/deployments.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,17 @@ package deployments

import (
"fmt"
"strconv"

"github.com/asobti/kube-monkey/config"

kube "k8s.io/client-go/1.5/kubernetes"
"k8s.io/client-go/1.5/pkg/api"
"k8s.io/client-go/1.5/pkg/api/v1"
"k8s.io/client-go/1.5/pkg/apis/extensions/v1beta1"
"k8s.io/client-go/1.5/pkg/labels"
"k8s.io/client-go/1.5/pkg/selection"
"k8s.io/client-go/1.5/pkg/util/sets"
"strconv"
)

type Deployment struct {
Expand Down
6 changes: 4 additions & 2 deletions deployments/eligible_deployments.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package deployments

import (
"fmt"
"github.com/golang/glog"

"github.com/asobti/kube-monkey/config"
"github.com/asobti/kube-monkey/kubernetes"

"k8s.io/client-go/1.5/pkg/api"
"k8s.io/client-go/1.5/pkg/apis/extensions/v1beta1"
"k8s.io/client-go/1.5/pkg/labels"
Expand All @@ -23,7 +25,7 @@ func EligibleDeployments() ([]*Deployment, error) {
for _, dep := range enabledDeployments {
deployment, err := New(&dep)
if err != nil {
fmt.Printf("Skipping eligible deployment %s because of error:\n%s\n", dep.Name, err.Error())
glog.V(3).Infof("Skipping eligible deployment %s because of error:\n%s\n", dep.Name, err.Error())
continue
}

Expand Down
1 change: 1 addition & 0 deletions examples/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
- name: kube-monkey
command:
- "/kube-monkey"
args: ["-v=5", "-log_dir=/var/log/kube-monkey"]
image: kube-monkey:v0.1.0
volumeMounts:
- name: config-volume
Expand Down
35 changes: 14 additions & 21 deletions kubemonkey/kubemonkey.go
Original file line number Diff line number Diff line change
@@ -1,35 +1,29 @@
package kubemonkey

import (
"fmt"
"github.com/asobti/kube-monkey/calendar"
"time"

"github.com/golang/glog"

"github.com/asobti/kube-monkey/chaos"
"github.com/asobti/kube-monkey/config"
"github.com/asobti/kube-monkey/kubernetes"
"github.com/asobti/kube-monkey/calendar"
"github.com/asobti/kube-monkey/schedule"
"time"
)

func verifyKubeClient() error {
client, err := kubernetes.NewInClusterClient()
if err != nil {
return err
}
if !kubernetes.VerifyClient(client) {
fmt.Println(err)
return fmt.Errorf("Unable to verify client connectivity to Kubernetes server")
}
return nil
_, err := chaos.CreateClient()
return err
}

func durationToNextRun(runhour int, location *time.Location) time.Duration {
if config.DebugEnabled() {
debugDelayDuration := config.DebugScheduleDelay()
fmt.Printf("Debug mode detected. Next run scheduled in %.0f sec\n", debugDelayDuration.Seconds())
glog.V(2).Infof("Debug mode detected! Generating next schedule in %.0f sec\n", debugDelayDuration.Seconds())
return debugDelayDuration
} else {
nextRun := calendar.NextRuntime(location, runhour)
fmt.Printf("Next run scheduled at %s\n", nextRun)
glog.V(2).Infof("Generating next schedule at %s\n", nextRun)
return nextRun.Sub(time.Now())
}
}
Expand All @@ -48,7 +42,7 @@ func Run() error {

schedule, err := schedule.New()
if err != nil {
panic(err.Error())
glog.Fatal(err.Error())
}
schedule.Print()
ScheduleTerminations(schedule.Entries())
Expand All @@ -67,19 +61,18 @@ func ScheduleTerminations(entries []*chaos.Chaos) {
completedCount := 0
var result *chaos.ChaosResult

fmt.Println("Waiting for terminations to run")
glog.V(3).Infof("Waiting for terminations to run")

// Gather results
for completedCount < len(entries) {
result = <-resultchan
if result.Error() != nil {
fmt.Printf("Failed to execute termination for deployment %s. Error:\n", result.Deployment().Name())
fmt.Println(result.Error().Error())
glog.Errorf("Failed to execute termination for deployment %s. Error: %v", result.Deployment().Name(), result.Error().Error())
} else {
fmt.Printf("Termination successfully executed for deployment %s\n", result.Deployment().Name())
glog.V(2).Infof("Termination successfully executed for deployment %s\n", result.Deployment().Name())
}
completedCount++
}

fmt.Println("All terminations done")
glog.V(3).Info("All terminations done")
}
Loading