Fix websocket for #384

This commit is contained in:
simon987 2023-07-12 19:39:52 -04:00
parent a0b6eed037
commit 84958502b1
2 changed files with 195 additions and 186 deletions

View File

@ -1,14 +1,15 @@
<template> <template>
<div id="app"> <div id="app">
<NavBar></NavBar> <NavBar></NavBar>
<b-container class="pt-4"> <b-container class="pt-4">
<b-alert show dismissible variant="info"> <b-alert show dismissible variant="info">
This is a beta version of sist2-admin. Please submit bug reports, usability issues and feature requests This is a beta version of sist2-admin. Please submit bug reports, usability issues and feature requests
to the <a href="https://github.com/simon987/sist2/issues/new/choose" target="_blank">issue tracker on Github</a>. Thank you! to the <a href="https://github.com/simon987/sist2/issues/new/choose" target="_blank">issue tracker on
</b-alert> Github</a>. Thank you!
<router-view/> </b-alert>
</b-container> <router-view/>
</div> </b-container>
</div>
</template> </template>
<script> <script>
@ -16,83 +17,87 @@ import NavBar from "@/components/NavBar";
import Sist2AdminApi from "@/Sist2AdminApi"; import Sist2AdminApi from "@/Sist2AdminApi";
export default { export default {
components: {NavBar}, components: {NavBar},
data() { data() {
return { return {
socket: null socket: null
}
},
mounted() {
Sist2AdminApi.getSist2AdminInfo()
.then(resp => this.$store.commit("setSist2AdminInfo", resp.data));
this.$store.dispatch("loadBrowserSettings");
this.connectNotifications();
// this.socket.onclose = this.connectNotifications;
},
methods: {
connectNotifications() {
this.socket = new WebSocket(`ws://${window.location.host}/notifications`);
this.socket.onopen = () => {
this.socket.send("Hello from client");
}
this.socket.onmessage = e => {
const notification = JSON.parse(e.data);
if (notification.message) {
notification.messageString = this.$t(notification.message).toString();
} }
},
mounted() {
Sist2AdminApi.getSist2AdminInfo()
.then(resp => this.$store.commit("setSist2AdminInfo", resp.data));
this.$store.dispatch("loadBrowserSettings");
this.connectNotifications();
// this.socket.onclose = this.connectNotifications;
},
methods: {
connectNotifications() {
if (window.location.protocol === "https:") {
this.socket = new WebSocket(`wss://${window.location.host}/notifications`);
} else {
this.socket = new WebSocket(`ws://${window.location.host}/notifications`);
}
this.socket.onopen = () => {
this.socket.send("Hello from client");
}
this.$store.dispatch("notify", notification) this.socket.onmessage = e => {
} const notification = JSON.parse(e.data);
if (notification.message) {
notification.messageString = this.$t(notification.message).toString();
}
this.$store.dispatch("notify", notification)
}
}
} }
}
} }
</script> </script>
<style> <style>
html, body { html, body {
height: 100%; height: 100%;
} }
#app { #app {
/*font-family: Avenir, Helvetica, Arial, sans-serif;*/ /*font-family: Avenir, Helvetica, Arial, sans-serif;*/
-webkit-font-smoothing: antialiased; -webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale; -moz-osx-font-smoothing: grayscale;
/*text-align: center;*/ /*text-align: center;*/
color: #2c3e50; color: #2c3e50;
padding-bottom: 1em; padding-bottom: 1em;
min-height: 100%; min-height: 100%;
} }
.info-icon { .info-icon {
width: 1rem; width: 1rem;
margin-right: 0.2rem; margin-right: 0.2rem;
cursor: pointer; cursor: pointer;
line-height: 1rem; line-height: 1rem;
height: 1rem; height: 1rem;
background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4PSIwcHgiIHk9IjBweCIKICAgICB2aWV3Qm94PSIwIDAgNDI2LjY2NyA0MjYuNjY3IiBzdHlsZT0iZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCA0MjYuNjY3IDQyNi42Njc7IiBmaWxsPSIjZmZmIj4KPGc+CiAgICA8Zz4KICAgICAgICA8Zz4KICAgICAgICAgICAgPHJlY3QgeD0iMTkyIiB5PSIxOTIiIHdpZHRoPSI0Mi42NjciIGhlaWdodD0iMTI4Ii8+CiAgICAgICAgICAgIDxwYXRoIGQ9Ik0yMTMuMzMzLDBDOTUuNDY3LDAsMCw5NS40NjcsMCwyMTMuMzMzczk1LjQ2NywyMTMuMzMzLDIxMy4zMzMsMjEzLjMzM1M0MjYuNjY3LDMzMS4yLDQyNi42NjcsMjEzLjMzMwogICAgICAgICAgICAgICAgUzMzMS4yLDAsMjEzLjMzMywweiBNMjEzLjMzMywzODRjLTk0LjA4LDAtMTcwLjY2Ny03Ni41ODctMTcwLjY2Ny0xNzAuNjY3UzExOS4yNTMsNDIuNjY3LDIxMy4zMzMsNDIuNjY3CiAgICAgICAgICAgICAgICBTMzg0LDExOS4yNTMsMzg0LDIxMy4zMzNTMzA3LjQxMywzODQsMjEzLjMzMywzODR6Ii8+CiAgICAgICAgICAgIDxyZWN0IHg9IjE5MiIgeT0iMTA2LjY2NyIgd2lkdGg9IjQyLjY2NyIgaGVpZ2h0PSI0Mi42NjciLz4KICAgICAgICA8L2c+CiAgICA8L2c+CjwvZz4KPC9zdmc+Cg==); background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4PSIwcHgiIHk9IjBweCIKICAgICB2aWV3Qm94PSIwIDAgNDI2LjY2NyA0MjYuNjY3IiBzdHlsZT0iZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCA0MjYuNjY3IDQyNi42Njc7IiBmaWxsPSIjZmZmIj4KPGc+CiAgICA8Zz4KICAgICAgICA8Zz4KICAgICAgICAgICAgPHJlY3QgeD0iMTkyIiB5PSIxOTIiIHdpZHRoPSI0Mi42NjciIGhlaWdodD0iMTI4Ii8+CiAgICAgICAgICAgIDxwYXRoIGQ9Ik0yMTMuMzMzLDBDOTUuNDY3LDAsMCw5NS40NjcsMCwyMTMuMzMzczk1LjQ2NywyMTMuMzMzLDIxMy4zMzMsMjEzLjMzM1M0MjYuNjY3LDMzMS4yLDQyNi42NjcsMjEzLjMzMwogICAgICAgICAgICAgICAgUzMzMS4yLDAsMjEzLjMzMywweiBNMjEzLjMzMywzODRjLTk0LjA4LDAtMTcwLjY2Ny03Ni41ODctMTcwLjY2Ny0xNzAuNjY3UzExOS4yNTMsNDIuNjY3LDIxMy4zMzMsNDIuNjY3CiAgICAgICAgICAgICAgICBTMzg0LDExOS4yNTMsMzg0LDIxMy4zMzNTMzA3LjQxMywzODQsMjEzLjMzMywzODR6Ii8+CiAgICAgICAgICAgIDxyZWN0IHg9IjE5MiIgeT0iMTA2LjY2NyIgd2lkdGg9IjQyLjY2NyIgaGVpZ2h0PSI0Mi42NjciLz4KICAgICAgICA8L2c+CiAgICA8L2c+CjwvZz4KPC9zdmc+Cg==);
filter: brightness(45%); filter: brightness(45%);
display: block; display: block;
} }
.tabs { .tabs {
margin-top: 10px; margin-top: 10px;
} }
.modal-title { .modal-title {
text-overflow: ellipsis; text-overflow: ellipsis;
overflow: hidden; overflow: hidden;
white-space: nowrap; white-space: nowrap;
} }
@media screen and (min-width: 1500px) { @media screen and (min-width: 1500px) {
.container { .container {
max-width: 1440px; max-width: 1440px;
} }
} }
label { label {
margin-top: 0.5rem; margin-top: 0.5rem;
margin-bottom: 0; margin-bottom: 0;
} }
</style> </style>

