2020-01-29 21:37:25 +02:00
< template >
2020-08-09 09:51:02 +03:00
< div v-if = "meta" class="xhexznfu" v-size="{ min: [1600] }" >
2020-01-29 21:37:25 +02:00
< portal to = "icon" > < fa :icon = "faServer" / > < / portal >
2020-07-24 19:56:52 +03:00
< portal to = "title" > { { $t ( 'instance' ) } } < / portal >
2020-01-29 21:37:25 +02:00
2020-08-09 09:51:02 +03:00
< mk-folder >
< template # header > < fa :icon = "faTachometerAlt" / > { { $t ( 'overview' ) } } < / template >
2020-08-13 11:58:16 +03:00
< div class = "sboqnrfi" : style = "{ gridTemplateRows: overviewHeight }" >
< mk-instance-stats :chart-limit = "300" :detailed = "true" class = "stats" ref = "stats" / >
2020-08-09 09:51:02 +03:00
< div class = "column" >
2020-08-13 11:58:16 +03:00
< mk-container :body-togglable = "true" : resize -base -el = " ( ) = > $el " class=" info " >
2020-08-09 09:51:02 +03:00
< template # header > < fa :icon = "faInfoCircle" / > { { $t ( 'instanceInfo' ) } } < / template >
2020-02-18 14:27:43 +02:00
2020-08-09 09:51:02 +03:00
< div class = "_content" >
< div class = "_keyValue" > < b > Misskey < / b > < span > v { { version } } < / span > < / div >
< / div >
< div class = "_content" v-if = "serverInfo" >
< div class = "_keyValue" > < b > Node . js < / b > < span > { { serverInfo . node } } < / span > < / div >
< div class = "_keyValue" > < b > PostgreSQL < / b > < span > v { { serverInfo . psql } } < / span > < / div >
< div class = "_keyValue" > < b > Redis < / b > < span > v { { serverInfo . redis } } < / span > < / div >
< / div >
< / mk-container >
2020-08-13 11:58:16 +03:00
< mk-container :body-togglable = "true" :scrollable = "true" : resize -base -el = " ( ) = > $el " class=" db " >
< template # header > < fa :icon = "faDatabase" / > { { $t ( 'database' ) } } < / template >
2020-08-09 09:51:02 +03:00
2020-08-13 11:58:16 +03:00
< div class = "_content" v-if = "dbInfo" >
< div class = "_keyValue" v-for = "table in Object.entries(dbInfo)" > < b > { { table [ 0 ] } } < / b > < span > { { table [ 1 ] . count | number } } < / span > < span > { { table [ 1 ] . size | bytes } } < / span > < / div >
< / div >
< / mk-container >
< mkw-federation class = "fed" / >
2020-02-18 14:27:43 +02:00
< / div >
< / div >
2020-08-09 09:51:02 +03:00
< / mk-folder >
2020-02-18 14:27:43 +02:00
2020-08-09 09:51:02 +03:00
< mk-folder style = "margin: var(--margin) 0;" >
< template # header > < fa :icon = "faHeartbeat" / > { { $t ( 'metrics' ) } } < / template >
< div class = "segusily" >
< mk-container :body-togglable = "false" : resize -base -el = " ( ) = > $el " >
< template # header > < fa :icon = "faMicrochip" / > { { $t ( 'cpuAndMemory' ) } } < / template >
< div class = "_content" style = "margin-top: -8px; margin-bottom: -12px;" >
< canvas ref = "cpumem" > < / canvas >
2020-02-16 19:21:27 +02:00
< / div >
2020-08-09 09:51:02 +03:00
< div class = "_content" v-if = "serverInfo" >
< div class = "_table" >
<!--
< div class = "_row" >
< div class = "_cell" > < div class = "_label" > CPU < / div > { { serverInfo . cpu . model } } < / div >
< / div >
-- >
< div class = "_row" >
< div class = "_cell" > < div class = "_label" > MEM total < / div > { { serverInfo . mem . total | bytes } } < / div >
< div class = "_cell" > < div class = "_label" > MEM used < / div > { { memUsage | bytes } } ( { { ( memUsage / serverInfo . mem . total * 100 ) . toFixed ( 0 ) } } % ) < / div >
< div class = "_cell" > < div class = "_label" > MEM free < / div > { { serverInfo . mem . total - memUsage | bytes } } ( { { ( ( serverInfo . mem . total - memUsage ) / serverInfo . mem . total * 100 ) . toFixed ( 0 ) } } % ) < / div >
< / div >
< / div >
2020-02-16 19:21:27 +02:00
< / div >
2020-08-09 09:51:02 +03:00
< / mk-container >
< mk-container :body-togglable = "false" : resize -base -el = " ( ) = > $el " >
< template # header > < fa :icon = "faHdd" / > { { $t ( 'disk' ) } } < / template >
< div class = "_content" style = "margin-top: -8px; margin-bottom: -12px;" >
< canvas ref = "disk" > < / canvas >
2020-02-16 19:21:27 +02:00
< / div >
2020-08-09 09:51:02 +03:00
< div class = "_content" v-if = "serverInfo" >
< div class = "_table" >
< div class = "_row" >
< div class = "_cell" > < div class = "_label" > Disk total < / div > { { serverInfo . fs . total | bytes } } < / div >
< div class = "_cell" > < div class = "_label" > Disk used < / div > { { serverInfo . fs . used | bytes } } ( { { ( serverInfo . fs . used / serverInfo . fs . total * 100 ) . toFixed ( 0 ) } } % ) < / div >
< div class = "_cell" > < div class = "_label" > Disk free < / div > { { serverInfo . fs . total - serverInfo . fs . used | bytes } } ( { { ( ( serverInfo . fs . total - serverInfo . fs . used ) / serverInfo . fs . total * 100 ) . toFixed ( 0 ) } } % ) < / div >
< / div >
< / div >
2020-02-16 19:21:27 +02:00
< / div >
2020-08-09 09:51:02 +03:00
< / mk-container >
< mk-container :body-togglable = "false" : resize -base -el = " ( ) = > $el " >
< template # header > < fa :icon = "faExchangeAlt" / > { { $t ( 'network' ) } } < / template >
< div class = "_content" style = "margin-top: -8px; margin-bottom: -12px;" >
< canvas ref = "net" > < / canvas >
< / div >
< div class = "_content" v-if = "serverInfo" >
< div class = "_table" >
< div class = "_row" >
< div class = "_cell" > < div class = "_label" > Interface < / div > { { serverInfo . net . interface } } < / div >
< / div >
< / div >
< / div >
< / mk-container >
2020-01-29 21:37:25 +02:00
< / div >
2020-08-09 09:51:02 +03:00
< / mk-folder >
< mk-folder >
< template # header > < fa :icon = "faClipboardList" / > { { $t ( 'jobQueue' ) } } < / template >
2020-02-16 19:27:14 +02:00
2020-08-09 09:51:02 +03:00
< div class = "vkyrmkwb" >
2020-08-10 14:23:51 +03:00
< mk-container :body-togglable = "false" :scrollable = "true" : resize -base -el = " ( ) = > $el " >
2020-08-09 09:51:02 +03:00
< template # header > < fa :icon = "faExclamationTriangle" / > { { $t ( 'delayed' ) } } < / template >
< div class = "_content" >
< div class = "_keyValue" v-for = "job in jobs" :key="job[0]" >
2020-08-10 14:23:51 +03:00
< button class = "_button" @click ="showInstanceInfo(job[0])" > {{ job [ 0 ] }} < / button >
2020-08-10 06:31:22 +03:00
< div style = "text-align: right;" > { { job [ 1 ] | number } } jobs < / div >
2020-08-09 09:51:02 +03:00
< / div >
< / div >
< / mk-container >
< x-queue :connection = "queueConnection" domain = "inbox" >
< template # title > < fa :icon = "faExchangeAlt" / > In < / template >
< / x-queue >
< x-queue :connection = "queueConnection" domain = "deliver" >
< template # title > < fa :icon = "faExchangeAlt" / > Out < / template >
< / x-queue >
2020-02-16 19:27:14 +02:00
< / div >
2020-08-09 09:51:02 +03:00
< / mk-folder >
< mk-folder >
< template # header > < fa :icon = "faStream" / > { { $t ( 'logs' ) } } < / template >
< div class = "uwuemslx" >
< mk-container :body-togglable = "false" : resize -base -el = " ( ) = > $el " >
< template # header > < fa :icon = "faInfoCircle" / > { { $t ( '' ) } } < / template >
< div class = "_content" >
< div class = "_keyValue" v-for = "log in modLogs" >
< b > { { log . type } } < / b > < span > by { { log . user . username } } < / span > < mk-time :time = "log.createdAt" style = "opacity: 0.7;" / >
< / div >
< / div >
< / mk-container >
< section class = "_card logs" >
< div class = "_title" > < fa :icon = "faStream" / > { { $t ( 'serverLogs' ) } } < / div >
< div class = "_content" >
< div class = "_inputs" >
< mk-input v-model ="logDomain" :debounce ="true" >
< span > { { $t ( 'domain' ) } } < / span >
< / mk-input >
< mk-select v-model = "logLevel" >
< template # label > { { $t ( 'level' ) } } < / template >
< option value = "all" > { { $t ( 'levels.all' ) } } < / option >
< option value = "info" > { { $t ( 'levels.info' ) } } < / option >
< option value = "success" > { { $t ( 'levels.success' ) } } < / option >
< option value = "warning" > { { $t ( 'levels.warning' ) } } < / option >
< option value = "error" > { { $t ( 'levels.error' ) } } < / option >
< option value = "debug" > { { $t ( 'levels.debug' ) } } < / option >
< / mk-select >
< / div >
< div class = "logs" >
< code v-for = "log in logs" :key="log.id" :class="log.level" >
< details >
< summary > < mk-time :time = "log.createdAt" / > [ { { log . domain . join ( '.' ) } } ] { { log . message } } < / summary >
< vue-json-pretty v-if = "log.data" :data="log.data" > < / vue -json -pretty >
< / details >
< / code >
< / div >
< / div >
< div class = "_footer" >
< mk-button @click ="deleteAllLogs()" primary > < fa :icon = "faTrashAlt" / > { { $t ( 'deleteAll' ) } } < / mk-button >
< / div >
< / section >
2020-02-16 19:27:14 +02:00
< / div >
2020-08-09 09:51:02 +03:00
< / mk-folder >
2020-01-29 21:37:25 +02:00
< / div >
< / template >
< script lang = "ts" >
import Vue from 'vue' ;
2020-08-13 11:58:16 +03:00
import { faDatabase , faServer , faExchangeAlt , faMicrochip , faHdd , faStream , faTrashAlt , faInfoCircle , faExclamationTriangle , faTachometerAlt , faHeartbeat , faClipboardList } from '@fortawesome/free-solid-svg-icons' ;
2020-02-16 19:21:27 +02:00
import Chart from 'chart.js' ;
2020-02-18 14:27:43 +02:00
import VueJsonPretty from 'vue-json-pretty' ;
2020-02-16 19:21:27 +02:00
import MkInstanceStats from '../../components/instance-stats.vue' ;
2020-02-18 14:27:43 +02:00
import MkButton from '../../components/ui/button.vue' ;
import MkSelect from '../../components/ui/select.vue' ;
import MkInput from '../../components/ui/input.vue' ;
2020-08-09 09:51:02 +03:00
import MkContainer from '../../components/ui/container.vue' ;
import MkFolder from '../../components/ui/folder.vue' ;
import MkwFederation from '../../widgets/federation.vue' ;
2020-02-09 12:18:06 +02:00
import { version , url } from '../../config' ;
2020-08-09 09:51:02 +03:00
import XQueue from './index.queue-chart.vue' ;
2020-08-10 14:23:51 +03:00
import MkInstanceInfo from './instance.vue' ;
2020-02-16 19:21:27 +02:00
const alpha = ( hex , a ) => {
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i . exec ( hex ) ! ;
const r = parseInt ( result [ 1 ] , 16 ) ;
const g = parseInt ( result [ 2 ] , 16 ) ;
const b = parseInt ( result [ 3 ] , 16 ) ;
return ` rgba( ${ r } , ${ g } , ${ b } , ${ a } ) ` ;
} ;
2020-01-29 21:37:25 +02:00
export default Vue . extend ( {
metaInfo ( ) {
return {
title : this . $t ( 'instance' ) as string
} ;
} ,
components : {
2020-02-16 19:21:27 +02:00
MkInstanceStats ,
2020-02-18 14:27:43 +02:00
MkButton ,
MkSelect ,
MkInput ,
2020-08-09 09:51:02 +03:00
MkContainer ,
MkFolder ,
MkwFederation ,
XQueue ,
VueJsonPretty ,
2020-01-29 21:37:25 +02:00
} ,
data ( ) {
return {
version ,
2020-02-09 12:18:06 +02:00
url ,
2020-01-29 21:37:25 +02:00
stats : null ,
serverInfo : null ,
2020-02-16 19:21:27 +02:00
connection : null ,
2020-08-09 09:51:02 +03:00
queueConnection : this . $root . stream . useSharedConnection ( 'queueStats' ) ,
2020-02-16 19:21:27 +02:00
memUsage : 0 ,
chartCpuMem : null ,
chartNet : null ,
2020-08-09 09:51:02 +03:00
jobs : [ ] ,
2020-02-18 14:27:43 +02:00
logs : [ ] ,
logLevel : 'all' ,
logDomain : '' ,
2020-08-09 09:51:02 +03:00
modLogs : [ ] ,
2020-08-13 11:58:16 +03:00
dbInfo : null ,
overviewHeight : '1fr' ,
faDatabase , faServer , faExchangeAlt , faMicrochip , faHdd , faStream , faTrashAlt , faInfoCircle , faExclamationTriangle , faTachometerAlt , faHeartbeat , faClipboardList ,
2020-01-29 21:37:25 +02:00
}
} ,
2020-02-10 16:17:42 +02:00
computed : {
meta ( ) {
return this . $store . state . instance . meta ;
} ,
} ,
2020-02-18 14:27:43 +02:00
watch : {
logLevel ( ) {
this . logs = [ ] ;
this . fetchLogs ( ) ;
} ,
logDomain ( ) {
this . logs = [ ] ;
this . fetchLogs ( ) ;
}
} ,
2020-08-09 09:51:02 +03:00
created ( ) {
this . $store . commit ( 'setFullView' , true ) ;
} ,
2020-02-16 19:21:27 +02:00
mounted ( ) {
2020-02-18 14:27:43 +02:00
this . fetchLogs ( ) ;
2020-08-09 09:51:02 +03:00
this . fetchJobs ( ) ;
this . fetchModLogs ( ) ;
// TODO: var(--panel)の色が暗いか明るいかで判定する
const gridColor = this . $store . state . device . darkMode ? 'rgba(255, 255, 255, 0.1)' : 'rgba(0, 0, 0, 0.1)' ;
2020-02-18 14:27:43 +02:00
2020-02-16 19:21:27 +02:00
Chart . defaults . global . defaultFontColor = getComputedStyle ( document . documentElement ) . getPropertyValue ( '--fg' ) ;
2020-02-05 03:15:09 +02:00
2020-02-16 19:21:27 +02:00
this . chartCpuMem = new Chart ( this . $refs . cpumem , {
type : 'line' ,
data : {
labels : [ ] ,
datasets : [ {
label : 'CPU' ,
pointRadius : 0 ,
lineTension : 0 ,
borderWidth : 2 ,
borderColor : '#86b300' ,
backgroundColor : alpha ( '#86b300' , 0.1 ) ,
data : [ ]
} , {
label : 'MEM (active)' ,
pointRadius : 0 ,
lineTension : 0 ,
borderWidth : 2 ,
borderColor : '#935dbf' ,
backgroundColor : alpha ( '#935dbf' , 0.02 ) ,
data : [ ]
} , {
label : 'MEM (used)' ,
pointRadius : 0 ,
lineTension : 0 ,
borderWidth : 2 ,
borderColor : '#935dbf' ,
borderDash : [ 5 , 5 ] ,
fill : false ,
data : [ ]
} ]
} ,
options : {
aspectRatio : 3 ,
layout : {
padding : {
left : 0 ,
right : 0 ,
top : 8 ,
bottom : 0
}
} ,
legend : {
position : 'bottom' ,
labels : {
boxWidth : 16 ,
}
} ,
scales : {
xAxes : [ {
gridLines : {
2020-08-09 09:51:02 +03:00
display : false ,
color : gridColor ,
zeroLineColor : gridColor ,
2020-02-16 19:21:27 +02:00
} ,
ticks : {
2020-08-09 09:51:02 +03:00
display : false ,
2020-02-16 19:21:27 +02:00
}
} ] ,
yAxes : [ {
position : 'right' ,
2020-08-09 09:51:02 +03:00
gridLines : {
display : true ,
color : gridColor ,
zeroLineColor : gridColor ,
} ,
2020-02-16 19:21:27 +02:00
ticks : {
display : false ,
max : 100
}
} ]
} ,
tooltips : {
intersect : false ,
mode : 'index' ,
}
}
} ) ;
2020-01-29 21:37:25 +02:00
2020-02-16 19:21:27 +02:00
this . chartNet = new Chart ( this . $refs . net , {
type : 'line' ,
data : {
labels : [ ] ,
datasets : [ {
label : 'In' ,
pointRadius : 0 ,
lineTension : 0 ,
borderWidth : 2 ,
borderColor : '#94a029' ,
backgroundColor : alpha ( '#94a029' , 0.1 ) ,
data : [ ]
} , {
label : 'Out' ,
pointRadius : 0 ,
lineTension : 0 ,
borderWidth : 2 ,
borderColor : '#ff9156' ,
backgroundColor : alpha ( '#ff9156' , 0.1 ) ,
data : [ ]
} ]
} ,
options : {
aspectRatio : 3 ,
layout : {
padding : {
left : 0 ,
right : 0 ,
top : 8 ,
bottom : 0
}
} ,
legend : {
position : 'bottom' ,
labels : {
boxWidth : 16 ,
}
} ,
scales : {
xAxes : [ {
gridLines : {
2020-08-09 09:51:02 +03:00
display : false ,
color : gridColor ,
zeroLineColor : gridColor ,
2020-02-16 19:21:27 +02:00
} ,
ticks : {
display : false
}
} ] ,
yAxes : [ {
position : 'right' ,
2020-08-09 09:51:02 +03:00
gridLines : {
display : true ,
color : gridColor ,
zeroLineColor : gridColor ,
} ,
2020-02-16 19:21:27 +02:00
ticks : {
display : false ,
}
} ]
} ,
tooltips : {
intersect : false ,
mode : 'index' ,
}
}
2020-01-29 21:37:25 +02:00
} ) ;
2020-02-16 19:21:27 +02:00
this . chartDisk = new Chart ( this . $refs . disk , {
type : 'line' ,
data : {
labels : [ ] ,
datasets : [ {
label : 'Read' ,
pointRadius : 0 ,
lineTension : 0 ,
borderWidth : 2 ,
borderColor : '#94a029' ,
backgroundColor : alpha ( '#94a029' , 0.1 ) ,
data : [ ]
} , {
label : 'Write' ,
pointRadius : 0 ,
lineTension : 0 ,
borderWidth : 2 ,
borderColor : '#ff9156' ,
backgroundColor : alpha ( '#ff9156' , 0.1 ) ,
data : [ ]
} ]
} ,
options : {
aspectRatio : 3 ,
layout : {
padding : {
left : 0 ,
right : 0 ,
top : 8 ,
bottom : 0
}
} ,
legend : {
position : 'bottom' ,
labels : {
boxWidth : 16 ,
}
} ,
scales : {
xAxes : [ {
gridLines : {
2020-08-09 09:51:02 +03:00
display : false ,
color : gridColor ,
zeroLineColor : gridColor ,
2020-02-16 19:21:27 +02:00
} ,
ticks : {
display : false
}
} ] ,
yAxes : [ {
position : 'right' ,
2020-08-09 09:51:02 +03:00
gridLines : {
display : true ,
color : gridColor ,
zeroLineColor : gridColor ,
} ,
2020-02-16 19:21:27 +02:00
ticks : {
display : false ,
}
} ]
} ,
tooltips : {
intersect : false ,
mode : 'index' ,
}
}
2020-01-29 21:37:25 +02:00
} ) ;
2020-02-16 19:21:27 +02:00
this . $root . api ( 'admin/server-info' , { } ) . then ( res => {
this . serverInfo = res ;
this . connection = this . $root . stream . useSharedConnection ( 'serverStats' ) ;
this . connection . on ( 'stats' , this . onStats ) ;
this . connection . on ( 'statsLog' , this . onStatsLog ) ;
this . connection . send ( 'requestLog' , {
id : Math . random ( ) . toString ( ) . substr ( 2 , 8 ) ,
length : 150
2020-01-29 21:37:25 +02:00
} ) ;
2020-08-09 09:51:02 +03:00
this . $nextTick ( ( ) => {
this . queueConnection . send ( 'requestLog' , {
id : Math . random ( ) . toString ( ) . substr ( 2 , 8 ) ,
length : 200
} ) ;
} ) ;
2020-01-29 21:37:25 +02:00
} ) ;
2020-08-13 11:58:16 +03:00
this . $root . api ( 'admin/get-table-stats' , { } ) . then ( res => {
this . dbInfo = res ;
} ) ;
this . $nextTick ( ( ) => {
const ro = new ResizeObserver ( ( entries , observer ) => {
if ( this . $refs . stats ) {
this . overviewHeight = this . $refs . stats . $el . offsetHeight + 'px' ;
}
} ) ;
ro . observe ( this . $refs . stats . $el ) ;
} ) ;
2020-01-29 21:37:25 +02:00
} ,
2020-02-16 19:21:27 +02:00
beforeDestroy ( ) {
this . connection . off ( 'stats' , this . onStats ) ;
this . connection . off ( 'statsLog' , this . onStatsLog ) ;
this . connection . dispose ( ) ;
2020-08-09 09:51:02 +03:00
this . queueConnection . dispose ( ) ;
this . $store . commit ( 'setFullView' , false ) ;
2020-02-16 19:21:27 +02:00
} ,
2020-01-29 21:37:25 +02:00
methods : {
2020-08-10 14:23:51 +03:00
async showInstanceInfo ( q ) {
let instance = q ;
if ( typeof q === 'string' ) {
instance = await this . $root . api ( 'federation/show-instance' , {
host : q
} ) ;
}
this . $root . new ( MkInstanceInfo , {
instance : instance
} ) ;
} ,
2020-02-18 14:27:43 +02:00
fetchLogs ( ) {
this . $root . api ( 'admin/logs' , {
level : this . logLevel === 'all' ? null : this . logLevel ,
domain : this . logDomain === '' ? null : this . logDomain ,
limit : 30
} ) . then ( logs => {
this . logs = logs . reverse ( ) ;
} ) ;
} ,
2020-08-09 09:51:02 +03:00
fetchJobs ( ) {
this . $root . api ( 'admin/queue/deliver-delayed' , { } ) . then ( jobs => {
this . jobs = jobs ;
} ) ;
} ,
fetchModLogs ( ) {
this . $root . api ( 'admin/show-moderation-logs' , { } ) . then ( logs => {
this . modLogs = logs ;
} ) ;
} ,
2020-02-18 14:27:43 +02:00
deleteAllLogs ( ) {
this . $root . api ( 'admin/delete-logs' ) . then ( ( ) => {
this . $root . dialog ( {
type : 'success' ,
iconOnly : true , autoClose : true
} ) ;
} ) ;
} ,
2020-02-16 19:21:27 +02:00
onStats ( stats ) {
const cpu = ( stats . cpu * 100 ) . toFixed ( 0 ) ;
const memActive = ( stats . mem . active / this . serverInfo . mem . total * 100 ) . toFixed ( 0 ) ;
const memUsed = ( stats . mem . used / this . serverInfo . mem . total * 100 ) . toFixed ( 0 ) ;
this . memUsage = stats . mem . active ;
2020-01-29 21:37:25 +02:00
2020-02-16 19:21:27 +02:00
this . chartCpuMem . data . labels . push ( '' ) ;
this . chartCpuMem . data . datasets [ 0 ] . data . push ( cpu ) ;
this . chartCpuMem . data . datasets [ 1 ] . data . push ( memActive ) ;
this . chartCpuMem . data . datasets [ 2 ] . data . push ( memUsed ) ;
this . chartNet . data . labels . push ( '' ) ;
this . chartNet . data . datasets [ 0 ] . data . push ( stats . net . rx ) ;
this . chartNet . data . datasets [ 1 ] . data . push ( stats . net . tx ) ;
this . chartDisk . data . labels . push ( '' ) ;
this . chartDisk . data . datasets [ 0 ] . data . push ( stats . fs . r ) ;
this . chartDisk . data . datasets [ 1 ] . data . push ( stats . fs . w ) ;
if ( this . chartCpuMem . data . datasets [ 0 ] . data . length > 150 ) {
this . chartCpuMem . data . labels . shift ( ) ;
this . chartCpuMem . data . datasets [ 0 ] . data . shift ( ) ;
this . chartCpuMem . data . datasets [ 1 ] . data . shift ( ) ;
this . chartCpuMem . data . datasets [ 2 ] . data . shift ( ) ;
this . chartNet . data . labels . shift ( ) ;
this . chartNet . data . datasets [ 0 ] . data . shift ( ) ;
this . chartNet . data . datasets [ 1 ] . data . shift ( ) ;
this . chartDisk . data . labels . shift ( ) ;
this . chartDisk . data . datasets [ 0 ] . data . shift ( ) ;
this . chartDisk . data . datasets [ 1 ] . data . shift ( ) ;
}
this . chartCpuMem . update ( ) ;
this . chartNet . update ( ) ;
this . chartDisk . update ( ) ;
2020-02-05 03:15:09 +02:00
} ,
2020-02-16 19:21:27 +02:00
onStatsLog ( statsLog ) {
2020-07-27 17:25:37 +03:00
for ( const stats of [ ... statsLog ] . reverse ( ) ) {
2020-02-16 19:21:27 +02:00
this . onStats ( stats ) ;
}
2020-01-29 21:37:25 +02:00
}
}
} ) ;
< / script >
< style lang = "scss" scoped >
2020-02-16 19:21:27 +02:00
. xhexznfu {
2020-08-09 09:51:02 +03:00
& . min - width _1600px {
. sboqnrfi {
display : grid ;
grid - template - columns : 3.2 fr 1 fr ;
grid - template - rows : 1 fr ;
gap : 16 px 16 px ;
2020-08-13 11:58:16 +03:00
> . stats {
height : min - content ;
}
2020-08-09 09:51:02 +03:00
> . column {
2020-08-13 11:58:16 +03:00
display : flex ;
flex - direction : column ;
> . info {
flex - shrink : 0 ;
flex - grow : 0 ;
}
> . db {
flex : 1 ;
flex - grow : 0 ;
}
> . fed {
flex : 1 ;
flex - grow : 0 ;
}
> * : not ( : last - child ) {
margin - bottom : var ( -- margin ) ;
}
2020-08-09 09:51:02 +03:00
}
}
. segusily {
display : grid ;
grid - template - columns : 1 fr 1 fr 1 fr ;
grid - template - rows : 1 fr ;
gap : 16 px 16 px ;
}
. vkyrmkwb {
display : grid ;
grid - template - columns : 0.5 fr 1 fr 1 fr ;
2020-08-13 11:58:16 +03:00
grid - template - rows : 400 px ;
2020-08-09 09:51:02 +03:00
gap : 16 px 16 px ;
}
. uwuemslx {
display : grid ;
grid - template - columns : 2 fr 3 fr ;
grid - template - rows : 1 fr ;
gap : 16 px 16 px ;
height : 400 px ;
}
}
. vkyrmkwb {
> * {
margin - bottom : var ( -- margin ) ;
}
}
2020-02-16 19:21:27 +02:00
> . stats {
display : flex ;
justify - content : space - between ;
flex - wrap : wrap ;
margin : calc ( 0 px - var ( -- margin ) / 2 ) ;
margin - bottom : calc ( var ( -- margin ) / 2 ) ;
> div {
flex : 1 0 213 px ;
margin : calc ( var ( -- margin ) / 2 ) ;
box - sizing : border - box ;
padding : 16 px ;
}
}
2020-02-18 14:27:43 +02:00
> . logs {
> . _content {
> . logs {
padding : 8 px ;
background : # 000 ;
color : # fff ;
font - size : 0.9 em ;
> code {
display : block ;
& . error {
color : # f00 ;
}
& . warning {
color : # ff0 ;
}
& . success {
color : # 0 f0 ;
}
& . debug {
opacity : 0.7 ;
}
}
}
}
}
2020-01-29 21:37:25 +02:00
}
< / style >