Compare commits

..

25 Commits

Author SHA1 Message Date
Ian Fijolek
0b2078c6c5 uncomment test stuff 2021-01-08 18:09:27 -05:00
Ian Fijolek
0ed96f6c22 Remove prerelease 2021-01-08 18:06:56 -05:00
Ian Fijolek
8c12e80ad2 Try to stop building on pushes to non-master 2021-01-08 18:05:33 -05:00
Ian Fijolek
f6a9199f25 Change exec find 2021-01-08 18:01:58 -05:00
Ian Fijolek
3c2cae3011 Switch to ubuntu 2021-01-08 17:59:28 -05:00
Ian Fijolek
f9c082d30f More debugging 2021-01-08 17:56:30 -05:00
Ian Fijolek
5bb4da6178 More debugging 2021-01-08 17:53:19 -05:00
Ian Fijolek
d810bcb61c Try to fix compress step again 2021-01-08 17:44:52 -05:00
Ian Fijolek
e7353bb8df Try to fix compress step 2021-01-08 17:38:55 -05:00
Ian Fijolek
06ea8bea30 Add branch name to unstable release 2021-01-08 17:36:24 -05:00
Ian Fijolek
2e5ab23bd1 Add darwin releases 2021-01-08 17:33:27 -05:00
Ian Fijolek
aa741eb49e Make check step faster 2021-01-08 17:31:56 -05:00
Ian Fijolek
96c9b7d74c Add prereleases 2021-01-08 17:29:57 -05:00
Ian Fijolek
31336280e6 Add release uploads 2021-01-08 17:21:02 -05:00
Ian Fijolek
a1b906b94a Update for go 1.15 2020-11-16 15:56:31 -08:00
Ian Fijolek
0a5be250b5 Scripts: Add echoing log lines to helper scripts
Rather than only returning the status of whether or not a container is
healhthy, the helper scripts will now optionally echo some of the latest
log lines.
2020-11-16 15:52:21 -08:00
Ian Fijolek
88f77aa27c Fix Makefile comment 2020-11-16 15:51:41 -08:00
Ian Fijolek
67c2375bba Remove docker linting for now
Drone check doesn't pass. Need to install docker there
2020-07-14 17:29:54 -07:00
Ian Fijolek
aad9eaa32f Update exported status metric to properly reflect alerting status of a monitor
It was using the result of the individual check and not the monitor as a whole
2020-07-14 17:09:56 -07:00
Ian Fijolek
5dc5ba5257 Add docker linting 2020-07-14 17:08:48 -07:00
Ian Fijolek
4aff294739 Set overrided version in drone config 2020-07-07 12:15:53 -07:00
Ian Fijolek
0684b15a44 Update logic for setting version
I noticed that versions were not being properly dervied from the git
tags. This fixes that in a simpler way by allowing git to describe the
current commit with tags, commits, shas, and a dirty maker.
2020-07-07 10:51:13 -07:00
Ian Fijolek
d3826dacde Update drone to use new linux only target 2020-07-06 20:33:02 -07:00
Ian Fijolek
f8e40c643c Move static binaries to dist/ for easier publishing
This will make it easier to publish them to Github or Gitea releases later.

