Compare commits
No commits in common. "72f23b9c4d1cac2a713cb0fc8a81b72f5e81c26e" and "a1201003055d9aeff30af3722caa45380ea5701c" have entirely different histories.
72f23b9c4d
...
a120100305
@ -28,9 +28,8 @@ session:
|
|||||||
|
|
||||||
application:
|
application:
|
||||||
logfile: /var/log/smon.log
|
logfile: /var/log/smon.log
|
||||||
nodata_interval: 60
|
|
||||||
```
|
```
|
||||||
|
|
||||||
# Data from systems to datapoints
|
# Data from systems to datapoints
|
||||||
|
|
||||||
`curl -d "$(time +'%F %T +02')" http://localhost:9000/entry/datapoint_name`
|
`curl -d "$(time +'%F %T +02')" http://localhost:9000/entry/datapoint_name`
|
22
main.go
22
main.go
@ -27,7 +27,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
const VERSION = "v17"
|
const VERSION = "v16"
|
||||||
|
|
||||||
var (
|
var (
|
||||||
logger *slog.Logger
|
logger *slog.Logger
|
||||||
@ -143,7 +143,6 @@ func main() { // {{{
|
|||||||
service.Register("/trigger/addDatapoint/{id}/{datapointName}", false, false, pageTriggerDatapointAdd)
|
service.Register("/trigger/addDatapoint/{id}/{datapointName}", false, false, pageTriggerDatapointAdd)
|
||||||
service.Register("/trigger/update/{id}", false, false, pageTriggerUpdate)
|
service.Register("/trigger/update/{id}", false, false, pageTriggerUpdate)
|
||||||
service.Register("/trigger/run/{id}", false, false, pageTriggerRun)
|
service.Register("/trigger/run/{id}", false, false, pageTriggerRun)
|
||||||
service.Register("/trigger/delete/{id}", false, false, actionTriggerDelete)
|
|
||||||
|
|
||||||
service.Register("/configuration", false, false, pageConfiguration)
|
service.Register("/configuration", false, false, pageConfiguration)
|
||||||
service.Register("/entry/{datapoint}", false, false, entryDatapoint)
|
service.Register("/entry/{datapoint}", false, false, entryDatapoint)
|
||||||
@ -696,7 +695,7 @@ func triggerCreate(w http.ResponseWriter, r *http.Request, _ *session.T) { // {{
|
|||||||
}
|
}
|
||||||
|
|
||||||
resp := struct {
|
resp := struct {
|
||||||
OK bool
|
OK bool
|
||||||
Trigger Trigger
|
Trigger Trigger
|
||||||
}{
|
}{
|
||||||
true,
|
true,
|
||||||
@ -863,23 +862,6 @@ func pageTriggerRun(w http.ResponseWriter, r *http.Request, _ *session.T) { // {
|
|||||||
w.Header().Add("Content-Type", "application/json")
|
w.Header().Add("Content-Type", "application/json")
|
||||||
w.Write(j)
|
w.Write(j)
|
||||||
} // }}}
|
} // }}}
|
||||||
func actionTriggerDelete(w http.ResponseWriter, r *http.Request, _ *session.T) { // {{{
|
|
||||||
idStr := r.PathValue("id")
|
|
||||||
id, err := strconv.Atoi(idStr)
|
|
||||||
if err != nil {
|
|
||||||
httpError(w, werr.Wrap(err).Log())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err = TriggerDelete(id)
|
|
||||||
if err != nil {
|
|
||||||
httpError(w, werr.Wrap(err).Log())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
w.Header().Add("Location", "/triggers")
|
|
||||||
w.WriteHeader(302)
|
|
||||||
} // }}}
|
|
||||||
|
|
||||||
func pageConfiguration(w http.ResponseWriter, _ *http.Request, _ *session.T) { // {{{
|
func pageConfiguration(w http.ResponseWriter, _ *http.Request, _ *session.T) { // {{{
|
||||||
areas, err := AreaRetrieve()
|
areas, err := AreaRetrieve()
|
||||||
|
@ -103,6 +103,7 @@ label {
|
|||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
}
|
}
|
||||||
.graph {
|
.graph {
|
||||||
margin-top: 192px;
|
margin-top: 32px;
|
||||||
|
padding: 32px;
|
||||||
border-radius: 16px;
|
border-radius: 16px;
|
||||||
}
|
}
|
||||||
|
@ -201,6 +201,19 @@ label {
|
|||||||
#areas .area .section > .name {
|
#areas .area .section > .name {
|
||||||
font-weight: 800;
|
font-weight: 800;
|
||||||
}
|
}
|
||||||
|
#areas .area .section .triggers .trigger {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: min-content 1fr;
|
||||||
|
grid-gap: 8px;
|
||||||
|
align-items: center;
|
||||||
|
margin-top: 8px;
|
||||||
|
}
|
||||||
|
#areas .area .section .triggers .trigger img {
|
||||||
|
height: 16px;
|
||||||
|
}
|
||||||
|
#areas .area .section .triggers .trigger .label {
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
dialog {
|
dialog {
|
||||||
background: #202020;
|
background: #202020;
|
||||||
border: 1px solid #606060;
|
border: 1px solid #606060;
|
||||||
|
@ -1,117 +0,0 @@
|
|||||||
html {
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
*,
|
|
||||||
*:before,
|
|
||||||
*:after {
|
|
||||||
box-sizing: inherit;
|
|
||||||
}
|
|
||||||
*:focus {
|
|
||||||
outline: none;
|
|
||||||
}
|
|
||||||
[onClick] {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
html,
|
|
||||||
body {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
body {
|
|
||||||
background: #282828;
|
|
||||||
font-family: sans-serif;
|
|
||||||
font-weight: 300;
|
|
||||||
color: #d5c4a1;
|
|
||||||
font-size: 11pt;
|
|
||||||
}
|
|
||||||
h1,
|
|
||||||
h2 {
|
|
||||||
margin-bottom: 4px;
|
|
||||||
}
|
|
||||||
h1:first-child,
|
|
||||||
h2:first-child {
|
|
||||||
margin-top: 0px;
|
|
||||||
}
|
|
||||||
h1 {
|
|
||||||
font-size: 1.5em;
|
|
||||||
color: #fb4934;
|
|
||||||
font-weight: 800;
|
|
||||||
}
|
|
||||||
h2 {
|
|
||||||
font-size: 1.25em;
|
|
||||||
color: #b8bb26;
|
|
||||||
font-weight: 800;
|
|
||||||
}
|
|
||||||
a {
|
|
||||||
color: #3f9da1;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
a:hover {
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
b {
|
|
||||||
font-weight: 800;
|
|
||||||
}
|
|
||||||
input[type="text"],
|
|
||||||
textarea,
|
|
||||||
select {
|
|
||||||
font-family: monospace;
|
|
||||||
background: #202020;
|
|
||||||
color: #d5c4a1;
|
|
||||||
padding: 4px 8px;
|
|
||||||
border: none;
|
|
||||||
font-size: 1em;
|
|
||||||
line-height: 1.5em;
|
|
||||||
}
|
|
||||||
button {
|
|
||||||
background: #202020;
|
|
||||||
color: #d5c4a1;
|
|
||||||
padding: 8px 32px;
|
|
||||||
border: 1px solid #535353;
|
|
||||||
font-size: 1em;
|
|
||||||
height: 3em;
|
|
||||||
}
|
|
||||||
button:focus {
|
|
||||||
background: #333;
|
|
||||||
}
|
|
||||||
.line {
|
|
||||||
grid-column: 1 / -1;
|
|
||||||
border-bottom: 1px solid #4e4e4e;
|
|
||||||
}
|
|
||||||
span.date {
|
|
||||||
color: #d5c4a1;
|
|
||||||
font-weight: 800;
|
|
||||||
}
|
|
||||||
span.time {
|
|
||||||
font-size: 0.9em;
|
|
||||||
color: #d5c4a1;
|
|
||||||
}
|
|
||||||
span.seconds {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
label {
|
|
||||||
user-select: none;
|
|
||||||
}
|
|
||||||
.description {
|
|
||||||
border: 1px solid #737373;
|
|
||||||
color: #3f9da1;
|
|
||||||
background: #202020;
|
|
||||||
padding: 4px 8px;
|
|
||||||
margin-top: 8px;
|
|
||||||
white-space: nowrap;
|
|
||||||
width: min-content;
|
|
||||||
border-radius: 8px;
|
|
||||||
}
|
|
||||||
#areas .area .section .triggers .trigger {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: min-content 1fr min-content;
|
|
||||||
grid-gap: 8px;
|
|
||||||
align-items: center;
|
|
||||||
margin-top: 8px;
|
|
||||||
}
|
|
||||||
#areas .area .section .triggers .trigger img {
|
|
||||||
height: 16px;
|
|
||||||
}
|
|
||||||
#areas .area .section .triggers .trigger .label {
|
|
||||||
color: inherit;
|
|
||||||
}
|
|
@ -1,6 +1,7 @@
|
|||||||
@import "theme.less";
|
@import "theme.less";
|
||||||
|
|
||||||
.graph {
|
.graph {
|
||||||
margin-top: 192px;
|
margin-top: 32px;
|
||||||
|
padding: 32px;
|
||||||
border-radius: 16px;
|
border-radius: 16px;
|
||||||
}
|
}
|
||||||
|
@ -117,6 +117,24 @@
|
|||||||
&>.name {
|
&>.name {
|
||||||
font-weight: @bold;
|
font-weight: @bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.triggers {
|
||||||
|
.trigger {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: min-content 1fr;
|
||||||
|
grid-gap: 8px;
|
||||||
|
align-items: center;
|
||||||
|
margin-top: 8px;
|
||||||
|
|
||||||
|
img {
|
||||||
|
height: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,26 +0,0 @@
|
|||||||
@import 'theme.less';
|
|
||||||
|
|
||||||
|
|
||||||
#areas {
|
|
||||||
.area {
|
|
||||||
.section {
|
|
||||||
.triggers {
|
|
||||||
.trigger {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: min-content 1fr min-content;
|
|
||||||
grid-gap: 8px;
|
|
||||||
align-items: center;
|
|
||||||
margin-top: 8px;
|
|
||||||
|
|
||||||
img {
|
|
||||||
height: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.label {
|
|
||||||
color: inherit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
27
trigger.go
27
trigger.go
@ -2,7 +2,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
// External
|
// External
|
||||||
werr "git.gibonuddevalla.se/go/wrappederror"
|
we "git.gibonuddevalla.se/go/wrappederror"
|
||||||
"github.com/expr-lang/expr"
|
"github.com/expr-lang/expr"
|
||||||
"github.com/lib/pq"
|
"github.com/lib/pq"
|
||||||
|
|
||||||
@ -67,7 +67,7 @@ func TriggersRetrieve() (areas []Area, err error) { // {{{
|
|||||||
var jsonData []byte
|
var jsonData []byte
|
||||||
err = row.Scan(&jsonData)
|
err = row.Scan(&jsonData)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = werr.Wrap(err)
|
err = we.Wrap(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,7 +77,7 @@ func TriggersRetrieve() (areas []Area, err error) { // {{{
|
|||||||
|
|
||||||
err = json.Unmarshal(jsonData, &areas)
|
err = json.Unmarshal(jsonData, &areas)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = werr.Wrap(err)
|
err = we.Wrap(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,13 +97,13 @@ func TriggersRetrieveByDatapoint(datapointName string) (triggers []Trigger, err
|
|||||||
var data []byte
|
var data []byte
|
||||||
err = row.Scan(&data)
|
err = row.Scan(&data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = werr.Wrap(err).WithData(datapointName)
|
err = we.Wrap(err).WithData(datapointName)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err = json.Unmarshal(data, &triggers)
|
err = json.Unmarshal(data, &triggers)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = werr.Wrap(err).WithData(datapointName)
|
err = we.Wrap(err).WithData(datapointName)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,7 +114,7 @@ func TriggerRetrieve(id int) (trigger Trigger, err error) { // {{{
|
|||||||
var jsonData []byte
|
var jsonData []byte
|
||||||
err = row.Scan(&jsonData)
|
err = row.Scan(&jsonData)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = werr.Wrap(err)
|
err = we.Wrap(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -158,7 +158,7 @@ func (t *Trigger) Update() (err error) { // {{{
|
|||||||
)
|
)
|
||||||
err = row.Scan(&t.ID)
|
err = row.Scan(&t.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = werr.Wrap(err).WithData(
|
err = we.Wrap(err).WithData(
|
||||||
struct {
|
struct {
|
||||||
SectionID int
|
SectionID int
|
||||||
Name string
|
Name string
|
||||||
@ -191,7 +191,7 @@ func (t *Trigger) Update() (err error) { // {{{
|
|||||||
}
|
}
|
||||||
|
|
||||||
if pqErr, ok := err.(*pq.Error); ok {
|
if pqErr, ok := err.(*pq.Error); ok {
|
||||||
err = werr.Wrap(err).WithData(
|
err = we.Wrap(err).WithData(
|
||||||
struct {
|
struct {
|
||||||
Trigger *Trigger
|
Trigger *Trigger
|
||||||
PostgresCode pq.ErrorCode
|
PostgresCode pq.ErrorCode
|
||||||
@ -202,14 +202,7 @@ func (t *Trigger) Update() (err error) { // {{{
|
|||||||
pqErr.Code.Name(),
|
pqErr.Code.Name(),
|
||||||
})
|
})
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
err = werr.Wrap(err).WithData(t)
|
err = we.Wrap(err).WithData(t)
|
||||||
}
|
|
||||||
return
|
|
||||||
} // }}}
|
|
||||||
func TriggerDelete(id int) (err error) { // {{{
|
|
||||||
_, err = service.Db.Conn.Exec(`DELETE FROM public.trigger WHERE id=$1`, id)
|
|
||||||
if err != nil {
|
|
||||||
return werr.Wrap(err).WithData(id)
|
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
} // }}}
|
} // }}}
|
||||||
@ -220,7 +213,7 @@ func (t *Trigger) Run() (output any, err error) { // {{{
|
|||||||
var dp Datapoint
|
var dp Datapoint
|
||||||
dp, err = DatapointRetrieve(0, dpname)
|
dp, err = DatapointRetrieve(0, dpname)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = werr.Wrap(err)
|
err = we.Wrap(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
datapoints[dpname] = dp
|
datapoints[dpname] = dp
|
||||||
|
@ -9,9 +9,9 @@
|
|||||||
<h1>SMon</h1>
|
<h1>SMon</h1>
|
||||||
<h2>{{ .VERSION }}</h2>
|
<h2>{{ .VERSION }}</h2>
|
||||||
|
|
||||||
|
<div class="graph">
|
||||||
|
<img src="/images/{{ .VERSION }}/graph.svg">
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="clear: both" class="graph">
|
|
||||||
<img src="/images/{{ .VERSION }}/graph.svg">
|
|
||||||
</div>
|
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
{{ block "page_label" . }}{{end}}
|
{{ block "page_label" . }}{{end}}
|
||||||
{{ $version := .VERSION }}
|
{{ $version := .VERSION }}
|
||||||
<link rel="stylesheet" type="text/css" href="/css/{{ .VERSION }}/triggers.css">
|
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
function createTrigger(sectionID) {
|
function createTrigger(sectionID) {
|
||||||
@ -25,12 +24,6 @@
|
|||||||
location.href = `/trigger/edit/${json.Trigger.ID}`
|
location.href = `/trigger/edit/${json.Trigger.ID}`
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function deleteTrigger(triggerID, name) {
|
|
||||||
if (!confirm(`Sure you want to delete '${name}'?`))
|
|
||||||
return
|
|
||||||
location.href = `/trigger/delete/${triggerID}`
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div id="areas">
|
<div id="areas">
|
||||||
@ -49,11 +42,12 @@
|
|||||||
{{ if eq .Name "" }}
|
{{ if eq .Name "" }}
|
||||||
{{ continue }}
|
{{ continue }}
|
||||||
{{ end }}
|
{{ end }}
|
||||||
<div class="trigger">
|
<a href="/trigger/edit/{{ .ID }}">
|
||||||
<img src="/images/{{ $version }}/triggers.svg">
|
<div class="trigger">
|
||||||
<div class="label"><a href="/trigger/edit/{{ .ID }}">{{ .Name }}</a></div>
|
<img src="/images/{{ $version }}/triggers.svg">
|
||||||
<img src="/images/{{ $version }}/delete.svg" onclick="deleteTrigger({{ .ID }}, '{{ .Name }}')">
|
<div class="label">{{ .Name }}</div>
|
||||||
</div>
|
</div>
|
||||||
|
</a>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
Reference in New Issue
Block a user