View File

@ -1,168 +1,172 @@
<template> <template>
<b-card> <b-card>
<b-card-body> <b-card-body>
<h4 class="mb-3">{{ taskId }} {{ $t("logs") }}</h4> <h4 class="mb-3">{{ taskId }} {{ $t("logs") }}</h4>
<div v-if="$store.state.sist2AdminInfo"> <div v-if="$store.state.sist2AdminInfo">
{{ $t("logFile") }} {{ $t("logFile") }}
<code>{{ $store.state.sist2AdminInfo.logs_folder }}/sist2-{{ taskId }}.log</code> <code>{{ $store.state.sist2AdminInfo.logs_folder }}/sist2-{{ taskId }}.log</code>
<br/> <br/>
<br/> <br/>
</div> </div>
<b-row> <b-row>
<b-col> <b-col>
<span>{{ $t("logLevel") }}</span> <span>{{ $t("logLevel") }}</span>
<b-select :options="levels.slice(0, -1)" v-model="logLevel" @input="connect()"></b-select> <b-select :options="levels.slice(0, -1)" v-model="logLevel" @input="connect()"></b-select>
</b-col> </b-col>
<b-col> <b-col>
<span>{{ $t("logMode") }}</span> <span>{{ $t("logMode") }}</span>
<b-select :options="modeOptions" v-model="mode" @input="connect()"></b-select> <b-select :options="modeOptions" v-model="mode" @input="connect()"></b-select>
</b-col> </b-col>
</b-row> </b-row>
<div id="log-tail-output" class="mt-3 ml-1"></div> <div id="log-tail-output" class="mt-3 ml-1"></div>
</b-card-body> </b-card-body>
</b-card> </b-card>
</template> </template>
<script> <script>
export default { export default {
name: "Tail", name: "Tail",
data() { data() {
return { return {
logLevel: "DEBUG", logLevel: "DEBUG",
levels: ["DEBUG", "INFO", "WARNING", "ERROR", "ADMIN", "FATAL"], levels: ["DEBUG", "INFO", "WARNING", "ERROR", "ADMIN", "FATAL"],
socket: null, socket: null,
mode: "follow", mode: "follow",
modeOptions: [ modeOptions: [
{ {
"text": this.$t('follow'), "text": this.$t('follow'),
"value": "follow" "value": "follow"
}, },
{ {
"text": this.$t('wholeFile'), "text": this.$t('wholeFile'),
"value": "wholeFile" "value": "wholeFile"
}
]
} }
] },
computed: {
taskId: function () {
return this.$route.params.taskId;
}
},
methods: {
connect() {
let lineCount = 0;
const outputElem = document.getElementById("log-tail-output")
outputElem.replaceChildren();
if (this.socket !== null) {
this.socket.close();
}
const n = this.mode === "follow" ? 32 : 9999999999;
if (window.location.protocol === "https:") {
this.socket = new WebSocket(`wss://${window.location.host}/log/${this.taskId}?n=${n}`);
} else {
this.socket = new WebSocket(`ws://${window.location.host}/log/${this.taskId}?n=${n}`);
}
this.socket.onopen = () => {
this.socket.send("Hello from client");
}
this.socket.onmessage = e => {
let message;
try {
message = JSON.parse(e.data);
} catch {
console.error(e.data)
return;
}
if ("ping" in message) {
return;
}
if (message.level === undefined) {
if ("stderr" in message) {
message.level = "ERROR";
message.message = message["stderr"];
} else {
message.level = "ADMIN";
message.message = message["sist2-admin"];
}
message.datetime = ""
message.filepath = ""
}
if (this.levels.indexOf(message.level) < this.levels.indexOf(this.logLevel)) {
return;
}
const logLine = `${message.datetime} [${message.level} ${message.filepath}] ${message.message}`;
const span = document.createElement("span");
span.setAttribute("class", message.level);
span.appendChild(document.createTextNode(logLine));
outputElem.appendChild(span);
lineCount += 1;
if (this.mode === "follow" && lineCount >= n) {
outputElem.firstChild.remove();
}
}
}
},
mounted() {
this.connect()
} }
},
computed: {
taskId: function () {
return this.$route.params.taskId;
}
},
methods: {
connect() {
let lineCount = 0;
const outputElem = document.getElementById("log-tail-output")
outputElem.replaceChildren();
if (this.socket !== null) {
this.socket.close();
}
const n = this.mode === "follow" ? 32 : 9999999999;
this.socket = new WebSocket(`ws://${window.location.host}/log/${this.taskId}?n=${n}`);
this.socket.onopen = () => {
this.socket.send("Hello from client");
}
this.socket.onmessage = e => {
let message;
try {
message = JSON.parse(e.data);
} catch {
console.error(e.data)
return;
}
if ("ping" in message) {
return;
}
if (message.level === undefined) {
if ("stderr" in message) {
message.level = "ERROR";
message.message = message["stderr"];
} else {
message.level = "ADMIN";
message.message = message["sist2-admin"];
}
message.datetime = ""
message.filepath = ""
}
if (this.levels.indexOf(message.level) < this.levels.indexOf(this.logLevel)) {
return;
}
const logLine = `${message.datetime} [${message.level} ${message.filepath}] ${message.message}`;
const span = document.createElement("span");
span.setAttribute("class", message.level);
span.appendChild(document.createTextNode(logLine));
outputElem.appendChild(span);
lineCount += 1;
if (this.mode === "follow" && lineCount >= n) {
outputElem.firstChild.remove();
}
}
}
},
mounted() {
this.connect()
}
} }
</script> </script>
<style> <style>
#log-tail-output span { #log-tail-output span {
display: block; display: block;
} }
span.DEBUG { span.DEBUG {
color: #9E9E9E; color: #9E9E9E;
} }
span.WARNING { span.WARNING {
color: #FFB300; color: #FFB300;
} }
span.INFO { span.INFO {
color: #039BE5; color: #039BE5;
} }
span.ERROR { span.ERROR {
color: #F4511E; color: #F4511E;
} }
span.FATAL { span.FATAL {
color: #F4511E; color: #F4511E;
} }
span.ADMIN { span.ADMIN {
color: #ee05ff; color: #ee05ff;
} }
#log-tail-output { #log-tail-output {
font-size: 13px; font-size: 13px;
font-family: monospace; font-family: monospace;
padding: 6px; padding: 6px;
background-color: #f5f5f5; background-color: #f5f5f5;
border: 1px solid #ccc; border: 1px solid #ccc;
border-radius: 4px; border-radius: 4px;
margin: 3px; margin: 3px;
white-space: pre; white-space: pre;
color: #000; color: #000;
overflow: hidden; overflow: hidden;
} }
</style> </style>