ログビューア実装
This commit is contained in:
		
							parent
							
								
									e2ff408f2f
								
							
						
					
					
						commit
						da4af041af
					
				
					 2 changed files with 110 additions and 2 deletions
				
			
		|  | @ -419,6 +419,8 @@ hideThisNote: "このノートを非表示" | ||||||
| showFeaturedNotesInTimeline: "タイムラインにおすすめのノートを表示する" | showFeaturedNotesInTimeline: "タイムラインにおすすめのノートを表示する" | ||||||
| objectStorage: "オブジェクトストレージ" | objectStorage: "オブジェクトストレージ" | ||||||
| useObjectStorage: "オブジェクトストレージを使用" | useObjectStorage: "オブジェクトストレージを使用" | ||||||
|  | serverLogs: "サーバーログ" | ||||||
|  | deleteAll: "全て削除" | ||||||
| 
 | 
 | ||||||
| _ago: | _ago: | ||||||
|   unknown: "謎" |   unknown: "謎" | ||||||
|  |  | ||||||
|  | @ -5,6 +5,38 @@ | ||||||
| 
 | 
 | ||||||
| 	<mk-instance-stats style="margin-bottom: var(--margin);"/> | 	<mk-instance-stats style="margin-bottom: var(--margin);"/> | ||||||
| 
 | 
 | ||||||
|  | 	<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> | ||||||
|  | 
 | ||||||
| 	<section class="_card chart"> | 	<section class="_card chart"> | ||||||
| 		<div class="_title"><fa :icon="faMicrochip"/> {{ $t('cpuAndMemory') }}</div> | 		<div class="_title"><fa :icon="faMicrochip"/> {{ $t('cpuAndMemory') }}</div> | ||||||
| 		<div class="_content" style="margin-top: -8px; margin-bottom: -12px;"> | 		<div class="_content" style="margin-top: -8px; margin-bottom: -12px;"> | ||||||
|  | @ -67,9 +99,13 @@ | ||||||
| 
 | 
 | ||||||
| <script lang="ts"> | <script lang="ts"> | ||||||
| import Vue from 'vue'; | import Vue from 'vue'; | ||||||
| import { faServer, faExchangeAlt, faMicrochip, faHdd } from '@fortawesome/free-solid-svg-icons'; | import { faServer, faExchangeAlt, faMicrochip, faHdd, faStream, faTrashAlt } from '@fortawesome/free-solid-svg-icons'; | ||||||
| import Chart from 'chart.js'; | import Chart from 'chart.js'; | ||||||
|  | import VueJsonPretty from 'vue-json-pretty'; | ||||||
| import MkInstanceStats from '../../components/instance-stats.vue'; | import MkInstanceStats from '../../components/instance-stats.vue'; | ||||||
|  | import MkButton from '../../components/ui/button.vue'; | ||||||
|  | import MkSelect from '../../components/ui/select.vue'; | ||||||
|  | import MkInput from '../../components/ui/input.vue'; | ||||||
| import { version, url } from '../../config'; | import { version, url } from '../../config'; | ||||||
| import i18n from '../../i18n'; | import i18n from '../../i18n'; | ||||||
| 
 | 
 | ||||||
|  | @ -92,6 +128,10 @@ export default Vue.extend({ | ||||||
| 
 | 
 | ||||||
| 	components: { | 	components: { | ||||||
| 		MkInstanceStats, | 		MkInstanceStats, | ||||||
|  | 		MkButton, | ||||||
|  | 		MkSelect, | ||||||
|  | 		MkInput, | ||||||
|  | 		VueJsonPretty | ||||||
| 	}, | 	}, | ||||||
| 
 | 
 | ||||||
| 	data() { | 	data() { | ||||||
|  | @ -104,7 +144,10 @@ export default Vue.extend({ | ||||||
| 			memUsage: 0, | 			memUsage: 0, | ||||||
| 			chartCpuMem: null, | 			chartCpuMem: null, | ||||||
| 			chartNet: null, | 			chartNet: null, | ||||||
| 			faServer, faExchangeAlt, faMicrochip, faHdd | 			logs: [], | ||||||
|  | 			logLevel: 'all', | ||||||
|  | 			logDomain: '', | ||||||
|  | 			faServer, faExchangeAlt, faMicrochip, faHdd, faStream, faTrashAlt | ||||||
| 		} | 		} | ||||||
| 	}, | 	}, | ||||||
| 
 | 
 | ||||||
|  | @ -114,7 +157,20 @@ export default Vue.extend({ | ||||||
| 		}, | 		}, | ||||||
| 	}, | 	}, | ||||||
| 
 | 
 | ||||||
