Skip to content

Commit

Permalink
First release
Browse files Browse the repository at this point in the history
  • Loading branch information
mitjafelicijan committed Mar 22, 2021
1 parent b95aa7b commit d18f552
Show file tree
Hide file tree
Showing 9 changed files with 398 additions and 0 deletions.
20 changes: 20 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# EditorConfig is awesome: https://EditorConfig.org

# top-most EditorConfig file
root = true

[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

[*.go]
indent_style = tab
indent_size = 4

[Makefile]
indent_style = tab
indent_size = 4
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
release/
21 changes: 21 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
VERSION = "1.0.0"

dev:
find -type f \( -name "*.go" \) | entr -r go run *.go

build: clean-build embed-assets amd64 arm
@echo "Building amd64 and arm version"

embed-assets:
go-bindata assets/...

clean-build:
- rm release -Rf

amd64:
mkdir -p release/linux-amd64
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-X 'main.ldVersion=$(VERSION)'" -o release/linux-amd64/journalctl-proxy -v -a *.go

arm:
mkdir -p release/linux-arm
CGO_ENABLED=0 GOOS=linux GOARCH=arm GOARM=5 go build -ldflags="-X 'main.ldVersion=$(VERSION)'" -o release/linux-arm/journalctl-proxy -v -a *.go
115 changes: 115 additions & 0 deletions assets/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>journalctl</title>

<style>
body {
font-family: sans-serif;
font-size: 13px;
}

header {
display: flex;
align-items: center;
}

header h1 {
flex-grow: 1;
}
</style>

</head>

<body>

<header>
<h1>journalctl proxy</h1>
<div>
<select onchange="startListeningToService()">
<option>Select service</option>
</select>
</div>
</header>

<table border="1" width="100%">
<thead>
<tr>
<th>PID</th>
<th>Unit</th>
<th>Timestamp</th>
<th>Message</th>
</tr>
</thead>
<tbody></tbody>
</table>

<script>

let socket = null;

const select = document.querySelector('select');
const table = document.querySelector('table');

(async () => {
const servicesRequest = await fetch('/list-services');
const servicesList = await servicesRequest.text();

for (let line of servicesList.split('\n')) {
line = line.trim();
if (line === '') break;

if (!line.startsWith('UNIT')) {
const serviceName = line.split(' ')[0];
const option = document.createElement('option');
option.value = serviceName.split('.')[0];
option.innerText = serviceName;
select.appendChild(option)
}
}
})();

function startListeningToService() {
if (socket) {
socket.close(1000, 'Work complete');
}

socket = new WebSocket(`ws://${window.location.host}/ws/${select.value}`);

socket.onopen = function (e) {
console.log(`[open] Connection established with service: ${select.value}`);
};

socket.onmessage = function (event) {
const incomingMessage = JSON.parse(event.data);

const row = document.createElement('tr');
const pid = document.createElement('td');
const priority = document.createElement('td');
const systemdUnit = document.createElement('td');
const realtimeTimestamp = document.createElement('td');
const message = document.createElement('td');

pid.innerText = incomingMessage._PID;
systemdUnit.innerText = incomingMessage._SYSTEMD_UNIT;
realtimeTimestamp.innerText = incomingMessage.__REALTIME_TIMESTAMP;
message.innerText = incomingMessage.MESSAGE;

row.appendChild(pid);
row.appendChild(systemdUnit);
row.appendChild(realtimeTimestamp);
row.appendChild(message);

table.appendChild(row);
};
}

</script>

</body>

</html>
105 changes: 105 additions & 0 deletions bindata.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package main

import (
"bytes"
"compress/gzip"
"fmt"
"io"
"strings"
)

func bindata_read(data []byte, name string) ([]byte, error) {
gz, err := gzip.NewReader(bytes.NewBuffer(data))
if err != nil {
return nil, fmt.Errorf("Read %q: %v", name, err)
}

var buf bytes.Buffer
_, err = io.Copy(&buf, gz)
gz.Close()

if err != nil {
return nil, fmt.Errorf("Read %q: %v", name, err)
}

return buf.Bytes(), nil
}

var _assets_index_html = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x94\x56\xdd\x6e\xdb\x38\x13\xbd\xf7\x53\x4c\x85\x7e\xb0\x0c\xd4\x92\x8d\xef\x66\xe1\x48\x06\x82\xc4\xbb\xc8\xa2\x69\x83\xda\x41\xb7\xe8\x16\x29\x2d\x8d\x2d\x6e\x29\x52\x25\xc7\x51\xbc\x45\xde\x7d\x41\x51\xd6\x8f\xeb\x1a\x48\x2e\x62\x91\x33\x67\xe6\x9c\x99\x21\xa5\xe8\xd5\xf5\xfb\xab\xd5\xa7\xbb\x05\x64\x94\x8b\xf9\x20\xb2\x3f\x20\x98\xdc\xc6\x1e\x4a\x6f\x3e\x18\x00\x44\x19\xb2\x74\x3e\x00\x00\x88\x72\x24\x06\x49\xc6\xb4\x41\x8a\xbd\xfb\xd5\xef\xe3\xdf\xbc\xae\x29\x23\x2a\xc6\xf8\x7d\xc7\x1f\x63\xef\xaf\xf1\xfd\xe5\xf8\x4a\xe5\x05\x23\xbe\x16\xe8\x41\xa2\x24\xa1\xa4\xd8\xbb\x59\xc4\x98\x6e\xb1\x87\x94\x2c\xc7\xd8\x7b\xe4\x58\x16\x4a\x53\xc7\xb9\xe4\x29\x65\x71\x8a\x8f\x3c\xc1\x71\xb5\x78\x03\x5c\x72\xe2\x4c\x8c\x4d\xc2\x04\xc6\xd3\x60\x72\x08\x45\x9c\x04\xce\xff\x51\x3b\x2d\x99\x48\x48\x44\xa1\xdb\x19\x38\xb3\xa1\xbd\x5d\x40\xf5\xb7\x56\xe9\x1e\x7e\xd4\x0b\x80\x8d\x92\x34\xde\xb0\x9c\x8b\xfd\x0c\x0c\x93\x66\x6c\x50\xf3\xcd\x45\xdf\xc1\xf0\x7f\x71\x06\xd3\xff\x17\x4f\x07\xc3\xf3\xa0\x7e\xb0\x65\x42\xdd\x89\x98\x72\x53\x08\xb6\x9f\xc1\x46\xe0\x53\x1b\x87\x09\xbe\x95\x63\x4e\x98\x9b\x19\x24\x28\x09\xf5\xaf\x62\x65\xd3\x2e\x41\x81\x4f\xe3\xad\x56\xe5\x0c\xa6\x2d\xa0\xd2\x15\xd6\xc2\x6c\xb7\x42\xd7\x2e\xfb\x68\x15\x1e\xa4\xbb\x88\x07\xed\x51\x36\xed\x54\x09\x0a\xad\x9e\xf6\x51\x98\x4d\x1b\x7b\xca\x1f\xe7\x4d\xe6\xc8\xa0\xc0\x84\x40\xc9\x24\x63\x72\x8b\xb1\x67\x88\x69\x7a\xcb\x0d\xa1\xe4\x72\xbb\x52\x4b\xd4\xb6\x3f\xfe\xc8\x6b\x51\x00\x91\x2a\x88\x2b\x39\x5f\x3a\xb8\x71\x4e\x51\x58\x6f\xb7\xf1\x43\x97\xa0\xc9\x1e\x36\xe9\x9d\x1c\x4b\xbc\x6e\x30\x5b\x0b\x84\xb5\xd2\x29\xea\xd8\x9b\x7a\xe0\xc6\xc3\x9b\x4e\x26\xff\x6b\x72\x47\xd4\x8e\xac\x5b\xeb\x1e\x2d\xca\xe6\x77\x37\xd7\x51\x48\xd9\xf1\xf6\xbd\xe4\x74\x6a\x7f\xc5\x73\x34\xc4\xf2\xe2\x94\xf1\x16\x8d\x61\x5b\xec\x9b\xa2\xb0\x4d\x6a\x2d\x1d\x42\x11\x55\x8d\x89\x42\xf7\x5b\xeb\xac\x94\x35\x83\x9a\x68\x5e\xd0\xfc\x30\x0e\x02\x09\x8c\x4a\xbe\x21\x41\x0c\x72\x27\xc4\xc5\xc1\x92\x28\x69\x6c\x65\xab\x02\xc7\x90\xaa\x64\x97\xa3\xa4\xe0\xfb\x0e\xf5\xde\xd5\x5d\x69\x7f\xe8\x1c\x86\xa3\x8b\x1e\xcc\x15\xf3\xd7\xa8\xca\x6e\x41\x35\xca\x67\x66\x2f\x13\xf0\x47\x10\xcf\x3b\x83\x79\xe0\x50\x75\xd7\x7c\xc0\xef\x3b\x34\x96\x0c\x2b\x19\x27\xd8\x20\x25\x99\x3f\x0c\x05\x37\x34\x3e\x38\xb5\x4c\x8e\xe1\x76\xa8\x1a\xec\x51\xcc\x80\xf0\x89\xfc\x96\x8f\x3d\x93\x1a\x7c\x5b\x1d\xc1\x25\x82\xda\xf4\xc2\x04\xa6\x10\x9c\xfc\xe1\xdf\x72\x38\x1a\x75\xf8\x82\xf3\x8e\xab\x9f\x80\x34\xcf\xfd\x0e\x1d\x00\xbe\x01\xdf\x79\xc4\x31\x0c\x87\x23\x58\x6b\x64\xdf\x3a\x59\x9d\xcb\xab\x0a\x5e\x9d\x04\xf3\x91\x53\xe6\x0f\xef\xdf\xdd\xac\x8e\x53\x1d\xe9\x7b\xc7\xf2\x26\x73\x4d\x0f\x86\xa3\xcf\x93\x2f\x17\x27\x30\xee\x9c\x74\x1b\x94\x68\x64\x84\x0b\x81\x76\xe5\x0f\x9d\xc3\x70\xd4\x07\xbb\xdd\xe0\x91\x89\x9d\xcd\xd5\xc9\x7c\x48\x19\x9c\x48\x59\xa3\xb8\x94\xa8\x57\xf8\x44\x7d\x64\xdf\xd7\x8d\x53\xc0\x8a\x02\x65\x7a\x95\x71\x91\xfa\x0e\x3e\xea\xb8\x3d\x0f\x8e\x9f\x9e\x47\x9d\xe6\x6d\x76\x32\xa9\xe4\xfd\xf2\x2e\xe9\xd4\xd1\xd6\xdb\x1d\x80\x7e\x75\xdd\x5e\x90\x08\x65\xd0\x9f\x4e\x26\x93\x37\x30\xfc\xa8\xf4\x37\x48\x54\x5e\x08\x24\xec\xd6\xe6\xb9\xed\x60\x7b\x98\xb0\x84\x8f\xb8\x5e\x56\x6b\xff\x6b\x69\x66\x61\xf8\xfa\x47\xc9\x65\xaa\xca\x40\xa8\x84\x55\x45\xc9\x94\xa1\xe7\xb0\x34\xe1\xeb\x1f\xb5\xf4\xaa\xb8\xcf\x5f\xbb\xb3\x58\x73\x51\x52\x15\x68\x9b\xd6\x08\xf4\xb1\x4f\xda\x36\x57\x09\x0c\x84\xda\xfa\x5f\x3f\x5b\xef\x2f\x70\xa5\xa4\x44\xe7\x6e\x2f\x9a\xb5\xe0\x26\xc3\x14\x4a\x4e\xd9\xa1\x0d\x33\x38\x91\xbd\xd1\x76\x8a\x48\xee\x2e\xa6\x3e\x97\x47\x94\xf4\x33\x1f\x02\x2e\x13\x95\x73\xb9\xbd\x6d\x40\x7f\x2e\xdf\xbf\x0b\x0a\xfb\xae\x77\xa8\x20\x65\xc4\x46\xbd\x73\xe0\xa0\x5a\x95\x67\x86\x94\x74\x7f\x40\x1d\xa6\xe0\xe9\x39\x4c\x7a\x12\xa3\xb9\xd2\x9c\xf6\x2f\x06\x9a\xbd\x21\xcc\x53\x7b\xbb\xbf\x18\xab\x91\x09\xe2\x39\x36\xaf\x80\x17\x47\x68\xdb\x70\x1e\xd7\x01\x16\x3c\xed\x9d\xc4\xa3\xe6\x04\x0f\x77\x37\xd7\xdd\x44\x1d\x81\xe7\x71\xcb\x4f\xcb\xd5\xe2\xf6\xfa\xc1\x5e\x55\xdd\x00\x3f\xa9\x3c\x1f\xe6\xe1\xc3\xe2\xf2\xed\xea\xe6\x76\xf1\x60\xff\x2d\x57\x97\xb7\x77\xdd\x68\xb5\xe2\xb3\x31\x6e\x17\xcb\xe5\xe5\x1f\x8b\x9e\x6c\xad\xca\xde\xa5\x52\xf0\xb4\x57\xcf\x63\x7b\x47\xf6\x59\xbf\x9f\xd4\x9d\xf5\xae\xd9\xf7\x3b\x52\xbd\x0b\xfb\x41\x55\xd9\x3f\x80\xf5\xc3\xe0\xf0\x4d\xd6\xbe\xc3\xa3\xb0\xfe\x14\x8b\x42\xf7\x9d\xfd\x5f\x00\x00\x00\xff\xff\xfe\x7d\x8a\x21\x78\x0b\x00\x00")

func assets_index_html() ([]byte, error) {
return bindata_read(
_assets_index_html,
"assets/index.html",
)
}

// Asset loads and returns the asset for the given name.
// It returns an error if the asset could not be found or
// could not be loaded.
func Asset(name string) ([]byte, error) {
cannonicalName := strings.Replace(name, "\\", "/", -1)
if f, ok := _bindata[cannonicalName]; ok {
return f()
}
return nil, fmt.Errorf("Asset %s not found", name)
}

// AssetNames returns the names of the assets.
func AssetNames() []string {
names := make([]string, 0, len(_bindata))
for name := range _bindata {
names = append(names, name)
}
return names
}

// _bindata is a table, holding each asset generator, mapped to its name.
var _bindata = map[string]func() ([]byte, error){
"assets/index.html": assets_index_html,
}
// AssetDir returns the file names below a certain
// directory embedded in the file by go-bindata.
// For example if you run go-bindata on data/... and data contains the
// following hierarchy:
// data/
// foo.txt
// img/
// a.png
// b.png
// then AssetDir("data") would return []string{"foo.txt", "img"}
// AssetDir("data/img") would return []string{"a.png", "b.png"}
// AssetDir("foo.txt") and AssetDir("notexist") would return an error
// AssetDir("") will return []string{"data"}.
func AssetDir(name string) ([]string, error) {
node := _bintree
if len(name) != 0 {
cannonicalName := strings.Replace(name, "\\", "/", -1)
pathList := strings.Split(cannonicalName, "/")
for _, p := range pathList {
node = node.Children[p]
if node == nil {
return nil, fmt.Errorf("Asset %s not found", name)
}
}
}
if node.Func != nil {
return nil, fmt.Errorf("Asset %s not found", name)
}
rv := make([]string, 0, len(node.Children))
for name := range node.Children {
rv = append(rv, name)
}
return rv, nil
}

type _bintree_t struct {
Func func() ([]byte, error)
Children map[string]*_bintree_t
}
var _bintree = &_bintree_t{nil, map[string]*_bintree_t{
"assets": &_bintree_t{nil, map[string]*_bintree_t{
"index.html": &_bintree_t{assets_index_html, map[string]*_bintree_t{
}},
}},
}}
8 changes: 8 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module github.com/mitjafelicijan/journalctl-proxy

go 1.16

require (
github.com/gofiber/fiber/v2 v2.6.0
github.com/gofiber/websocket/v2 v2.0.2
)
39 changes: 39 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
github.com/andybalholm/brotli v1.0.0 h1:7UCwP93aiSfvWpapti8g88vVVGp2qqtGyePsSuDafo4=
github.com/andybalholm/brotli v1.0.0/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y=
github.com/fasthttp/websocket v1.4.3 h1:qjhRJ/rTy4KB8oBxljEC00SDt6HUY9jLRfM601SUdS4=
github.com/fasthttp/websocket v1.4.3/go.mod h1:5r4oKssgS7W6Zn6mPWap3NWzNPJNzUUh3baWTOhcYQk=
github.com/gofiber/fiber/v2 v2.1.0/go.mod h1:aG+lMkwy3LyVit4CnmYUbUdgjpc3UYOltvlJZ78rgQ0=
github.com/gofiber/fiber/v2 v2.6.0 h1:OywSUL6QPY/+/b89Ulnb8reovwm5QGjZQfk74v0R7Uc=
github.com/gofiber/fiber/v2 v2.6.0/go.mod h1:f8BRRIMjMdRyt2qmJ/0Sea3j3rwwfufPrh9WNBRiVZ0=
github.com/gofiber/websocket/v2 v2.0.2 h1:UA/6NpyG+vmPGlvJvW8MJPJpRFuS7abinZ5HbLuV8u0=
github.com/gofiber/websocket/v2 v2.0.2/go.mod h1:7VBnzEVRK0K0eTIVc5GbXPF1JWUFnllY0X4cRtG2v78=
github.com/klauspost/compress v1.10.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/klauspost/compress v1.10.7 h1:7rix8v8GpI3ZBb0nSozFRgbtXKv+hOe+qfEpZqybrAg=
github.com/klauspost/compress v1.10.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/savsgio/gotils v0.0.0-20200608150037-a5f6f5aef16c h1:2nF5+FZ4/qp7pZVL7fR6DEaSTzuDmNaFTyqp92/hwF8=
github.com/savsgio/gotils v0.0.0-20200608150037-a5f6f5aef16c/go.mod h1:TWNAOTaVzGOXq8RbEvHnhzA/A2sLZzgn0m6URjnukY8=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasthttp v1.14.0/go.mod h1:ol1PCaL0dX20wC0htZ7sYCsvCYmrouYra0zHzaclZhE=
github.com/valyala/fasthttp v1.16.0/go.mod h1:YOKImeEosDdBPnxc0gy7INqi3m1zK6A+xl6TwOBhHCA=
github.com/valyala/fasthttp v1.18.0 h1:IV0DdMlatq9QO1Cr6wGJPVW1sV1Q8HvZXAIcjorylyM=
github.com/valyala/fasthttp v1.18.0/go.mod h1:jjraHZVbKOXftJfsOYoAjaeygpj5hr8ermTRJNroD7A=
github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a h1:0R4NLDRDZX6JcmhJgXi5E4b8Wg84ihbmUKp/GvSPEzc=
github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20201016165138-7b1cca2348c0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201210223839-7e3030f88018 h1:XKi8B/gRBuTZN1vU9gFsLMm6zVz5FSCDzm8JYACnjy8=
golang.org/x/sys v0.0.0-20201210223839-7e3030f88018/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
80 changes: 80 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package main

import (
"bufio"
"flag"
"fmt"
"log"
"os/exec"

"github.com/gofiber/fiber/v2"
"github.com/gofiber/fiber/v2/middleware/logger"
"github.com/gofiber/fiber/v2/middleware/recover"
"github.com/gofiber/websocket/v2"
)

func main() {
var port int

flag.IntVar(&port, "p", 8000, "Server port number")
flag.Parse()

app := fiber.New(fiber.Config{
Prefork: false,
})

app.Use(recover.New())
app.Use(logger.New())

app.Get("/", func(c *fiber.Ctx) error {
data, err := Asset("assets/index.html")
if err != nil {
fmt.Println(err)
}

c.Type("html", "utf-8")
return c.SendString(string(data))
})

app.Get("/list-services", func(c *fiber.Ctx) error {
out, err := exec.Command("systemctl", "list-units", "--type=service", "--state=running", "--no-pager").Output()

if err != nil {
fmt.Printf("%s", err)
}

return c.SendString(string(out[:]))
})

app.Use("/ws", func(c *fiber.Ctx) error {
if websocket.IsWebSocketUpgrade(c) {
c.Locals("allowed", true)
return c.Next()
}
return fiber.ErrUpgradeRequired
})

app.Get("/ws/:id", websocket.New(func(c *websocket.Conn) {
var messageType int = 1
var message []byte
var err error

cmd := exec.Command("journalctl", "-b", "-u", fmt.Sprintf("%s.service", c.Params("id")), "-f", "-n", "5", "-o", "json")
stdout, _ := cmd.StdoutPipe()
cmd.Start()

scanner := bufio.NewScanner(stdout)
for scanner.Scan() {
message = []byte(scanner.Text())
if err = c.WriteMessage(messageType, message); err != nil {
log.Println(err)
}
}

cmd.Wait()
}, websocket.Config{
WriteBufferSize: 8192,
}))

log.Fatal(app.Listen(fmt.Sprintf(":%d", port)))
}
Loading

0 comments on commit d18f552

Please sign in to comment.