Skip to content

Commit

Permalink
Improved web metrics UI
Browse files Browse the repository at this point in the history
  • Loading branch information
Kashkovsky committed Apr 16, 2022
1 parent 1a4030d commit 863748c
Show file tree
Hide file tree
Showing 9 changed files with 118 additions and 53 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@ dist/
node_modules/
.parcel-cache/
static/
hostmonitor
2 changes: 1 addition & 1 deletion core/printer.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ func (p *Printer) ToTable(results *Store) {
p.t.AppendRow(table.Row{
r.Id,
r.Tcp,
r.HttpStatus,
r.HttpResponse,
r.Duration,
})
return true
Expand Down
11 changes: 6 additions & 5 deletions core/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,12 @@ func (s *Store) AddOrUpdate(res TestResult) {
} else {
prev := existing.(TestResult)
s.results.Store(res.Id, TestResult{
Id: prev.Id,
InProgress: true,
Tcp: prev.Tcp,
HttpStatus: prev.HttpStatus,
Duration: prev.Duration,
Id: prev.Id,
InProgress: true,
Tcp: prev.Tcp,
HttpResponse: prev.HttpResponse,
Duration: prev.Duration,
Status: prev.Status,
})
}
} else {
Expand Down
19 changes: 19 additions & 0 deletions core/test-result.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package core

import "net/url"

const (
StatusOK = "OK"
StatusErr = "Error"
StatusErrResponse = "ErrorResponse"
)

type TestResult struct {
Id string `json:"id"`
InProgress bool `json:"inProgress"`
url url.URL
Tcp string `json:"tcp"`
HttpResponse string `json:"httpResponse"`
Duration string `json:"duration"`
Status string `json:"status"`
}
44 changes: 22 additions & 22 deletions core/tester.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,6 @@ import (
"time"
)

type TestResult struct {
Id string `json:"id"`
InProgress bool `json:"inProgress"`
url url.URL
Tcp string `json:"tcp"`
HttpStatus string `json:"httpStatus"`
Duration string `json:"duration"`
}

type Tester struct {
requestTimeout time.Duration
testInterval time.Duration
Expand All @@ -40,23 +31,25 @@ func (t *Tester) Test(url *url.URL) {
case <-t.quit:
return
default:
tcp := "-"
t.out <- TestResult{
Id: url.String(),
InProgress: true,
HttpStatus: "Testing...",
Tcp: tcp,
}

var pass int
if url.Scheme == "tcp" {
pass = t.tcp(url)
pass := t.tcp(url)
tcp = fmt.Sprintf("%d/10", pass)
}
status, duration := t.http(url)
response, duration, status := t.http(url)
t.out <- TestResult{
Id: url.String(),
url: *url,
Tcp: fmt.Sprintf("%d/10", pass),
HttpStatus: status,
Duration: strconv.FormatInt(duration.Milliseconds(), 10) + "ms",
Id: url.String(),
url: *url,
Tcp: tcp,
HttpResponse: response,
Duration: strconv.FormatInt(duration.Milliseconds(), 10) + "ms",
Status: status,
}
time.Sleep(t.testInterval)
}
Expand All @@ -76,18 +69,25 @@ func (t *Tester) tcp(url *url.URL) int {
return pass
}

func (t *Tester) http(url *url.URL) (status string, duration time.Duration) {
func (t *Tester) http(url *url.URL) (statusMessage string, duration time.Duration, status string) {
tp := NewTransport(t.requestTimeout)
client := http.Client{Transport: tp, Timeout: t.requestTimeout}
addr := strings.Replace(url.String(), "tcp", "http", 1)
res, err := client.Get(addr)
duration = tp.Duration()
if err == nil {
status = res.Status
statusMessage = res.Status
if res.StatusCode >= 500 {
status = StatusErrResponse
} else {
status = StatusOK
}
} else if duration >= t.requestTimeout {
status = "TIMEOUT"
statusMessage = "TIMEOUT"
status = StatusErrResponse
} else {
status = formatError(err, url)
statusMessage = formatError(err, url)
status = StatusErr
}

return
Expand Down
Binary file removed hostmonitor
Binary file not shown.
30 changes: 12 additions & 18 deletions web/client/src/main.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { lift } from '@grammarly/focal'
import {
Chip,
Paper,
Table,
TableBody,
Expand All @@ -14,23 +15,14 @@ import { Stream } from './stream'

const Body = lift(TableBody)

const getBg = (item: Stream.Item) => {
switch (true) {
case item.httpStatus.includes('OK'):
return '#a1ffc3'
case item.httpStatus.includes('connection refused'):
return '#ebffa1'
case item.httpStatus.includes('TIMEOUT'):
return '#fc8672'
default:
return undefined
}
}
const Tcp = ({ item }: { item: Stream.Item }) => (
<Chip label={item.tcp} color={Stream.Item.getTcpStatus(item)} />
)

export const Main = () => (
<main>
<TableContainer component={Paper}>
<Table sx={{ minWidth: 650 }} aria-label="simple table">
<Table stickyHeader sx={{ minWidth: 650 }} size="small" aria-label="simple table">
<TableHead>
<TableRow>
<TableCell>Address</TableCell>
Expand All @@ -47,14 +39,16 @@ export const Main = () => (
key={item.id}
sx={{
'&:last-child td, &:last-child th': { border: 0 },
background: getBg(item)
background: Stream.Item.getStatusColor(item)
}}
>
<TableCell component="th" scope="row">
{item.id}
<TableCell width={150} component="th" scope="row">
<strong>{item.id}</strong>
</TableCell>
<TableCell align="right">
<Tcp item={item} />
</TableCell>
<TableCell align="right">{item.tcp}</TableCell>
<TableCell align="right">{item.httpStatus}</TableCell>
<TableCell align="right">{item.httpResponse}</TableCell>
<TableCell align="right">{item.duration}</TableCell>
</TableRow>
))
Expand Down
63 changes: 57 additions & 6 deletions web/client/src/stream.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,68 @@
import { pipe } from 'fp-ts/es6/function'
import { isNumber } from 'fp-ts/es6/number'
import * as Ord from 'fp-ts/es6/Ord'
import { fromEvent, map, mergeMap, Observable, retryWhen, scan, take, timer } from 'rxjs'
import { WebSocketSubject } from 'rxjs/webSocket'
import * as A from 'fp-ts/es6/Array'
import { string } from 'fp-ts'

export type Stream = Observable<Stream.Item>

export namespace Stream {
const RETRY_DELAY = 5000
export interface Item {
id: string
inProgress: boolean
tcp: string
httpStatus: string
duration: string
readonly id: string
readonly inProgress: boolean
readonly tcp: string
readonly httpResponse: string
readonly duration: string
readonly status: Stream.Item.Status
}

export namespace Item {
export enum Status {
StatusOK = 'OK',
StatusErr = 'Error',
StatusErrResponse = 'ErrorResponse'
}

export const ord: Ord.Ord<Stream.Item> = pipe(
Ord.contramap<string, Stream.Item>(x => x.status)(string.Ord),
Ord.reverse
)

export const getStatusColor = (item: Stream.Item) => {
switch (item.status) {
case Stream.Item.Status.StatusOK:
return '#a1ffc3'
case Stream.Item.Status.StatusErr:
return '#ebffa1'
case Stream.Item.Status.StatusErrResponse:
return '#fc8672'
default:
return undefined
}
}

export const getTcpStatus = (item: Stream.Item) => {
const success = +item.tcp.split('/')[0]
if (isNumber(success)) {
switch (true) {
case success >= 6:
return 'success'
case success < 6 && success > 3:
return 'warning'
case success <= 3:
return 'error'
default:
return 'default'
}
}

return 'default'
}
}

export const create = () => {
const sock = new WebSocketSubject<Stream.Item>(`ws://${location.host}/ws`)
return sock.pipe(
Expand All @@ -31,7 +82,7 @@ export namespace Stream {
(a, c) => (a.set(c.id, c), a),
new Map<string, Stream.Item>()
),
map(items => [...items.values()])
map(items => pipe([...items.values()], A.sort(Stream.Item.ord)))
)
}
}
1 change: 0 additions & 1 deletion web/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@ Loop:
s.store.ForEach(func(res core.TestResult) bool {
err := c.WriteJSON(res)
if err != nil {
log.Println("Error sending a message to client", err.Error())
close <- true
return false
}
Expand Down

0 comments on commit 863748c

Please sign in to comment.