|  | 	watch: { | ||||||
|  | 		logLevel() { | ||||||
|  | 			this.logs = []; | ||||||
|  | 			this.fetchLogs(); | ||||||
|  | 		}, | ||||||
|  | 		logDomain() { | ||||||
|  | 			this.logs = []; | ||||||
|  | 			this.fetchLogs(); | ||||||
|  | 		} | ||||||
|  | 	}, | ||||||
|  | 
 | ||||||
| 	mounted() { | 	mounted() { | ||||||
|  | 		this.fetchLogs(); | ||||||
|  | 	 | ||||||
| 		Chart.defaults.global.defaultFontColor = getComputedStyle(document.documentElement).getPropertyValue('--fg'); | 		Chart.defaults.global.defaultFontColor = getComputedStyle(document.documentElement).getPropertyValue('--fg'); | ||||||
| 
 | 
 | ||||||
| 		this.chartCpuMem = new Chart(this.$refs.cpumem, { | 		this.chartCpuMem = new Chart(this.$refs.cpumem, { | ||||||
|  | @ -330,6 +386,25 @@ export default Vue.extend({ | ||||||
| 	}, | 	}, | ||||||
| 
 | 
 | ||||||
| 	methods: { | 	methods: { | ||||||
|  | 		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(); | ||||||
|  | 			}); | ||||||
|  | 		}, | ||||||
|  | 
 | ||||||
|  | 		deleteAllLogs() { | ||||||
|  | 			this.$root.api('admin/delete-logs').then(() => { | ||||||
|  | 				this.$root.dialog({ | ||||||
|  | 					type: 'success', | ||||||
|  | 					iconOnly: true, autoClose: true | ||||||
|  | 				}); | ||||||
|  | 			}); | ||||||
|  | 		}, | ||||||
|  | 
 | ||||||
| 		onStats(stats) { | 		onStats(stats) { | ||||||
| 			const cpu = (stats.cpu * 100).toFixed(0); | 			const cpu = (stats.cpu * 100).toFixed(0); | ||||||
| 			const memActive = (stats.mem.active / this.serverInfo.mem.total * 100).toFixed(0); | 			const memActive = (stats.mem.active / this.serverInfo.mem.total * 100).toFixed(0); | ||||||
|  | @ -389,6 +464,37 @@ export default Vue.extend({ | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	> .logs { | ||||||
|  | 		> ._content { | ||||||
|  | 			> .logs { | ||||||
|  | 				padding: 8px; | ||||||
|  | 				background: #000; | ||||||
|  | 				color: #fff; | ||||||
|  | 				font-size: 0.9em; | ||||||
|  | 
 | ||||||
|  | 				> code { | ||||||
|  | 					display: block; | ||||||
|  | 
 | ||||||
|  | 					&.error { | ||||||
|  | 						color: #f00; | ||||||
|  | 					} | ||||||
|  | 
 | ||||||
|  | 					&.warning { | ||||||
|  | 						color: #ff0; | ||||||
|  | 					} | ||||||
|  | 
 | ||||||
|  | 					&.success { | ||||||
|  | 						color: #0f0; | ||||||
|  | 					} | ||||||
|  | 
 | ||||||
|  | 					&.debug { | ||||||
|  | 						opacity: 0.7; | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	> .chart { | 	> .chart { | ||||||
| 		> ._content { | 		> ._content { | ||||||
| 			> .table { | 			> .table { | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue