mirror of https://github.com/statping/statping
new
parent
6dc81e6849
commit
3866da7aad
|
@ -18,7 +18,7 @@ services:
|
|||
|
||||
env:
|
||||
global:
|
||||
- VERSION=0.27.8
|
||||
- VERSION=0.27.81
|
||||
- DB_HOST=localhost
|
||||
- DB_USER=travis
|
||||
- DB_PASS=
|
||||
|
|
|
@ -20,9 +20,9 @@ curl -s -X POST \
|
|||
-d "$body" \
|
||||
https://api.travis-ci.com/repo/hunterlong%2Fhomebrew-statup/requests
|
||||
|
||||
if [ "$TRAVIS_BRANCH" == "master" ]
|
||||
then
|
||||
curl -X POST $DOCKER > /dev/null
|
||||
else
|
||||
curl -H "Content-Type: application/json" --data '{"source_type": "Tag", "source_name": "v'"$VERSION"'"}' -X POST $DOCKER > /dev/null
|
||||
fi
|
||||
#if [ "$TRAVIS_BRANCH" == "master" ]
|
||||
#then
|
||||
# curl -X POST $DOCKER > /dev/null
|
||||
#else
|
||||
# curl -H "Content-Type: application/json" --data '{"source_type": "Tag", "source_name": "v'"$VERSION"'"}' -X POST $DOCKER > /dev/null
|
||||
#fi
|
|
@ -1,6 +1,6 @@
|
|||
FROM alpine:latest
|
||||
|
||||
ENV VERSION=v0.27.8
|
||||
ENV VERSION=v0.27.81
|
||||
|
||||
RUN apk --no-cache add libstdc++ ca-certificates
|
||||
RUN wget -q https://github.com/hunterlong/statup/releases/download/$VERSION/statup-linux-alpine.tar.gz && \
|
||||
|
|
|
@ -96,10 +96,11 @@ aws ec2 run-instances \
|
|||
```
|
||||
|
||||
## Prometheus Exporter
|
||||
Statup includes a prometheus exporter so you can have even more monitoring power with your services. The prometheus exporter can be seen on `/metrics`, simply create another exporter in your prometheus config.
|
||||
Statup includes a prometheus exporter so you can have even more monitoring power with your services. The prometheus exporter can be seen on `/metrics`, simply create another exporter in your prometheus config. Use your Statup API Secret for the Authorization Bearer header, the `/metrics` URL is dedicated for Prometheus and requires the correct API Secret has `Authorization` header.
|
||||
```yaml
|
||||
scrape_configs:
|
||||
- job_name: 'statup'
|
||||
bearer_token: MY API SECRET HERE
|
||||
static_configs:
|
||||
- targets: ['statup:8080']
|
||||
```
|
||||
|
|
|
@ -116,18 +116,17 @@ func (c *DbConfig) Save() error {
|
|||
DropDatabase()
|
||||
CreateDatabase()
|
||||
|
||||
newCore := Core{
|
||||
newCore := &Core{
|
||||
Name: c.Project,
|
||||
Description: c.Description,
|
||||
Config: "config.yml",
|
||||
ApiKey: utils.NewSHA1Hash(5),
|
||||
ApiSecret: utils.NewSHA1Hash(10),
|
||||
ApiKey: utils.NewSHA1Hash(9),
|
||||
ApiSecret: utils.NewSHA1Hash(16),
|
||||
Domain: c.Domain,
|
||||
}
|
||||
|
||||
col := DbSession.Collection("core")
|
||||
_, err = col.Insert(newCore)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
@ -104,6 +104,21 @@ type DateScan struct {
|
|||
Value int64 `json:"y"`
|
||||
}
|
||||
|
||||
func (s *Service) SmallText() string {
|
||||
last := s.LimitedFailures()
|
||||
hits, _ := s.LimitedHits()
|
||||
if !s.Online {
|
||||
return fmt.Sprintf("%v at %v", last[0].ParseError(), last[0].CreatedAt.Format("Monday 3:04PM, Jan _2 2006"))
|
||||
} else {
|
||||
if len(last) == 0 {
|
||||
return fmt.Sprintf("Online since %v", s.CreatedAt.Format("Monday 3:04PM, Jan _2 2006"))
|
||||
} else {
|
||||
return fmt.Sprintf("Online, last failure was %v", hits[0].CreatedAt.Format("Monday 3:04PM, Jan _2 2006"))
|
||||
}
|
||||
}
|
||||
return fmt.Sprintf("No Failures in the last 24 hours! %v", hits[0])
|
||||
}
|
||||
|
||||
func (s *Service) GraphData() string {
|
||||
var d []DateScan
|
||||
increment := "minute"
|
||||
|
|
|
@ -3,12 +3,24 @@ package handlers
|
|||
import (
|
||||
"fmt"
|
||||
"github.com/hunterlong/statup/core"
|
||||
"github.com/hunterlong/statup/utils"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func PrometheusHandler(w http.ResponseWriter, r *http.Request) {
|
||||
fmt.Printf("Prometheus /metrics Request From IP: %v\n", r.RemoteAddr)
|
||||
utils.Log(1, fmt.Sprintf("Prometheus /metrics Request From IP: %v\n", r.RemoteAddr))
|
||||
var token string
|
||||
tokens, ok := r.Header["Authorization"]
|
||||
if ok && len(tokens) >= 1 {
|
||||
token = tokens[0]
|
||||
token = strings.TrimPrefix(token, "Bearer ")
|
||||
}
|
||||
if token != core.CoreApp.ApiSecret {
|
||||
http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
metrics := []string{}
|
||||
system := fmt.Sprintf("statup_total_failures %v\n", core.CountFailures())
|
||||
system += fmt.Sprintf("statup_total_services %v", len(core.CoreApp.Services))
|
||||
|
|
|
@ -52,7 +52,7 @@ func Router() *mux.Router {
|
|||
r.Handle("/api/services/{id}", http.HandlerFunc(ApiServiceUpdateHandler)).Methods("POST")
|
||||
r.Handle("/api/users", http.HandlerFunc(ApiAllUsersHandler))
|
||||
r.Handle("/api/users/{id}", http.HandlerFunc(ApiUserHandler))
|
||||
r.Handle("/metrics", http.HandlerFunc(PrometheusHandler)).Methods("GET")
|
||||
r.Handle("/metrics", http.HandlerFunc(PrometheusHandler))
|
||||
Store = sessions.NewCookieStore([]byte("secretinfo"))
|
||||
return r
|
||||
}
|
||||
|
|
|
@ -82,7 +82,7 @@
|
|||
{{ end }}
|
||||
<div class="lower_canvas full-col-12 text-white{{if not .Online}} bg-danger{{end}}">
|
||||
<div class="col-12">
|
||||
<span>No failures within the last 25 days</span>
|
||||
<span>{{.SmallText}}</span>
|
||||
<a href="/service/{{ .Id }}" class="btn {{if .Online}}btn-success{{else}}btn-danger{{end}} btn-sm float-right">View Service</a>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -64,6 +64,17 @@
|
|||
|
||||
<button type="submit" class="btn btn-primary btn-block">Save Settings</button>
|
||||
|
||||
|
||||
<div class="form-group">
|
||||
<label for="formGroupExampleInput">API Key</label>
|
||||
<input type="text" name="description" class="form-control" value="{{ .ApiKey }}" id="formGroupExampleInput" readonly>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="formGroupExampleInput">API Secret</label>
|
||||
<input type="text" name="description" class="form-control" value="{{ .ApiSecret }}" id="formGroupExampleInput" readonly>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
|
||||
</div>
|
||||
|
|
|
@ -52,53 +52,25 @@
|
|||
|
||||
<canvas id="service" width="400" height="120"></canvas>
|
||||
|
||||
{{ range .Failures }}
|
||||
<blockquote class="blockquote text-right mt-3">
|
||||
<p class="mb-0">{{.ParseError}}</p>
|
||||
<footer class="blockquote-footer">Reported <cite title="Source Title">{{.Ago}}</cite></footer>
|
||||
</blockquote>
|
||||
{{ end }}
|
||||
{{ if .LimitedFailures }}
|
||||
<div class="list-group mt-5">
|
||||
{{ range .LimitedFailures }}
|
||||
<a href="#" class="list-group-item list-group-item-action flex-column align-items-start">
|
||||
<div class="d-flex w-100 justify-content-between">
|
||||
<h5 class="mb-1">{{.ParseError}}</h5>
|
||||
<small>Reported {{.Ago}}</small>
|
||||
</div>
|
||||
<p class="mb-1">{{.Issue}}</p>
|
||||
</a>
|
||||
{{ end }}
|
||||
</div>
|
||||
{{ end }}
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
{{if Auth}}
|
||||
|
||||
<div class="col-12 mt-4">
|
||||
|
||||
<h3>Service Checkins</h3>
|
||||
|
||||
{{ range .Checkins }}
|
||||
|
||||
<div class="col-12 mt-3">
|
||||
|
||||
<h5>Check #{{.Id}} <span class="badge online_badge float-right">Checked in {{.Ago}}</span></h5>
|
||||
|
||||
<input type="text" class="form-control" value="https://domainhere.com/api/checkin/{{.Api}}">
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
{{ end }}
|
||||
|
||||
<form action="/service/{{.Id}}/checkin" method="POST">
|
||||
<div class="form-group row">
|
||||
<label for="service_name" class="col-sm-4 col-form-label">Check Interval (in seconds)</label>
|
||||
<div class="col-sm-8">
|
||||
<input type="number" name="name" class="form-control" id="checkin_interval" value="30" placeholder="Name">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<div class="col-sm-10">
|
||||
<button type="submit" class="btn btn-success">Save Checkin</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div class="col-12 mt-4">
|
||||
|
||||
<h3>Edit Service</h3>
|
||||
|
@ -186,19 +158,37 @@
|
|||
{{end}}
|
||||
|
||||
|
||||
{{ if .LimitedFailures }}
|
||||
<div class="list-group mt-5">
|
||||
{{ range .LimitedFailures }}
|
||||
<a href="#" class="list-group-item list-group-item-action flex-column align-items-start">
|
||||
<div class="d-flex w-100 justify-content-between">
|
||||
<h5 class="mb-1">{{.ParseError}}</h5>
|
||||
<small>Reported {{.Ago}}</small>
|
||||
</div>
|
||||
<p class="mb-1">{{.Issue}}</p>
|
||||
</a>
|
||||
{{ end }}
|
||||
<div class="col-12 mt-4">
|
||||
<h3>Service Checkins</h3>
|
||||
|
||||
{{ range .Checkins }}
|
||||
|
||||
<h5>Check #{{.Id}} <span class="badge online_badge float-right">Checked in {{.Ago}}</span></h5>
|
||||
|
||||
<input type="text" class="form-control" value="https://domainhere.com/api/checkin/{{.Api}}">
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
{{ end }}
|
||||
|
||||
|
||||
<form action="/service/{{.Id}}/checkin" method="POST">
|
||||
<div class="form-group row">
|
||||
<label for="service_name" class="col-sm-4 col-form-label">Check Interval (in seconds)</label>
|
||||
<div class="col-sm-8">
|
||||
<input type="number" name="name" class="form-control" id="checkin_interval" value="30" placeholder="Name">
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
||||
<div class="form-group row">
|
||||
<div class="col-sm-10">
|
||||
<button type="submit" class="btn btn-success">Save Checkin</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
|
Loading…
Reference in New Issue