To avoid making the Makefile super complex, this patch also makes use of
variables to simplify the Makefile as well.
2020-07-06 20:15:21 -07:00
Ian Fijolek
cffbbd734a Make default log alert conditional
Allow using the default `log` alert for both up and down alerts using
Go's templating conditionals. Following this example can do away with
the need for an up and down version of every alert.
2020-06-19 09:51:42 -07:00
13 changed files with 144 additions and 80 deletions
+46 -24
View File
@@ -3,31 +3,15 @@ kind: pipeline
name: test name: test
steps: steps:
- name: test - name: test
image: golang:1.12 image: golang:1.12
environment:
VERSION: ${DRONE_TAG:-${DRONE_COMMIT}}
commands: commands:
- make build
- make test - make test
- name: check - name: check
image: python:3 image: iamthefij/drone-pre-commit:personal
commands:
- pip install pre-commit==1.20.0
- make check
- name: notify
image: drillster/drone-email
settings:
host:
from_secret: SMTP_HOST
username:
from_secret: SMTP_USER
password:
from_secret: SMTP_PASS
from: drone@iamthefij.com
when:
status: [changed, failure]
--- ---
kind: pipeline kind: pipeline
@@ -47,9 +31,35 @@ trigger:
steps: steps:
- name: build all binaries - name: build all binaries
image: golang:1.12 image: golang:1.12
environment:
VERSION: ${DRONE_TAG:-${DRONE_COMMIT}}
commands: commands:
- make all - make all
- name: compress binaries for release
image: ubuntu
commands:
- find ./dist -type f -executable -execdir tar -czvf {}.tar.gz {} \;
when:
event: tag
- name: upload gitea release
image: plugins/gitea-release
settings:
title: ${DRONE_TAG}
files: dist/*.tar.gz
checksum:
- md5
- sha1
- sha256
- sha512
base_url:
from_secret: gitea_base_url
api_key:
from_secret: gitea_token
when:
event: tag
- name: push image - arm - name: push image - arm
image: plugins/docker image: plugins/docker
settings: settings:
@@ -100,15 +110,27 @@ steps:
password: password:
from_secret: docker_password from_secret: docker_password
---
kind: pipeline
name: notify
depends_on:
- test
- publish
trigger:
status:
- failure
steps:
- name: notify - name: notify
image: drillster/drone-email image: drillster/drone-email
settings: settings:
host: host:
from_secret: SMTP_HOST from_secret: SMTP_HOST # pragma: whitelist secret
username: username:
from_secret: SMTP_USER from_secret: SMTP_USER # pragma: whitelist secret
password: password:
from_secret: SMTP_PASS from_secret: SMTP_PASS # pragma: whitelist secret
from: drone@iamthefij.com from: drone@iamthefij.com
when:
status: [changed, failure]
Vendored
+1 -2
View File
@@ -17,5 +17,4 @@ config.yml
# Output binary # Output binary
minitor minitor
minitor-linux-* dist/
minitor-darwin-amd64
+5
View File
@@ -17,3 +17,8 @@ repos:
- id: go-imports - id: go-imports
# - id: gometalinter # - id: gometalinter
# - id: golangci-lint # - id: golangci-lint
# - repo: https://github.com/IamTheFij/docker-pre-commit
# rev: v2.0.0
# hooks:
# - id: docker-compose-check
# - id: hadolint
+1 -1
View File
@@ -20,7 +20,7 @@ RUN chmod -R 755 /app/scripts
# Copy minitor in # Copy minitor in
ARG ARCH=amd64 ARG ARCH=amd64
COPY ./minitor-linux-${ARCH} ./minitor COPY ./dist/minitor-linux-${ARCH} ./minitor
# Drop to non-root user # Drop to non-root user
USER minitor USER minitor
+35 -41
View File
@@ -1,36 +1,43 @@
DOCKER_TAG ?= minitor-go-${USER} DOCKER_TAG ?= minitor-go-${USER}
GIT_TAG_NAME := $(shell git tag -l --contains HEAD) VERSION ?= $(shell git describe --tags --dirty)
GIT_SHA := $(shell git rev-parse HEAD) GOFILES = *.go
VERSION := $(if $(GIT_TAG_NAME),$(GIT_TAG_NAME),$(GIT_SHA)) # Multi-arch targets are generated from this
TARGET_ALIAS = minitor-linux-amd64 minitor-linux-arm minitor-linux-arm64 minitor-darwin-amd64
TARGETS = $(addprefix dist/,$(TARGET_ALIAS))
#
# Default make target will run tests
.DEFAULT_GOAL = test
# Build all static Minitor binaries
.PHONY: all .PHONY: all
all: minitor-linux-amd64 minitor-linux-arm minitor-linux-arm64 all: $(TARGETS)
.PHONY: default # Build all static Linux Minitor binaries. Used in Docker images
default: test .PHONY: all-linux
all-linux: $(filter dist/minitor-linux-%,$(TARGETS))
# Build minitor for the current machine
minitor: $(GOFILES)
@echo Version: $(VERSION)
go build -ldflags '-X "main.version=${VERSION}"' -o minitor
.PHONY: build .PHONY: build
build: minitor build: minitor
minitor: # Run minitor for the current machine
@echo Version: $(VERSION)
go build -ldflags '-X "main.version=${VERSION}"' -o minitor
.PHONY: run .PHONY: run
run: minitor build run: minitor
./minitor -debug ./minitor -debug
.PHONY: run-metrics .PHONY: run-metrics
run-metrics: minitor build run-metrics: minitor
./minitor -debug -metrics ./minitor -debug -metrics
# Run all tests
.PHONY: test .PHONY: test
test: test:
go test -coverprofile=coverage.out go test -coverprofile=coverage.out
@echo
go tool cover -func=coverage.out go tool cover -func=coverage.out
@echo
@# Check min coverage percentage
@go tool cover -func=coverage.out | awk -v target=80.0% \ @go tool cover -func=coverage.out | awk -v target=80.0% \
'/^total:/ { print "Total coverage: " $$3 " Minimum coverage: " target; if ($$3+0.0 >= target+0.0) print "ok"; else { print "fail"; exit 1; } }' '/^total:/ { print "Total coverage: " $$3 " Minimum coverage: " target; if ($$3+0.0 >= target+0.0) print "ok"; else { print "fail"; exit 1; } }'
@@ -39,7 +46,7 @@ test:
install-hooks: install-hooks:
pre-commit install --install-hooks pre-commit install --install-hooks
# Checks files for encryption # Runs pre-commit checks on files
.PHONY: check .PHONY: check
check: check:
pre-commit run --all-files pre-commit run --all-files
@@ -47,9 +54,8 @@ check:
.PHONY: clean .PHONY: clean
clean: clean:
rm -f ./minitor rm -f ./minitor
rm -f ./minitor-linux-*
rm -f ./minitor-darwin-amd64
rm -f ./coverage.out rm -f ./coverage.out
rm -fr ./dist
.PHONY: docker-build .PHONY: docker-build
docker-build: docker-build:
@@ -60,35 +66,23 @@ docker-run: docker-build
docker run --rm -v $(shell pwd)/config.yml:/root/config.yml $(DOCKER_TAG) docker run --rm -v $(shell pwd)/config.yml:/root/config.yml $(DOCKER_TAG)
## Multi-arch targets ## Multi-arch targets
$(TARGETS): $(GOFILES)
mkdir -p ./dist
GOOS=$(word 2, $(subst -, ,$(@))) GOARCH=$(word 3, $(subst -, ,$(@))) CGO_ENABLED=0 \
go build -ldflags '-X "main.version=${VERSION}"' -a -installsuffix nocgo \
-o $@
# Arch specific go build targets .PHONY: $(TARGET_ALIAS)
minitor-darwin-amd64: $(TARGET_ALIAS):
GOOS=darwin GOARCH=amd64 CGO_ENABLED=0 \ $(MAKE) $(addprefix dist/,$@)
go build -ldflags '-X "main.version=${VERSION}"' -a -installsuffix nocgo \
-o minitor-darwin-amd64
minitor-linux-amd64:
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 \
go build -ldflags '-X "main.version=${VERSION}"' -a -installsuffix nocgo \
-o minitor-linux-amd64
minitor-linux-arm:
GOOS=linux GOARCH=arm CGO_ENABLED=0 \
go build -ldflags '-X "main.version=${VERSION}"' -a -installsuffix nocgo \
-o minitor-linux-arm
minitor-linux-arm64:
GOOS=linux GOARCH=arm64 CGO_ENABLED=0 \
go build -ldflags '-X "main.version=${VERSION}"' -a -installsuffix nocgo \
-o minitor-linux-arm64
# Arch specific docker build targets # Arch specific docker build targets
.PHONY: docker-build-arm .PHONY: docker-build-arm
docker-build-arm: minitor-linux-arm docker-build-arm: dist/minitor-linux-arm
docker build --build-arg REPO=arm32v7 --build-arg ARCH=arm . -t ${DOCKER_TAG}-linux-arm docker build --build-arg REPO=arm32v7 --build-arg ARCH=arm . -t ${DOCKER_TAG}-linux-arm
.PHONY: docker-build-arm .PHONY: docker-build-arm64
docker-build-arm64: minitor-linux-arm64 docker-build-arm64: dist/minitor-linux-arm64
docker build --build-arg REPO=arm64v8 --build-arg ARCH=arm64 . -t ${DOCKER_TAG}-linux-arm64 docker build --build-arg REPO=arm64v8 --build-arg ARCH=arm64 . -t ${DOCKER_TAG}-linux-arm64
# Cross run on host architechture # Cross run on host architechture
+1
View File
@@ -93,6 +93,7 @@ Also, when alerts are executed, they will be passed through Go's format function
|`{{.LastCheckOutput}}`|The last returned value from the check command to either stderr or stdout| |`{{.LastCheckOutput}}`|The last returned value from the check command to either stderr or stdout|
|`{{.LastSuccess}}`|The ISO datetime of the last successful check| |`{{.LastSuccess}}`|The ISO datetime of the last successful check|
|`{{.MonitorName}}`|The name of the monitor that failed and triggered the alert| |`{{.MonitorName}}`|The name of the monitor that failed and triggered the alert|
|`{{.IsUp}}`|Indicates if the monitor that is alerting is up or not. Can be used in a conditional message template|
### Metrics ### Metrics
+2 -2
View File
@@ -55,7 +55,7 @@ func (alert *Alert) BuildTemplates() error {
cmdPart = legacy.Replace(cmdPart) cmdPart = legacy.Replace(cmdPart)
} }
alert.commandTemplate = append(alert.commandTemplate, template.Must( alert.commandTemplate = append(alert.commandTemplate, template.Must(
template.New(alert.Name+string(i)).Parse(cmdPart), template.New(alert.Name+fmt.Sprint(i)).Parse(cmdPart),
)) ))
} }
} else if alert.commandShellTemplate == nil && alert.Command.ShellCommand != "" { } else if alert.commandShellTemplate == nil && alert.Command.ShellCommand != "" {
@@ -124,7 +124,7 @@ func NewLogAlert() *Alert {
Command: CommandOrShell{ Command: CommandOrShell{
Command: []string{ Command: []string{
"echo", "echo",
"{{.MonitorName}} check has failed {{.FailureCount}} times", "{{.MonitorName}} {{if .IsUp}}has recovered{{else}}check has failed {{.FailureCount}} times{{end}}",
}, },
}, },
} }
+18
View File
@@ -76,6 +76,24 @@ func TestAlertSend(t *testing.T) {
"Command shell with legacy template", "Command shell with legacy template",
true, true,
}, },
// Test default log alert down
{
*NewLogAlert(),
AlertNotice{MonitorName: "Test", FailureCount: 1, IsUp: false},
"Test check has failed 1 times\n",
false,
"Default log alert down",
false,
},
// Test default log alert up
{
*NewLogAlert(),
AlertNotice{MonitorName: "Test", IsUp: true},
"Test has recovered\n",
false,
"Default log alert up",
false,
},
} }
for _, c := range cases { for _, c := range cases {
+1 -1
View File
@@ -33,7 +33,7 @@ func checkMonitors(config *Config) error {
hasAlert := alertNotice != nil hasAlert := alertNotice != nil
// Track status metrics // Track status metrics
Metrics.SetMonitorStatus(monitor.Name, success) Metrics.SetMonitorStatus(monitor.Name, monitor.IsUp())
Metrics.CountCheck(monitor.Name, success, hasAlert) Metrics.CountCheck(monitor.Name, success, hasAlert)
// Should probably consider refactoring everything below here // Should probably consider refactoring everything below here
+3 -2
View File
@@ -85,12 +85,13 @@ func (monitor *Monitor) Check() (bool, *AlertNotice) {
return isSuccess, alertNotice return isSuccess, alertNotice
} }
func (monitor Monitor) isUp() bool { // IsUp returns the status of the current monitor
func (monitor Monitor) IsUp() bool {
return monitor.alertCount == 0 return monitor.alertCount == 0
} }
func (monitor *Monitor) success() (notice *AlertNotice) { func (monitor *Monitor) success() (notice *AlertNotice) {
if !monitor.isUp() { if !monitor.IsUp() {
// Alert that we have recovered // Alert that we have recovered
notice = monitor.createAlertNotice(true) notice = monitor.createAlertNotice(true)
} }
+3 -3
View File
@@ -56,7 +56,7 @@ func TestMonitorShouldCheck(t *testing.T) {
} }
} }
// TestMonitorIsUp tests the Monitor.isUp() // TestMonitorIsUp tests the Monitor.IsUp()
func TestMonitorIsUp(t *testing.T) { func TestMonitorIsUp(t *testing.T) {
cases := []struct { cases := []struct {
monitor Monitor monitor Monitor
@@ -71,9 +71,9 @@ func TestMonitorIsUp(t *testing.T) {
for _, c := range cases { for _, c := range cases {
log.Printf("Testing case %s", c.name) log.Printf("Testing case %s", c.name)
actual := c.monitor.isUp() actual := c.monitor.IsUp()
if actual != c.expected { if actual != c.expected {
t.Errorf("isUp(%v), expected=%t actual=%t", c.name, c.expected, actual) t.Errorf("IsUp(%v), expected=%t actual=%t", c.name, c.expected, actual)
log.Printf("Case failed: %s", c.name) log.Printf("Case failed: %s", c.name)
} }
log.Println("-----") log.Println("-----")
+15 -3
View File
@@ -11,6 +11,7 @@ set -e
# To override, export DOCKER_HOST to a new hostname # To override, export DOCKER_HOST to a new hostname
DOCKER_HOST="${DOCKER_HOST:=socket}" DOCKER_HOST="${DOCKER_HOST:=socket}"
container_name="$1" container_name="$1"
num_log_lines="$2"
# Curls Docker either using a socket or URL # Curls Docker either using a socket or URL
function curl_docker { function curl_docker {
@@ -31,21 +32,32 @@ function get_container_id {
# Returns container JSON # Returns container JSON
function inspect_container { function inspect_container {
local container_id=$1 local container_id="$1"
curl_docker "containers/$container_id/json" curl_docker "containers/$container_id/json"
} }
# Gets some lines from docker log
function get_logs {
container_id="$1"
num_lines="$2"
curl_docker "containers/$container_id/logs?stdout=1&stderr=1" | tail -n "$num_lines"
}
if [ -z "$container_name" ]; then if [ -z "$container_name" ]; then
echo "Usage: $0 container_name" echo "Usage: $0 container_name [num_log_lines]"
echo "Will exit with the last status code of continer with provided name" echo "Will exit with the last status code of continer with provided name"
exit 1 exit 1
fi fi
container_id=$(get_container_id $container_name) container_id=$(get_container_id "$container_name")
if [ -z "$container_id" ]; then if [ -z "$container_id" ]; then
echo "ERROR: Could not find container with name: $container_name" echo "ERROR: Could not find container with name: $container_name"
exit 1 exit 1
fi fi
exit_code=$(inspect_container "$container_id" | jq -r .State.ExitCode) exit_code=$(inspect_container "$container_id" | jq -r .State.ExitCode)
if [ -n "$num_log_lines" ]; then
get_logs "$container_id" "$num_log_lines"
fi
exit "$exit_code" exit "$exit_code"
+13 -1
View File
@@ -11,6 +11,7 @@ set -e
# To override, export DOCKER_HOST to a new hostname # To override, export DOCKER_HOST to a new hostname
DOCKER_HOST="${DOCKER_HOST:=socket}" DOCKER_HOST="${DOCKER_HOST:=socket}"
container_name="$1" container_name="$1"
num_log_lines="$2"
# Curls Docker either using a socket or URL # Curls Docker either using a socket or URL
function curl_docker { function curl_docker {
@@ -35,8 +36,15 @@ function inspect_container {
curl_docker "containers/$container_id/json" curl_docker "containers/$container_id/json"
} }
# Gets some lines from docker log
function get_logs {
container_id="$1"
num_lines="$2"
curl_docker "containers/$container_id/logs?stdout=1&stderr=1" | tail -n "$num_lines"
}
if [ -z "$container_name" ]; then if [ -z "$container_name" ]; then
echo "Usage: $0 container_name" echo "Usage: $0 container_name [num_log_lines]"
echo "Will return results of healthcheck for continer with provided name" echo "Will return results of healthcheck for continer with provided name"
exit 1 exit 1
fi fi
@@ -48,6 +56,10 @@ if [ -z "$container_id" ]; then
fi fi
health=$(inspect_container "$container_id" | jq -r '.State.Health.Status') health=$(inspect_container "$container_id" | jq -r '.State.Health.Status')
if [ -n "$num_log_lines" ]; then
get_logs "$container_id" "$num_log_lines"
fi
case "$health" in case "$health" in
null) null)
echo "No healthcheck results" echo "No healthcheck results"