diff --git a/frontend/src/components/log/container/index.vue b/frontend/src/components/log/container/index.vue index fa0d12e43..d589a1df5 100644 --- a/frontend/src/components/log/container/index.vue +++ b/frontend/src/components/log/container/index.vue @@ -25,7 +25,15 @@
- +
+
+ +
@@ -36,6 +44,7 @@ import { dateFormatForName } from '@/utils/util'; import { onUnmounted, reactive, ref } from 'vue'; import { ElMessageBox } from 'element-plus'; import { MsgError, MsgSuccess } from '@/utils/message'; +import hightlight from '@/components/log/custom-hightlight/index.vue'; import { GlobalStore } from '@/store'; const globalStore = GlobalStore(); @@ -63,6 +72,8 @@ const styleVars = computed(() => ({ })); const logVisible = ref(false); +const logContainer = ref(null); +const logs = ref([]); let eventSource: EventSource | null = null; const logSearch = reactive({ isWatch: true, @@ -71,7 +82,17 @@ const logSearch = reactive({ tail: 100, compose: '', }); -const logInfo = ref(''); +const logHeight = 20; +const logCount = computed(() => logs.value.length); +const totalHeight = computed(() => logHeight * logCount.value); +const startIndex = ref(0); +const containerHeight = ref(500); +const visibleCount = computed(() => Math.ceil(containerHeight.value / logHeight) + 2); +const visibleLogs = computed(() => { + const start = Math.max(0, startIndex.value - 1); + const end = startIndex.value + visibleCount.value + 1; + return logs.value.slice(start, end); +}); const timeOptions = ref([ { label: i18n.global.t('commons.table.all'), value: 'all' }, @@ -114,7 +135,7 @@ const searchLogs = async () => { if (!logSearch.isWatch) { return; } - logInfo.value = ''; + logs.value = []; let currentNode = globalStore.currentNode; let url = `/api/v2/containers/search/log?container=${logSearch.container}&since=${logSearch.mode}&tail=${logSearch.tail}&follow=${logSearch.isWatch}&operateNode=${currentNode}`; if (logSearch.compose !== '') { @@ -122,7 +143,13 @@ const searchLogs = async () => { } eventSource = new EventSource(url); eventSource.onmessage = (event: MessageEvent) => { - logInfo.value += event.data.replace(/\x1B\[[0-?]*[ -/]*[@-~]/g, '') + '\n'; + const data = event.data; + logs.value.push(data); + nextTick(() => { + if (logContainer.value) { + logContainer.value.scrollTop = logContainer.value.scrollHeight; + } + }); }; eventSource.onerror = (event: MessageEvent) => { stopListening(); @@ -172,23 +199,49 @@ const onClean = async () => { cancelButtonText: i18n.global.t('commons.button.cancel'), type: 'info', }).then(async () => { + console.log(logSearch); await cleanContainerLog(logSearch.container); - await searchLogs(); + searchLogs(); MsgSuccess(i18n.global.t('commons.msg.operationSuccess')); }); }; +const handleScroll = () => { + if (logContainer.value) { + const scrollTop = logContainer.value.scrollTop; + startIndex.value = Math.max(0, Math.floor(scrollTop / logHeight) - 1); + } +}; + onUnmounted(() => { handleClose(); + if (logContainer.value) { + logContainer.value.removeEventListener('scroll', handleScroll); + } }); +const resizeObserver = ref(null); + onMounted(() => { logSearch.container = props.container; logSearch.compose = props.compose; + logVisible.value = true; logSearch.tail = 100; logSearch.mode = 'all'; logSearch.isWatch = true; + + nextTick(() => { + if (logContainer.value) { + containerHeight.value = logContainer.value.clientHeight; + logContainer.value.addEventListener('scroll', handleScroll); + resizeObserver.value = new ResizeObserver((entries) => { + containerHeight.value = entries[0].contentRect.height; + }); + resizeObserver.value.observe(logContainer.value); + } + }); + searchLogs(); }); @@ -211,7 +264,8 @@ onMounted(() => { } .log-container { - overflow-y: hidden; + height: calc(100vh - var(--custom-height, 320px)); + overflow-y: auto; overflow-x: auto; position: relative; background-color: #1e1e1e; diff --git a/frontend/src/components/log/file/index.vue b/frontend/src/components/log/file/index.vue index 7d730a1df..8679a09fa 100644 --- a/frontend/src/components/log/file/index.vue +++ b/frontend/src/components/log/file/index.vue @@ -1,7 +1,7 @@