get logging
This commit is contained in:
parent
815e453acf
commit
f4aa0ac02b
@ -46,6 +46,16 @@ def write_json(data):
|
|||||||
json.dump(data, outfile, indent=4)
|
json.dump(data, outfile, indent=4)
|
||||||
|
|
||||||
|
|
||||||
|
def read_log(type):
|
||||||
|
config = read_yaml()
|
||||||
|
log_path = config['logging']['log_path']
|
||||||
|
log_file = os.path.join(log_path, '{}.log'.format(type))
|
||||||
|
|
||||||
|
if os.path.isfile(log_file):
|
||||||
|
with open(log_file, 'r') as log:
|
||||||
|
return log.read().strip()
|
||||||
|
|
||||||
|
|
||||||
def sizeof_fmt(num, suffix='B'):
|
def sizeof_fmt(num, suffix='B'):
|
||||||
for unit in ['', 'Ki', 'Mi', 'Gi', 'Ti', 'Pi', 'Ei', 'Zi']:
|
for unit in ['', 'Ki', 'Mi', 'Gi', 'Ti', 'Pi', 'Ei', 'Zi']:
|
||||||
if abs(num) < 1024.0:
|
if abs(num) < 1024.0:
|
||||||
@ -61,7 +71,8 @@ class PlayoutService:
|
|||||||
self.proc = None
|
self.proc = None
|
||||||
|
|
||||||
def run_cmd(self):
|
def run_cmd(self):
|
||||||
self.proc = run(self.cmd + self.service, stdout=PIPE, stderr=STDOUT, encoding="utf-8").stdout
|
self.proc = run(self.cmd + self.service, stdout=PIPE, stderr=STDOUT,
|
||||||
|
encoding="utf-8").stdout
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
self.cmd.append('start')
|
self.cmd.append('start')
|
||||||
@ -86,8 +97,8 @@ class PlayoutService:
|
|||||||
return self.proc.replace('\n', '')
|
return self.proc.replace('\n', '')
|
||||||
|
|
||||||
def log(self):
|
def log(self):
|
||||||
self.cmd = ['sudo', '/bin/systemctl', 'journalctl',
|
self.cmd = ['sudo', '/bin/journalctl', '-n', '1000', '-u']
|
||||||
'-n', '1000', '-u'] + self.service
|
|
||||||
self.run_cmd()
|
self.run_cmd()
|
||||||
|
|
||||||
return self.proc
|
return self.proc
|
||||||
|
@ -12,7 +12,7 @@ from rest_framework.response import Response
|
|||||||
from rest_framework.views import APIView
|
from rest_framework.views import APIView
|
||||||
|
|
||||||
from .utils import (PlayoutService, SystemStats, get_media_path, read_json,
|
from .utils import (PlayoutService, SystemStats, get_media_path, read_json,
|
||||||
read_yaml, write_json, write_yaml)
|
read_yaml, write_json, write_yaml, read_log)
|
||||||
|
|
||||||
|
|
||||||
class CurrentUserView(APIView):
|
class CurrentUserView(APIView):
|
||||||
@ -104,6 +104,22 @@ class SystemCtl(APIView):
|
|||||||
return Response({"success": False})
|
return Response({"success": False})
|
||||||
|
|
||||||
|
|
||||||
|
class LogReader(APIView):
|
||||||
|
def get(self, request, *args, **kwargs):
|
||||||
|
if 'type' in request.GET.dict():
|
||||||
|
type = request.GET.dict()['type']
|
||||||
|
log = read_log(type)
|
||||||
|
|
||||||
|
if log:
|
||||||
|
return Response({'log': log})
|
||||||
|
else:
|
||||||
|
return Response({
|
||||||
|
"success": False,
|
||||||
|
"error": "PLayout log file not found!"})
|
||||||
|
else:
|
||||||
|
return Response({"success": False})
|
||||||
|
|
||||||
|
|
||||||
class Playlist(APIView):
|
class Playlist(APIView):
|
||||||
"""
|
"""
|
||||||
read and write config from ffplayout engine
|
read and write config from ffplayout engine
|
||||||
|
@ -35,6 +35,7 @@ urlpatterns = [
|
|||||||
path('api/system/', views.SystemCtl.as_view()),
|
path('api/system/', views.SystemCtl.as_view()),
|
||||||
path('api/playlist/', views.Playlist.as_view()),
|
path('api/playlist/', views.Playlist.as_view()),
|
||||||
path('api/stats/', views.Statistics.as_view()),
|
path('api/stats/', views.Statistics.as_view()),
|
||||||
|
path('api/log/', views.LogReader.as_view()),
|
||||||
path('api/current/user/', views.CurrentUserView.as_view()),
|
path('api/current/user/', views.CurrentUserView.as_view()),
|
||||||
path('api/media/', views.Media.as_view()),
|
path('api/media/', views.Media.as_view()),
|
||||||
re_path(r'^api/media/upload/(?P<filename>[^/]+)$', views.FileUpload.as_view()),
|
re_path(r'^api/media/upload/(?P<filename>[^/]+)$', views.FileUpload.as_view()),
|
||||||
|
@ -397,7 +397,7 @@ export default {
|
|||||||
{ headers: { Authorization: 'Bearer ' + this.$store.state.auth.jwtToken } }
|
{ headers: { Authorization: 'Bearer ' + this.$store.state.auth.jwtToken } }
|
||||||
)
|
)
|
||||||
|
|
||||||
await this.getStatus()
|
setTimeout(() => { this.getStatus() }, 1000)
|
||||||
},
|
},
|
||||||
async getPlaylist () {
|
async getPlaylist () {
|
||||||
await this.$store.dispatch('auth/inspectToken')
|
await this.$store.dispatch('auth/inspectToken')
|
||||||
|
@ -1,75 +1,82 @@
|
|||||||
<template>
|
<template>
|
||||||
<div style="height:100%;">
|
<div>
|
||||||
<Menu />
|
<Menu />
|
||||||
<div class="logging">
|
<b-card no-body>
|
||||||
1<br>
|
<b-tabs pills card vertical>
|
||||||
2<br>
|
<b-tab title="Playout" active @click="getLog('ffplayout')">
|
||||||
3<br>
|
<b-container class="log-container">
|
||||||
4<br>
|
<!-- eslint-disable-next-line -->
|
||||||
5<br>
|
<pre v-if="currentLog" :inner-html.prop="currentLog | formatStr" class="log-content" />
|
||||||
6<br>
|
</b-container>
|
||||||
7<br>
|
</b-tab>
|
||||||
8<br>
|
<b-tab title="Decoder" @click="getLog('decoder')">
|
||||||
9<br>
|
<b-container class="log-container">
|
||||||
10<br>
|
<!-- eslint-disable-next-line -->
|
||||||
11<br>
|
<pre v-if="currentLog" :inner-html.prop="currentLog | formatStr" class="log-content" />
|
||||||
12<br>
|
</b-container>
|
||||||
13<br>
|
</b-tab>
|
||||||
14<br>
|
<b-tab title="Encoder" @click="getLog('encoder')">
|
||||||
15<br>
|
<b-container class="log-container">
|
||||||
16<br>
|
<!-- eslint-disable-next-line -->
|
||||||
17<br>
|
<pre v-if="currentLog" :inner-html.prop="currentLog | formatStr" class="log-content" />
|
||||||
18<br>
|
</b-container>
|
||||||
19<br>
|
</b-tab>
|
||||||
20<br>
|
<b-tab title="System" @click="getSystemLog()">
|
||||||
1<br>
|
<b-container class="log-container">
|
||||||
2<br>
|
<!-- eslint-disable-next-line -->
|
||||||
3<br>
|
<pre v-if="currentLog" :inner-html.prop="currentLog | formatStr" class="log-content" />
|
||||||
4<br>
|
</b-container>
|
||||||
5<br>
|
</b-tab>
|
||||||
6<br>
|
</b-tabs>
|
||||||
7<br>
|
</b-card>
|
||||||
8<br>
|
<Login :show="showLogin" />
|
||||||
9<br>
|
|
||||||
10<br>
|
|
||||||
11<br>
|
|
||||||
12<br>
|
|
||||||
13<br>
|
|
||||||
14<br>
|
|
||||||
15<br>
|
|
||||||
16<br>
|
|
||||||
17<br>
|
|
||||||
18<br>
|
|
||||||
19<br>
|
|
||||||
20<br>
|
|
||||||
10<br>
|
|
||||||
11<br>
|
|
||||||
12<br>
|
|
||||||
13<br>
|
|
||||||
14<br>
|
|
||||||
15<br>
|
|
||||||
16<br>
|
|
||||||
17<br>
|
|
||||||
18<br>
|
|
||||||
19<br>
|
|
||||||
20<br>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// import { mapState } from 'vuex'
|
// import { mapState } from 'vuex'
|
||||||
import Menu from '@/components/Menu.vue'
|
import Menu from '@/components/Menu.vue'
|
||||||
|
import Login from '@/components/Login.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Media',
|
name: 'Media',
|
||||||
|
|
||||||
components: {
|
components: {
|
||||||
Menu
|
Menu,
|
||||||
|
Login
|
||||||
|
},
|
||||||
|
|
||||||
|
filters: {
|
||||||
|
formatStr (text) {
|
||||||
|
return text
|
||||||
|
.replace(/("\[.*")/g, '<span class="log-cmd">$1</span>')
|
||||||
|
.replace(/("\/.*")/g, '<span class="log-path">$1</span>')
|
||||||
|
.replace(/(\/[\w\d.\-/]+\n)/g, '<span class="log-path">$1</span>')
|
||||||
|
.replace(/((tcp|https?):\/\/[\w\d.:]+)/g, '<span class="log-url">$1</span>')
|
||||||
|
.replace(/(\[\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}[0-9,.]+\])/g, '<span class="log-time">$1</span>')
|
||||||
|
.replace(/\[INFO\]/g, '<span class="log-info">[INFO]</span>')
|
||||||
|
.replace(/\[WARNING\]/g, '<span class="log-warning">[WARNING]</span>')
|
||||||
|
.replace(/\[ERROR\]/g, '<span class="log-error">[ERROR]</span>')
|
||||||
|
.replace(/\[DEBUG\]/g, '<span class="log-debug">[DEBUG]</span>')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
async asyncData ({ app, store }) {
|
||||||
|
await store.dispatch('auth/inspectToken')
|
||||||
|
let login = false
|
||||||
|
|
||||||
|
if (!store.state.auth.isLogin) {
|
||||||
|
login = true
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
showLogin: login
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
|
currentLog: null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -77,16 +84,91 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
async created () {
|
async created () {
|
||||||
|
await this.getLog('ffplayout')
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
|
async getLog (type) {
|
||||||
|
await this.$store.dispatch('auth/inspectToken')
|
||||||
|
const response = await this.$axios.get(
|
||||||
|
`api/log/?type=${type}`,
|
||||||
|
{ headers: { Authorization: 'Bearer ' + this.$store.state.auth.jwtToken } }
|
||||||
|
)
|
||||||
|
|
||||||
|
if (response.data.log) {
|
||||||
|
this.currentLog = response.data.log
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async getSystemLog () {
|
||||||
|
await this.$store.dispatch('auth/inspectToken')
|
||||||
|
const response = await this.$axios.post(
|
||||||
|
'api/system/',
|
||||||
|
{ run: 'log' },
|
||||||
|
{ headers: { Authorization: 'Bearer ' + this.$store.state.auth.jwtToken } }
|
||||||
|
)
|
||||||
|
|
||||||
|
console.log(response.data.data)
|
||||||
|
|
||||||
|
if (response.data.data) {
|
||||||
|
this.currentLog = response.data.data
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
.col-auto {
|
||||||
|
width: 122px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-content {
|
||||||
|
max-width: calc(100% - 122px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.log-container {
|
||||||
|
background: #1d2024;
|
||||||
|
max-width: 95%;
|
||||||
|
padding: 1em;
|
||||||
|
}
|
||||||
.logging {
|
.logging {
|
||||||
height: 50%;
|
height: 50%;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.log-content {
|
||||||
|
color: #ececec;
|
||||||
|
}
|
||||||
|
|
||||||
|
.log-time {
|
||||||
|
color: #a7a7a7;
|
||||||
|
}
|
||||||
|
|
||||||
|
.log-info {
|
||||||
|
color: #51d1de;
|
||||||
|
}
|
||||||
|
|
||||||
|
.log-warning {
|
||||||
|
color: #e4a428;
|
||||||
|
}
|
||||||
|
|
||||||
|
.log-error {
|
||||||
|
color: #e42e28;
|
||||||
|
}
|
||||||
|
|
||||||
|
.log-debug {
|
||||||
|
color: #23e493;
|
||||||
|
}
|
||||||
|
|
||||||
|
.log-path {
|
||||||
|
color: #e366cf;
|
||||||
|
}
|
||||||
|
|
||||||
|
.log-url {
|
||||||
|
color: #e3d666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.log-cmd {
|
||||||
|
color: #f1aa77;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user