mirror of https://github.com/statping/statping
PR merges, version bump, removed internal cache, removed unused http server complexities
parent
1a56afe7f7
commit
a03f93b433
|
@ -1,3 +1,10 @@
|
|||
# 0.90.73 (12-15-2020)
|
||||
- Removed complexity in code for http server
|
||||
- Removed internal cache functionality (not useful, needs refactor)
|
||||
- Merged PR https://github.com/statping/statping/pull/909
|
||||
- Merged PR https://github.com/statping/statping/pull/880
|
||||
- Merged PR https://github.com/statping/statping/pull/859
|
||||
|
||||
# 0.90.72 (10-28-2020)
|
||||
- Fixed issue with graphs becoming stuck on reload
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[defaults]
|
||||
org=Statping
|
||||
project=statping_frontend
|
||||
project=frontend
|
||||
url=https://sentry.statping.com
|
||||
|
||||
[auth]
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
"@fortawesome/vue-fontawesome": "^0.1.9",
|
||||
"@sentry/browser": "^5.20.1",
|
||||
"@sentry/integrations": "^5.20.1",
|
||||
"@sentry/tracing": "^5.29.0",
|
||||
"@sentry/vue": "^5.29.0",
|
||||
"apexcharts": "^3.6.6",
|
||||
"axios": "^0.19.1",
|
||||
"codemirror-colorpicker": "^1.9.66",
|
||||
|
|
|
@ -200,14 +200,6 @@ class Api {
|
|||
return axios.get('api/renew').then(response => (response.data))
|
||||
}
|
||||
|
||||
async cache() {
|
||||
return axios.get('api/cache').then(response => (response.data))
|
||||
}
|
||||
|
||||
async clearCache() {
|
||||
return axios.get('api/clear_cache').then(response => (response.data))
|
||||
}
|
||||
|
||||
async logs() {
|
||||
return axios.get('api/logs').then(response => (response.data)) || []
|
||||
}
|
||||
|
|
|
@ -1,53 +0,0 @@
|
|||
<template>
|
||||
<div class="card mb-5">
|
||||
<div class="card-header">Cache</div>
|
||||
<div class="card-body">
|
||||
<span v-if="!cache" class="text-muted">There are no cached pages yet!</span>
|
||||
<table v-if="cache" class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">URL</th>
|
||||
<th scope="col">Size</th>
|
||||
<th scope="col">Expiration</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
<tr v-for="(cache, index) in cache">
|
||||
<td>{{cache.url}}</td>
|
||||
<td>{{cache.size}}</td>
|
||||
<td>{{ago(cache.expiration)}}</td>
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
<button v-if="cache" @click.prevent="clearCache" class="btn btn-danger btn-block">Clear Cache</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Api from "../../API";
|
||||
|
||||
export default {
|
||||
name: 'Cache',
|
||||
data() {
|
||||
return {
|
||||
cache: [],
|
||||
}
|
||||
},
|
||||
async mounted() {
|
||||
this.cache = await Api.cache()
|
||||
},
|
||||
methods: {
|
||||
async clearCache() {
|
||||
await Api.clearCache()
|
||||
this.cache = []
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
||||
<style scoped>
|
||||
</style>
|
|
@ -6,14 +6,14 @@ import VueClipboard from 'vue-clipboard2'
|
|||
import VueCookies from 'vue-cookies'
|
||||
import VueI18n from 'vue-i18n'
|
||||
import * as Sentry from "@sentry/browser";
|
||||
import * as Integrations from "@sentry/integrations";
|
||||
import { Integrations as TracingIntegrations } from "@sentry/tracing";
|
||||
import router from './routes'
|
||||
import "./mixin"
|
||||
import "./icons"
|
||||
import store from './store'
|
||||
import language from './languages'
|
||||
|
||||
const errorReporter = "https://bed4d75404924cb3a799e370733a1b64@sentry.statping.com/3"
|
||||
const errorReporter = "https://f674a4b91578476a99809f1dea56b63b@sentry.statping.com/3"
|
||||
|
||||
const App = () => import(/* webpackChunkName: "index" */ '@/App.vue')
|
||||
|
||||
|
@ -33,8 +33,11 @@ const i18n = new VueI18n({
|
|||
Vue.$cookies.config('3d')
|
||||
|
||||
Sentry.init({
|
||||
Vue: Vue,
|
||||
dsn: errorReporter,
|
||||
integrations: [new Integrations.Vue({Vue, attachProps: true, logErrors: true})],
|
||||
integrations: [new TracingIntegrations.BrowserTracing()],
|
||||
tracesSampleRate: 0.2,
|
||||
environment: process.env.NODE_ENV === 'production' ? 'production' : 'development',
|
||||
});
|
||||
|
||||
Vue.config.productionTip = process.env.NODE_ENV !== 'production'
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
|
||||
<script>
|
||||
import Api from "@/API";
|
||||
|
||||
const Group = () => import(/* webpackChunkName: "index" */ '@/components/Index/Group')
|
||||
const Header = () => import(/* webpackChunkName: "index" */ '@/components/Index/Header')
|
||||
const MessageBlock = () => import(/* webpackChunkName: "index" */ '@/components/Index/MessageBlock')
|
||||
|
@ -63,9 +64,7 @@ export default {
|
|||
},
|
||||
computed: {
|
||||
loading_text() {
|
||||
if (!this.$store.getters.core.version) {
|
||||
return "Loading Core"
|
||||
} else if (this.$store.getters.groups.length === 0) {
|
||||
if (this.$store.getters.groups.length === 0) {
|
||||
return "Loading Groups"
|
||||
} else if (this.$store.getters.services.length === 0) {
|
||||
return "Loading Services"
|
||||
|
@ -74,7 +73,7 @@ export default {
|
|||
}
|
||||
},
|
||||
loaded() {
|
||||
return this.$store.getters.core.version && this.$store.getters.services.length !== 0
|
||||
return this.$store.getters.services.length !== 0
|
||||
},
|
||||
core() {
|
||||
return this.$store.getters.core
|
||||
|
|
|
@ -24,9 +24,6 @@
|
|||
<a @click.prevent="changeTab" class="nav-link" v-bind:class="{active: liClass('v-pills-style-tab')}" id="v-pills-style-tab" data-toggle="pill" href="#v-pills-style" role="tab" aria-controls="v-pills-style" aria-selected="false">
|
||||
<font-awesome-icon icon="image" class="mr-2"/> {{ $t('theme') }}
|
||||
</a>
|
||||
<a @click.prevent="changeTab" class="nav-link" v-bind:class="{active: liClass('v-pills-cache-tab')}" id="v-pills-cache-tab" data-toggle="pill" href="#v-pills-cache" role="tab" aria-controls="v-pills-cache" aria-selected="false">
|
||||
<font-awesome-icon icon="paperclip" class="mr-2"/> {{ $t('cache') }}
|
||||
</a>
|
||||
<a @click.prevent="changeTab" class="nav-link" v-bind:class="{active: liClass('v-pills-oauth-tab')}" id="v-pills-oauth-tab" data-toggle="pill" href="#v-pills-oauth" role="tab" aria-controls="v-pills-oauth" aria-selected="false">
|
||||
<font-awesome-icon icon="key" class="mr-2"/> {{ $t('authentication') }}
|
||||
</a>
|
||||
|
@ -110,10 +107,6 @@
|
|||
<ThemeEditor/>
|
||||
</div>
|
||||
|
||||
<div class="tab-pane fade" v-bind:class="{active: liClass('v-pills-cache-tab'), show: liClass('v-pills-cache-tab')}" id="v-pills-cache" role="tabpanel" aria-labelledby="v-pills-cache-tab">
|
||||
<Cache/>
|
||||
</div>
|
||||
|
||||
<div class="tab-pane fade" v-bind:class="{active: liClass('v-pills-oauth-tab'), show: liClass('v-pills-oauth-tab')}" id="v-pills-oauth" role="tabpanel" aria-labelledby="v-pills-oauth-tab">
|
||||
<OAuth/>
|
||||
</div>
|
||||
|
@ -150,7 +143,6 @@
|
|||
const Notifier = () => import(/* webpackChunkName: "dashboard" */ '@/forms/Notifier')
|
||||
const OAuth = () => import(/* webpackChunkName: "dashboard" */ '@/forms/OAuth')
|
||||
const ThemeEditor = () => import(/* webpackChunkName: "dashboard" */ '@/components/Dashboard/ThemeEditor')
|
||||
const Cache = () => import(/* webpackChunkName: "dashboard" */ '@/components/Dashboard/Cache')
|
||||
const Importer = () => import(/* webpackChunkName: "dashboard" */ '@/components/Dashboard/Importer')
|
||||
const Variables = () => import(/* webpackChunkName: "dashboard" */ '@/components/Dashboard/Variables')
|
||||
const Configs = () => import(/* webpackChunkName: "dashboard" */ '@/components/Dashboard/Configs')
|
||||
|
@ -162,7 +154,6 @@
|
|||
Importer,
|
||||
Variables,
|
||||
OAuth,
|
||||
Cache,
|
||||
ThemeEditor,
|
||||
FormIntegration,
|
||||
Notifier,
|
||||
|
@ -196,7 +187,6 @@
|
|||
},
|
||||
methods: {
|
||||
async update() {
|
||||
this.cache = await Api.cache()
|
||||
await this.getGithub()
|
||||
},
|
||||
async getGithub() {
|
||||
|
|
|
@ -1094,6 +1094,16 @@
|
|||
"@nodelib/fs.scandir" "2.1.3"
|
||||
fastq "^1.6.0"
|
||||
|
||||
"@sentry/browser@5.29.0":
|
||||
version "5.29.0"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-5.29.0.tgz#a8cab91729c759c456bd2254cef65bafa5cdc4ea"
|
||||
integrity sha512-kRlt1mE2wrYjspnIupNnPxqsUrRuy02SuXhbpP7J6uu8QasoEmJ78hk0hHz4jOZRmuWwfs2zIXD4tLGgWOKq8A==
|
||||
dependencies:
|
||||
"@sentry/core" "5.29.0"
|
||||
"@sentry/types" "5.29.0"
|
||||
"@sentry/utils" "5.29.0"
|
||||
tslib "^1.9.3"
|
||||
|
||||
"@sentry/browser@^5.20.1":
|
||||
version "5.20.1"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-5.20.1.tgz#be59522d0914d58309e1367d997d4b3cd5385d7e"
|
||||
|
@ -1115,6 +1125,17 @@
|
|||
"@sentry/utils" "5.20.1"
|
||||
tslib "^1.9.3"
|
||||
|
||||
"@sentry/core@5.29.0":
|
||||
version "5.29.0"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/core/-/core-5.29.0.tgz#4410ca0dc5785abf3df02fa23c18e83ad90d7cda"
|
||||
integrity sha512-a1sZBJ2u3NG0YDlGvOTwUCWiNjhfmDtAQiKK1o6RIIbcrWy9TlSps7CYDkBP239Y3A4pnvohjEEKEP3v3L3LZQ==
|
||||
dependencies:
|
||||
"@sentry/hub" "5.29.0"
|
||||
"@sentry/minimal" "5.29.0"
|
||||
"@sentry/types" "5.29.0"
|
||||
"@sentry/utils" "5.29.0"
|
||||
tslib "^1.9.3"
|
||||
|
||||
"@sentry/hub@5.20.1":
|
||||
version "5.20.1"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-5.20.1.tgz#05e83ba972a96e9d7225a64c7d3728aa9fcefc4e"
|
||||
|
@ -1124,6 +1145,15 @@
|
|||
"@sentry/utils" "5.20.1"
|
||||
tslib "^1.9.3"
|
||||
|
||||
"@sentry/hub@5.29.0":
|
||||
version "5.29.0"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-5.29.0.tgz#d018b978fdffc6c8261744b0d08e8d25a3f4dc58"
|
||||
integrity sha512-kcDPQsRG4cFdmqDh+TzjeO7lWYxU8s1dZYAbbl1J4uGKmhNB0J7I4ak4SGwTsXLY6fhbierxr6PRaoNojCxjPw==
|
||||
dependencies:
|
||||
"@sentry/types" "5.29.0"
|
||||
"@sentry/utils" "5.29.0"
|
||||
tslib "^1.9.3"
|
||||
|
||||
"@sentry/integrations@^5.20.1":
|
||||
version "5.20.1"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/integrations/-/integrations-5.20.1.tgz#c42dd53c2162b96bf4da641cd1c2bd53c0bbdce3"
|
||||
|
@ -1142,11 +1172,36 @@
|
|||
"@sentry/types" "5.20.1"
|
||||
tslib "^1.9.3"
|
||||
|
||||
"@sentry/minimal@5.29.0":
|
||||
version "5.29.0"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/minimal/-/minimal-5.29.0.tgz#bd8b52f388abcec2234dbbc6d6721ff65aa30e35"
|
||||
integrity sha512-nhXofdjtO41/caiF1wk1oT3p/QuhOZDYdF/b29DoD2MiAMK9IjhhOXI/gqaRpDKkXlDvd95fDTcx4t/MqqcKXA==
|
||||
dependencies:
|
||||
"@sentry/hub" "5.29.0"
|
||||
"@sentry/types" "5.29.0"
|
||||
tslib "^1.9.3"
|
||||
|
||||
"@sentry/tracing@^5.29.0":
|
||||
version "5.29.0"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/tracing/-/tracing-5.29.0.tgz#8ed515b3f9d409137357c38c8622858f9e684e4a"
|
||||
integrity sha512-2ZITUH7Eur7IkmRAd5gw8Xt2Sfc28btCnT7o2P2J8ZPD65e99ATqjxXPokx0+6zEkTsstIDD3mbyuwkpbuvuTA==
|
||||
dependencies:
|
||||
"@sentry/hub" "5.29.0"
|
||||
"@sentry/minimal" "5.29.0"
|
||||
"@sentry/types" "5.29.0"
|
||||
"@sentry/utils" "5.29.0"
|
||||
tslib "^1.9.3"
|
||||
|
||||
"@sentry/types@5.20.1":
|
||||
version "5.20.1"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/types/-/types-5.20.1.tgz#ccc4fa4c9d0f94d93014b04e674762d5d5cd30a2"
|
||||
integrity sha512-OU+i/lcjGpDJv0XkNpsKrI2r1VPp8qX0H6Knq8NuZrlZe3AbvO3jRJJK0pH14xFv8Xok5jbZZpKKoQLxYfxqsw==
|
||||
|
||||
"@sentry/types@5.29.0":
|
||||
version "5.29.0"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/types/-/types-5.29.0.tgz#af5cec98cde54316c14df3121f0e8106e56b578e"
|
||||
integrity sha512-iDkxT/9sT3UF+Xb+JyLjZ5caMXsgLfRyV9VXQEiR2J6mgpMielj184d9jeF3bm/VMuAf/VFFqrHlcVsVgmrrMw==
|
||||
|
||||
"@sentry/utils@5.20.1":
|
||||
version "5.20.1"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-5.20.1.tgz#68cfae0d0e3b321b4649b59f30265024b29eae63"
|
||||
|
@ -1155,6 +1210,26 @@
|
|||
"@sentry/types" "5.20.1"
|
||||
tslib "^1.9.3"
|
||||
|
||||
"@sentry/utils@5.29.0":
|
||||
version "5.29.0"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-5.29.0.tgz#b4c1223ba362a94cf4850e9ca2cb24655b006b53"
|
||||
integrity sha512-b2B1gshw2u3EHlAi84PuI5sfmLKXW1z9enMMhNuuNT/CoRp+g5kMAcUv/qYTws7UNnYSvTuVGuZG30v1e0hP9A==
|
||||
dependencies:
|
||||
"@sentry/types" "5.29.0"
|
||||
tslib "^1.9.3"
|
||||
|
||||
"@sentry/vue@^5.29.0":
|
||||
version "5.29.0"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/vue/-/vue-5.29.0.tgz#606e0c7fe3e6860934eb19461d8fc6cf97b1a198"
|
||||
integrity sha512-AIlPWdC6uNhLcFUBFfvY2CblHSQK0IK7y+qdOKVhpQFNBz6zOEHleg98UEv4uVmXeKqmpESkIDeCcAP7MqCCyQ==
|
||||
dependencies:
|
||||
"@sentry/browser" "5.29.0"
|
||||
"@sentry/core" "5.29.0"
|
||||
"@sentry/minimal" "5.29.0"
|
||||
"@sentry/types" "5.29.0"
|
||||
"@sentry/utils" "5.29.0"
|
||||
tslib "^1.9.3"
|
||||
|
||||
"@soda/friendly-errors-webpack-plugin@^1.7.1":
|
||||
version "1.7.1"
|
||||
resolved "https://registry.yarnpkg.com/@soda/friendly-errors-webpack-plugin/-/friendly-errors-webpack-plugin-1.7.1.tgz#706f64bcb4a8b9642b48ae3ace444c70334d615d"
|
||||
|
|
|
@ -116,27 +116,6 @@ type cacheJson struct {
|
|||
Size int `json:"size"`
|
||||
}
|
||||
|
||||
func apiCacheHandler(w http.ResponseWriter, r *http.Request) {
|
||||
var cacheList []cacheJson
|
||||
for k, v := range CacheStorage.List() {
|
||||
cacheList = append(cacheList, cacheJson{
|
||||
URL: k,
|
||||
Expiration: time.Unix(0, v.Expiration).UTC(),
|
||||
Size: len(v.Content),
|
||||
})
|
||||
}
|
||||
returnJson(cacheList, w, r)
|
||||
}
|
||||
|
||||
func apiClearCacheHandler(w http.ResponseWriter, r *http.Request) {
|
||||
CacheStorage.StopRoutine()
|
||||
CacheStorage = NewStorage()
|
||||
output := apiResponse{
|
||||
Status: "success",
|
||||
}
|
||||
returnJson(output, w, r)
|
||||
}
|
||||
|
||||
func sendErrorJson(err error, w http.ResponseWriter, r *http.Request) {
|
||||
errCode := 0
|
||||
e, ok := err.(errors.Error)
|
||||
|
|
|
@ -8,7 +8,6 @@ import (
|
|||
"github.com/pkg/errors"
|
||||
_ "github.com/statping/statping/notifiers"
|
||||
"github.com/statping/statping/source"
|
||||
"github.com/statping/statping/types"
|
||||
"github.com/statping/statping/types/checkins"
|
||||
"github.com/statping/statping/types/core"
|
||||
"github.com/statping/statping/types/groups"
|
||||
|
@ -168,33 +167,6 @@ func TestMainApiRoutes(t *testing.T) {
|
|||
BeforeTest: SetTestENV,
|
||||
SecureRoute: true,
|
||||
},
|
||||
{
|
||||
Name: "Statping View Cache",
|
||||
URL: "/api/cache",
|
||||
Method: "GET",
|
||||
ExpectedStatus: 200,
|
||||
BeforeTest: SetTestENV,
|
||||
SecureRoute: true,
|
||||
ResponseLen: 0,
|
||||
},
|
||||
{
|
||||
Name: "Statping Clear Cache",
|
||||
URL: "/api/clear_cache",
|
||||
Method: "POST",
|
||||
ExpectedStatus: 200,
|
||||
SecureRoute: true,
|
||||
BeforeTest: func(t *testing.T) error {
|
||||
CacheStorage.Set("test", []byte("data here"), types.Day)
|
||||
list := CacheStorage.List()
|
||||
assert.Len(t, list, 1)
|
||||
return nil
|
||||
},
|
||||
AfterTest: func(t *testing.T) error {
|
||||
list := CacheStorage.List()
|
||||
assert.Len(t, list, 0)
|
||||
return nil
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "Update Core",
|
||||
URL: "/api/core",
|
||||
|
|
|
@ -1,122 +0,0 @@
|
|||
package handlers
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/statping/statping/utils"
|
||||
)
|
||||
|
||||
var CacheStorage Cacher
|
||||
|
||||
type Cacher interface {
|
||||
Get(key string) []byte
|
||||
Delete(key string)
|
||||
Set(key string, content []byte, duration time.Duration)
|
||||
List() map[string]Item
|
||||
Lock()
|
||||
Unlock()
|
||||
StopRoutine()
|
||||
}
|
||||
|
||||
// Item is a cached reference
|
||||
type Item struct {
|
||||
Content []byte
|
||||
Expiration int64
|
||||
}
|
||||
|
||||
// cleanRoutine is a go routine to automatically remove expired caches that haven't been hit recently
|
||||
func cleanRoutine(s *Storage) {
|
||||
duration := 60 * time.Second
|
||||
|
||||
CacheRoutine:
|
||||
for {
|
||||
select {
|
||||
case <-s.running:
|
||||
break CacheRoutine
|
||||
case <-time.After(duration):
|
||||
for k, v := range s.List() {
|
||||
if v.Expired() {
|
||||
s.Delete(k)
|
||||
}
|
||||
}
|
||||
duration = 60 * time.Second
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Expired returns true if the item has expired.
|
||||
func (item Item) Expired() bool {
|
||||
if item.Expiration == 0 {
|
||||
return false
|
||||
}
|
||||
return utils.Now().UnixNano() > item.Expiration
|
||||
}
|
||||
|
||||
//Storage mecanism for caching strings in memory
|
||||
type Storage struct {
|
||||
items map[string]Item
|
||||
mu *sync.RWMutex
|
||||
running chan bool
|
||||
}
|
||||
|
||||
//NewStorage creates a new in memory CacheStorage
|
||||
func NewStorage() *Storage {
|
||||
storage := &Storage{
|
||||
items: make(map[string]Item),
|
||||
mu: &sync.RWMutex{},
|
||||
running: make(chan bool),
|
||||
}
|
||||
go cleanRoutine(storage)
|
||||
return storage
|
||||
}
|
||||
|
||||
func (s Storage) StopRoutine() {
|
||||
close(s.running)
|
||||
}
|
||||
|
||||
func (s Storage) Lock() {
|
||||
s.mu.Lock()
|
||||
}
|
||||
|
||||
func (s Storage) Unlock() {
|
||||
s.mu.Unlock()
|
||||
}
|
||||
|
||||
func (s Storage) List() map[string]Item {
|
||||
return s.items
|
||||
}
|
||||
|
||||
//Get a cached content by key
|
||||
func (s Storage) Get(key string) []byte {
|
||||
item := s.items[key]
|
||||
if item.Expired() {
|
||||
s.Delete(key)
|
||||
return nil
|
||||
}
|
||||
return item.Content
|
||||
}
|
||||
|
||||
func (s Storage) Delete(key string) {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
delete(s.items, key)
|
||||
}
|
||||
|
||||
//Set a cached content by key
|
||||
func (s Storage) Set(key string, content []byte, duration time.Duration) {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
u, err := url.Parse(key)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if u.Query().Get("v") != "" {
|
||||
return
|
||||
}
|
||||
s.items[key] = Item{
|
||||
Content: content,
|
||||
Expiration: utils.Now().Add(duration).UnixNano(),
|
||||
}
|
||||
}
|
|
@ -15,7 +15,8 @@ import (
|
|||
|
||||
const (
|
||||
cookieName = "statping_auth"
|
||||
timeout = time.Second * 30
|
||||
|
||||
timeout = time.Second * 30
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -24,13 +25,10 @@ var (
|
|||
usingSSL bool
|
||||
mainTmpl = `{{define "main" }} {{ template "base" . }} {{ end }}`
|
||||
templates = []string{"base.gohtml"}
|
||||
httpError chan error
|
||||
)
|
||||
|
||||
func StopHTTPServer(err error) {
|
||||
log.Infoln("Stopping HTTP Server")
|
||||
httpError <- err
|
||||
close(httpError)
|
||||
}
|
||||
|
||||
// RunHTTPServer will start a HTTP server on a specific IP and port
|
||||
|
@ -54,21 +52,13 @@ func RunHTTPServer() error {
|
|||
|
||||
router = Router()
|
||||
resetCookies()
|
||||
httpError = make(chan error)
|
||||
|
||||
if utils.Params.GetBool("LETSENCRYPT_ENABLE") {
|
||||
go startLetsEncryptServer(ip)
|
||||
return startLetsEncryptServer(ip)
|
||||
} else if usingSSL {
|
||||
go startSSLServer(ip)
|
||||
return startSSLServer(ip)
|
||||
} else {
|
||||
go startServer(host)
|
||||
}
|
||||
|
||||
for {
|
||||
select {
|
||||
case err := <-httpError:
|
||||
return err
|
||||
}
|
||||
return startServer(host)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -25,18 +25,12 @@ func findIncident(r *http.Request) (*incidents.Incident, int64, error) {
|
|||
}
|
||||
|
||||
func apiServiceIncidentsHandler(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
id := vars["id"]
|
||||
if utils.NotNumber(id) {
|
||||
sendErrorJson(errors.NotNumber, w, r)
|
||||
service, err := findService(r)
|
||||
if err != nil {
|
||||
sendErrorJson(err, w, r)
|
||||
return
|
||||
}
|
||||
incids := incidents.FindByService(utils.ToInt(id))
|
||||
if incids == nil {
|
||||
sendErrorJson(errors.Missing(&incidents.Incident{}, id), w, r)
|
||||
return
|
||||
}
|
||||
returnJson(incids, w, r)
|
||||
returnJson(service.Incidents, w, r)
|
||||
}
|
||||
|
||||
func apiIncidentUpdatesHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
|
|
@ -13,9 +13,7 @@ import (
|
|||
"github.com/statping/statping/utils"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -139,36 +137,6 @@ func readOnly(handler http.Handler, redirect bool) http.Handler {
|
|||
})
|
||||
}
|
||||
|
||||
// cached is a middleware function that accepts a duration and content type and will cache the response of the original request
|
||||
func cached(duration, contentType string, handler func(w http.ResponseWriter, r *http.Request)) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
content := CacheStorage.Get(r.RequestURI)
|
||||
w.Header().Set("Content-Type", contentType)
|
||||
w.Header().Set("Access-Control-Allow-Origin", "*")
|
||||
if !core.App.Setup {
|
||||
handler(w, r)
|
||||
return
|
||||
}
|
||||
if content != nil {
|
||||
w.Write(content)
|
||||
} else {
|
||||
c := httptest.NewRecorder()
|
||||
handler(c, r)
|
||||
content := c.Body.Bytes()
|
||||
result := c.Result()
|
||||
if result.StatusCode != 200 {
|
||||
w.WriteHeader(result.StatusCode)
|
||||
w.Write(content)
|
||||
return
|
||||
}
|
||||
w.Write(content)
|
||||
if d, err := time.ParseDuration(duration); err == nil {
|
||||
go CacheStorage.Set(r.RequestURI, content, d)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// prometheusMiddleware implements mux.MiddlewareFunc.
|
||||
func prometheusMiddleware(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
|
|
|
@ -27,7 +27,6 @@ func staticAssets(src string) http.Handler {
|
|||
// Server will use static assets if the 'assets' directory is found in the root directory.
|
||||
func Router() *mux.Router {
|
||||
dir := utils.Directory
|
||||
CacheStorage = NewStorage()
|
||||
|
||||
r := mux.NewRouter().StrictSlash(true)
|
||||
r.Use(prometheusMiddleware)
|
||||
|
@ -96,8 +95,6 @@ func Router() *mux.Router {
|
|||
api.Handle("/api/login", http.HandlerFunc(apiLoginHandler)).Methods("POST")
|
||||
api.Handle("/api/logout", http.HandlerFunc(logoutHandler))
|
||||
api.Handle("/api/renew", authenticated(apiRenewHandler, false))
|
||||
api.Handle("/api/cache", authenticated(apiCacheHandler, false)).Methods("GET")
|
||||
api.Handle("/api/clear_cache", authenticated(apiClearCacheHandler, false))
|
||||
api.Handle("/api/core", authenticated(apiCoreHandler, false)).Methods("POST")
|
||||
api.Handle("/api/logs", authenticated(logsHandler, false)).Methods("GET")
|
||||
api.Handle("/api/logs/last", authenticated(logsLineHandler, false)).Methods("GET")
|
||||
|
@ -139,9 +136,9 @@ func Router() *mux.Router {
|
|||
api.Handle("/api/services/{id}/hits", authenticated(apiServiceHitsDeleteHandler, false)).Methods("DELETE")
|
||||
|
||||
// API SERVICE CHART DATA Routes
|
||||
api.Handle("/api/services/{id}/hits_data", cached("30s", "application/json", apiServiceDataHandler)).Methods("GET")
|
||||
api.Handle("/api/services/{id}/failure_data", cached("30s", "application/json", apiServiceFailureDataHandler)).Methods("GET")
|
||||
api.Handle("/api/services/{id}/ping_data", cached("30s", "application/json", apiServicePingDataHandler)).Methods("GET")
|
||||
api.Handle("/api/services/{id}/hits_data", http.HandlerFunc(apiServiceDataHandler)).Methods("GET")
|
||||
api.Handle("/api/services/{id}/failure_data", http.HandlerFunc(apiServiceFailureDataHandler)).Methods("GET")
|
||||
api.Handle("/api/services/{id}/ping_data", http.HandlerFunc(apiServicePingDataHandler)).Methods("GET")
|
||||
api.Handle("/api/services/{id}/uptime_data", http.HandlerFunc(apiServiceTimeDataHandler)).Methods("GET")
|
||||
|
||||
// API INCIDENTS Routes
|
||||
|
|
|
@ -10,7 +10,7 @@ import (
|
|||
"strings"
|
||||
)
|
||||
|
||||
func startServer(host string) {
|
||||
func startServer(host string) error {
|
||||
httpServer = &http.Server{
|
||||
Addr: host,
|
||||
WriteTimeout: timeout,
|
||||
|
@ -19,9 +19,7 @@ func startServer(host string) {
|
|||
Handler: router,
|
||||
}
|
||||
httpServer.SetKeepAlivesEnabled(false)
|
||||
if err := httpServer.ListenAndServe(); err != nil {
|
||||
httpError <- err
|
||||
}
|
||||
return httpServer.ListenAndServe()
|
||||
}
|
||||
|
||||
func letsEncryptCert() (*tls.Config, error) {
|
||||
|
@ -63,14 +61,13 @@ func letsEncryptCert() (*tls.Config, error) {
|
|||
return tlsconf, nil
|
||||
}
|
||||
|
||||
func startLetsEncryptServer(ip string) {
|
||||
func startLetsEncryptServer(ip string) error {
|
||||
log.Infoln("Starting LetEncrypt redirect server on port 80")
|
||||
go http.ListenAndServe(":80", http.HandlerFunc(simplecert.Redirect))
|
||||
|
||||
cfg, err := letsEncryptCert()
|
||||
if err != nil {
|
||||
httpError <- err
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
srv := &http.Server{
|
||||
|
@ -82,12 +79,10 @@ func startLetsEncryptServer(ip string) {
|
|||
IdleTimeout: timeout,
|
||||
}
|
||||
|
||||
if err := srv.ListenAndServeTLS("", ""); err != nil {
|
||||
httpError <- err
|
||||
}
|
||||
return srv.ListenAndServeTLS("", "")
|
||||
}
|
||||
|
||||
func startSSLServer(ip string) {
|
||||
func startSSLServer(ip string) error {
|
||||
cfg := &tls.Config{
|
||||
MinVersion: tls.VersionTLS12,
|
||||
CurvePreferences: []tls.CurveID{tls.CurveP521, tls.CurveP384, tls.CurveP256},
|
||||
|
@ -112,7 +107,5 @@ func startSSLServer(ip string) {
|
|||
certFile := utils.Directory + "/server.crt"
|
||||
keyFile := utils.Directory + "/server.key"
|
||||
|
||||
if err := srv.ListenAndServeTLS(certFile, keyFile); err != nil {
|
||||
httpError <- err
|
||||
}
|
||||
return srv.ListenAndServeTLS(certFile, keyFile)
|
||||
}
|
||||
|
|
|
@ -234,6 +234,7 @@ func apiServiceTimeDataHandler(w http.ResponseWriter, r *http.Request) {
|
|||
sendErrorJson(err, w, r)
|
||||
return
|
||||
}
|
||||
|
||||
returnJson(uptimeData, w, r)
|
||||
}
|
||||
|
||||
|
|
|
@ -120,7 +120,6 @@ func processSetupHandler(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
core.App.Setup = true
|
||||
|
||||
CacheStorage.Delete("/")
|
||||
resetCookies()
|
||||
|
||||
out := struct {
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -42,7 +42,7 @@ func InitEnvs() {
|
|||
Params.SetDefault("MAX_LIFE_CONN", 5*time.Minute)
|
||||
Params.SetDefault("SAMPLE_DATA", true)
|
||||
Params.SetDefault("USE_CDN", false)
|
||||
Params.SetDefault("ALLOW_REPORTS", false)
|
||||
Params.SetDefault("ALLOW_REPORTS", true)
|
||||
Params.SetDefault("POSTGRES_SSLMODE", "disable")
|
||||
Params.SetDefault("NAME", "Statping Sample Data")
|
||||
Params.SetDefault("DOMAIN", "http://localhost:8080")
|
||||
|
|
|
@ -26,7 +26,7 @@ var (
|
|||
|
||||
const (
|
||||
logFilePath = "/logs/statping.log"
|
||||
errorReporter = "https://ddf2784201134d51a20c3440e222cebe@sentry.statping.com/4"
|
||||
errorReporter = "https://518d5b04a52b4130bbbbd5b9e70cb7ba@sentry.statping.com/2"
|
||||
)
|
||||
|
||||
func SentryInit(allow bool) {
|
||||
|
@ -43,6 +43,7 @@ func SentryInit(allow bool) {
|
|||
Log.Errorln(err)
|
||||
}
|
||||
Log.Infoln("Error Reporting initiated, thank you!")
|
||||
sentry.CaptureMessage("sentry connected")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
0.90.72
|
||||
0.90.73
|
||||
|
|
Loading…
Reference in New Issue