-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
b95aa7b
commit d18f552
Showing
9 changed files
with
398 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
release/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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{ | ||
}}, | ||
}}, | ||
}} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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))) | ||
} |
Oops, something went wrong.