Skip to content

Commit

Permalink
Refactor/log page (#361)
Browse files Browse the repository at this point in the history
* feat: create text tag

* feat: init

* feat: text data

* feat: zoom

* feat: text detail

* feat: step

* style

* fix: width

* fix: change

* fix: change

* feat: modal title

* fix: line clamp

* test: text log

* Squashed commit of the following:

commit 6ec7f6d
Author: KAAANG <79990647+SAKURA-CAT@users.noreply.github.com>
Date:   Thu Feb 22 16:13:17 2024 +0800

    record max step and min step (#341)

commit ce48cd8
Author: KAAANG <cunykang@gmail.com>
Date:   Thu Feb 22 15:51:42 2024 +0800

    delete Video

commit a11a7ed
Author: Bote Huang <106975133+KashiwaByte@users.noreply.github.com>
Date:   Thu Feb 22 15:36:32 2024 +0800

    Feat/video chart (#338)

    * feat:create class Video

    * feat:add __init__,add video chart

    * feat:add function for saving video

    * feat:add function for getting list of video

    * feat:add function get_data

    * feat:add function __save and __prepare_video

    * feat:add function load_from_str and load_from_BytesIO

    * bugfix: fix __save function

    * del test file

commit 6b5b9c3
Author: KAAANG <79990647+SAKURA-CAT@users.noreply.github.com>
Date:   Wed Feb 21 15:25:33 2024 +0800

    Feat/new line chart (#334)

    * add type——linear

    * label formatter

    * update tick

commit 788d8c1
Author: Ze-Yi LIN <58305964+xiaolin199912@users.noreply.github.com>
Date:   Tue Feb 20 21:07:39 2024 +0800

    Feat/image-add-parameters-boxes-masks (#329)

    * add BoundingBoxes class

    * update something

    * Update transfer_logfile_0.1.4.py

    * add ImageMask class

    * bugfix

commit 65a6378
Author: Ze-Yi LIN <58305964+xiaolin199912@users.noreply.github.com>
Date:   Mon Feb 19 18:42:11 2024 +0800

    Readme v0.2.0 (#326)

commit 7b964e9
Author: Zirui Cai <74649535+Feudalman@users.noreply.github.com>
Date:   Mon Feb 19 18:29:05 2024 +0800

    Fixbug/tag sort (#327)

* use hash name to filename

* feat: get text

* feat: get text

* feat: caption

* fix: log page layout

* ui: color

* feat: skeleton

* fix: detail caption

* fix: length

* feat: log height

* feat: page index

* fix: flash

* fix: skeleton

* fix: flash

* fix: some bug

* fix:wrap

* ui: color

* Squashed commit of the following:

commit b328478
Author: KAAANG <79990647+SAKURA-CAT@users.noreply.github.com>
Date:   Mon Feb 26 22:12:23 2024 +0800

    Update/line chart styles (#351)

    * hover active

    * hover top

    * optimize hover top

    * Update LineChart.vue

    * update hover

    * allow hover while running

    * Limit height when zooming in

    * fix slidebar bug

    * thickenByTag

    * Logic to distinguish between multiple data charts and single data charts

    * allow config crosshair

    * update crosshairsColor

    * update doc

    * update thickerLineWidth

    ---------

    Co-authored-by: ZeYi Lin <944270057@qq.com>

* refactor: click to turn page

* feat: enter and blur

* doc: comments

* fix: bg height

* fix: csv runtime

* fix: column

* feat: compute

* feat: render

* fix: text wrap

* fix: error logs

* fix: error log

* Squashed commit of the following:

commit bb6d595
Author: Zirui Cai <74649535+Feudalman@users.noreply.github.com>
Date:   Wed Feb 28 21:25:42 2024 +0800

    Feature/text chart (#337)

    * feat: create text tag

    * feat: init

    * feat: text data

    * feat: zoom

    * feat: text detail

    * feat: step

    * style

    * fix: width

    * fix: change

    * fix: change

    * feat: modal title

    * fix: line clamp

    * test: text log

    * Squashed commit of the following:

    commit 6ec7f6d
    Author: KAAANG <79990647+SAKURA-CAT@users.noreply.github.com>
    Date:   Thu Feb 22 16:13:17 2024 +0800

        record max step and min step (#341)

    commit ce48cd8
    Author: KAAANG <cunykang@gmail.com>
    Date:   Thu Feb 22 15:51:42 2024 +0800

        delete Video

    commit a11a7ed
    Author: Bote Huang <106975133+KashiwaByte@users.noreply.github.com>
    Date:   Thu Feb 22 15:36:32 2024 +0800

        Feat/video chart (#338)

        * feat:create class Video

        * feat:add __init__,add video chart

        * feat:add function for saving video

        * feat:add function for getting list of video

        * feat:add function get_data

        * feat:add function __save and __prepare_video

        * feat:add function load_from_str and load_from_BytesIO

        * bugfix: fix __save function

        * del test file

    commit 6b5b9c3
    Author: KAAANG <79990647+SAKURA-CAT@users.noreply.github.com>
    Date:   Wed Feb 21 15:25:33 2024 +0800

        Feat/new line chart (#334)

        * add type——linear

        * label formatter

        * update tick

    commit 788d8c1
    Author: Ze-Yi LIN <58305964+xiaolin199912@users.noreply.github.com>
    Date:   Tue Feb 20 21:07:39 2024 +0800

        Feat/image-add-parameters-boxes-masks (#329)

        * add BoundingBoxes class

        * update something

        * Update transfer_logfile_0.1.4.py

        * add ImageMask class

        * bugfix

    commit 65a6378
    Author: Ze-Yi LIN <58305964+xiaolin199912@users.noreply.github.com>
    Date:   Mon Feb 19 18:42:11 2024 +0800

        Readme v0.2.0 (#326)

    commit 7b964e9
    Author: Zirui Cai <74649535+Feudalman@users.noreply.github.com>
    Date:   Mon Feb 19 18:29:05 2024 +0800

        Fixbug/tag sort (#327)

    * use hash name to filename

    * feat: get text

    * feat: get text

    * feat: caption

    * fix: log page layout

    * ui: color

    * feat: skeleton

    * fix: detail caption

    * fix: length

    * feat: log height

    * feat: page index

    * fix: flash

    * fix: skeleton

    * fix: flash

    * fix: some bug

    * fix:wrap

    * ui: color

    * Squashed commit of the following:

    commit b328478
    Author: KAAANG <79990647+SAKURA-CAT@users.noreply.github.com>
    Date:   Mon Feb 26 22:12:23 2024 +0800

        Update/line chart styles (#351)

        * hover active

        * hover top

        * optimize hover top

        * Update LineChart.vue

        * update hover

        * allow hover while running

        * Limit height when zooming in

        * fix slidebar bug

        * thickenByTag

        * Logic to distinguish between multiple data charts and single data charts

        * allow config crosshair

        * update crosshairsColor

        * update doc

        * update thickerLineWidth

        ---------

        Co-authored-by: ZeYi Lin <944270057@qq.com>

    * refactor: click to turn page

    * feat: enter and blur

    * doc: comments

    * fix: bg height

    * Update launch.json

    * refactor: get texts

    * refactor: script to create experiment

    ---------

    Co-authored-by: ZeYi Lin <944270057@qq.com>
    Co-authored-by: KAAANG <cunykang@gmail.com>

commit 113d4bc
Author: KAAANG <79990647+SAKURA-CAT@users.noreply.github.com>
Date:   Wed Feb 28 00:01:25 2024 +0800

    legend component (#354)

commit b328478
Author: KAAANG <79990647+SAKURA-CAT@users.noreply.github.com>
Date:   Mon Feb 26 22:12:23 2024 +0800

    Update/line chart styles (#351)

    * hover active

    * hover top

    * optimize hover top

    * Update LineChart.vue

    * update hover

    * allow hover while running

    * Limit height when zooming in

    * fix slidebar bug

    * thickenByTag

    * Logic to distinguish between multiple data charts and single data charts

    * allow config crosshair

    * update crosshairsColor

    * update doc

    * update thickerLineWidth

    ---------

    Co-authored-by: ZeYi Lin <944270057@qq.com>

* fix

* ui: optimize

* ui: optimize

---------

Co-authored-by: ZeYi Lin <944270057@qq.com>
  • Loading branch information
Feudalman and Zeyi-Lin authored Feb 29, 2024
1 parent 7311bc6 commit a52669b
Show file tree
Hide file tree
Showing 4 changed files with 212 additions and 60 deletions.
8 changes: 4 additions & 4 deletions swanlab/server/controller/experiment.py
Original file line number Diff line number Diff line change
Expand Up @@ -426,14 +426,14 @@ def get_recent_logs(experiment_id):
with open(os.path.join(console_path, f), mode="r", encoding="utf-8") as log:
logs = log.read().split("\n") + logs
# 如果当前收集到的数据超过限制,退出循环
if len(logs) >= MAX_NUM:
# current_page = index
break
# if len(logs) >= MAX_NUM:
# # current_page = index
# break
# 如果 logs 内容为空
if logs[0] == "":
return NOT_FOUND_404("No Logs Found")

logs = logs[:MAX_NUM]
# logs = logs[:MAX_NUM]
end = (logs[-1] if not logs[-1] == "" else logs[-2]).split(" ")[0]
data = {
"recent": [logs[0].split(" ")[0], end],
Expand Down
39 changes: 37 additions & 2 deletions vue/src/views/experiment/components/FuncBar.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
<template>
<div class="w-full flex justify-between gap-5">
<SLSearch @input="input" :placeholder="placeholder" class="max-w-[400px]" />
<div class="flex items-center w-full">
<SLSearch @input="input" :placeholder="placeholder" class="max-w-[400px]" />
<div class="flex items-center px-4" v-show="targets?.length">
<span>{{ _modelValue }} / {{ targets?.length }}</span>
<div class="w-3 flex-shrink-0 flex-col flex ml-2">
<SLIcon icon="down" class="w-full h-3 -rotate-180 -mb-1" @click="_modelValue++" />
<SLIcon icon="down" class="w-full aspect-square" @click="_modelValue--" />
</div>
</div>
</div>
<div class="flex gap-3">
<SLButton hollow @click="copy">
<SLIcon icon="copy" class="icon"></SLIcon>
Expand All @@ -21,6 +30,7 @@
* @since: 2024-01-10 12:54:19
**/
import { computed } from 'vue'
import SLSearch from '@swanlab-vue/components/SLSearch.vue'
import { message } from '@swanlab-vue/components/message'
import { t } from '@swanlab-vue/i18n'
Expand All @@ -41,10 +51,35 @@ const props = defineProps({
placeholder: {
type: String,
default: 'Search...'
},
// 目标行
targets: {
type: Array,
default: () => []
},
// 当前选中的搜索目标
modelValue: {
type: Number,
default: 1
}
})
const emits = defineEmits(['input', 'download'])
const emits = defineEmits(['input', 'download', 'update:modelValue'])
const _modelValue = computed({
get() {
return props.modelValue
},
set(v) {
if (v < 1) {
emits('update:modelValue', 1)
} else if (v > props.targets.length) {
emits('update:modelValue', props.targets.length)
} else {
emits('update:modelValue', v)
}
}
})
// 输入触发
const input = (value) => {
Expand Down
218 changes: 166 additions & 52 deletions vue/src/views/experiment/pages/log/LogPage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,32 +8,42 @@
:filename="filename"
v-if="logs"
/>
<section class="log-container" :class="experimentStore.experiment.description ? 'h-[65vh]' : 'h-[70vh]'">
<div class="log-area" ref="logAreaRef" v-if="logs">
<!-- 运行日志 -->
<div class="log-line" v-for="line in lines" :key="line">
<!-- 行号 -->
<span class="w-8 text-right flex-shrink-0 text-dimmest select-none">{{ line.index }}</span>
<!-- 日志内容 -->
<!-- 如果没有搜索内容/不含搜索内容 -->
<span v-show="!line.isTarget">{{ line.value }} </span>
<!-- 如果有搜索内容且含有搜索内容 -->
<span v-show="line.isTarget">
<section class="log-container" @scroll="handleScroll">
<!-- 用于撑开容器,保证滚动条高度 -->
<div class="log-area" :style="{ height: areaHeight + 'px' }" v-if="logs">
<!-- 日志画板 -->
<div class="log-board" :style="{ top: computeTop + 'px' }">
<!-- 运行日志 -->
<div
class="log-line"
v-for="(line, index) in lines.slice(range[0], range[1] + 1)"
:key="line.value + range[0] + index"
>
<!-- 行号 -->
<span
v-for="substring in line.value"
:key="substring"
:class="{ 'bg-warning-dimmest': substring.toLowerCase() === searchValue }"
class="w-8 text-right flex-shrink-0 text-dimmest select-none"
:class="{ 'text-negative-default': line.error }"
:style="{ width: indexWidth }"
>{{ line.index }}</span
>
{{ substring }}
</span>
</span>
</div>
<!-- 错误日志 -->
<div class="log-line text-negative-default" v-for="(line, index) in errorLogs" :key="line">
<!-- 行数 -->
<span class="w-8 text-right flex-shrink-0 select-none">{{ lastLineIndex + index + 1 }}</span>
<!-- 日志内容 -->
<span>{{ line }}</span>
<!-- 正常日志 -->
<div v-if="!line.error">
<!-- 如果没有搜索内容/不含搜索内容 -->
<span v-show="!line.isTarget">{{ line.value }} </span>
<!-- 如果有搜索内容且含有搜索内容 -->
<span v-show="line.isTarget">
<span
v-for="substring in line.value"
:key="substring"
:class="{ 'bg-warning-dimmest': substring.toLowerCase() === searchValue }"
>
{{ substring }}
</span>
</span>
</div>
<!-- 错误日志 -->
<div class="text-negative-default" v-else>{{ line.value }}</div>
</div>
</div>
<!-- 没有日志 -->
<div
Expand All @@ -58,14 +68,14 @@
* @since: 2023-12-09 20:40:44
**/
import { ref } from 'vue'
import { ref, onMounted } from 'vue'
import http from '@swanlab-vue/api/http'
import { useExperimentStore } from '@swanlab-vue/store'
import SLLoding from '@swanlab-vue/components/SLLoading.vue'
import FuncBar from '../../components/FuncBar.vue'
import { computed } from 'vue'
const logAreaRef = ref()
import { debounce } from '@swanlab-vue/utils/common'
import { addTaskToBrowserMainThread } from '@swanlab-vue/utils/browser'
// ---------------------------------- 系统相关 ----------------------------------
Expand All @@ -79,7 +89,8 @@ const logs = ref()
// 分开行号和内容之后的日志
const lines = computed(() => {
return logs.value?.map((line) => {
// 正常日志内容
const data = logs.value?.map((line) => {
const noIndex = isNaN(line.substring(0, line.indexOf(' ')))
const index = noIndex ? null : line.substring(0, line.indexOf(' '))
const content = noIndex ? line : line.substring(line.indexOf(' ')).trimStart()
Expand All @@ -90,16 +101,38 @@ const lines = computed(() => {
value: isTarget ? splitStringBySearch(content, searchValue.value) : content
}
})
// 正常内容最后一行的行号
const lastLineIndex = getLastLineIndex(data)
// 处理错误日志内容
errorLogs.value.map((line, index) => {
return data.push({
index: lastLineIndex + index + 1,
value: line,
error: true
})
})
return data
})
// 行号宽度
const indexWidth = computed(() => {
let index = 1
const l = lines.value?.length
if (l) {
index = lines.value[l - 1].index === '' ? lines.value[l - 2].index : lines.value[l - 1].index
}
return 8 * index.length + 'px'
})
// 正常内容最后一行的行号
const lastLineIndex = computed(() => {
const maxIndex = lines.value?.reduce((max, line) => {
// 获取正常内容最后一行的行号
const getLastLineIndex = (data) => {
const maxIndex = data?.reduce((max, line) => {
if (!line.index) return max
return Number(line.index) > Number(max) ? line.index : max
}, 0)
return Number(maxIndex)
})
}
const download = computed(() => {
const log_list = logs.value?.map((log) => {
Expand All @@ -110,7 +143,7 @@ const download = computed(() => {
return log_list?.join('\n') + errorLogs.value.join('\n')
})
function splitStringBySearch(target, substring) {
const splitStringBySearch = (target, substring) => {
// 使用正则表达式进行大小写不敏感的分割,并保留分割点
let resultArray = target.split(new RegExp(`(${substring})`, 'i'))
Expand All @@ -123,8 +156,88 @@ function splitStringBySearch(target, substring) {
// 错误日志
const errorLogs = ref([])
;(async function () {
// 获取日志
// ---------------------------------- 搜索 ----------------------------------
const searchValue = ref('')
const searchIndex = ref(1)
const search = (value) => {
searchValue.value = value.toLowerCase()
}
const searchTargets = computed(() => {
return lines.value.filter((line) => {
return line.isTarget
})
})
// ---------------------------------- 下载 ----------------------------------
const filename = 'print.log'
// ---------------------------------- 动态渲染 ----------------------------------
// log 渲染范围
const range = ref([0, 0])
// 行高
const lineHeight = ref(16)
// 最大额外渲染行数
const addition = 30
// log 区高度
const areaHeight = computed(() => {
return lines.value?.length * lineHeight.value
})
const handleScroll = debounce((event) => {
const e = event.target
computeRange(e)
}, 100)
// 计算 log 的渲染范围
const computeRange = (e) => {
const line_height = lineHeight.value
// 计算应该渲染多少条数据
const pageSize = Math.ceil(e.clientHeight / line_height)
// 计算第一条 log 的索引
const startIndex = Math.floor(e.scrollTop / line_height)
// 计算最后一条 log 的索引
const endIndex = startIndex + pageSize
// 如果距离顶部很近,把顶部到第一条中的log也渲染了
if (e.scrollTop <= addition * line_height) range.value[0] = 0
// 如果距离顶部比较远,仅渲染第一条上的 addition 条 log
else range.value[0] = startIndex - addition
// 如果距离底部很近,把最后一条到底部的log也渲染了
if (e.scrollTop + e.clientHeight >= e.scrollHeight - addition * line_height) range.value[1] = lines.value.length - 1
// 如果距离底部较远,仅渲染最后一条下的 addition 条 log
else range.value[1] = endIndex + addition
}
/**
* 计算 log 行高
* 没有使用计算属性,因为担心用户手动更改缩放等情况,不会触发响应式计算
* 采用函数,对某些事件进行监听后调用以适应不同情况下的行高
* 一般行高是 16px,基本不会出问题,所以目前只在初始化时计算,而没做另外的事件监听
*/
const computeLineHeight = () => {
const line_styles = window.getComputedStyle(document.querySelector('.log-line'))
lineHeight.value = parseFloat(line_styles.getPropertyValue('line-height'))
}
const computeTop = computed(() => {
return range.value[0] * lineHeight.value
})
/**
* 初始化:
* 1. 获取日志数据
* 2. 计算日志行高
* 3. 计算日志渲染范围
*/
onMounted(async () => {
// 获取日志数据
const { data } = await http.get(`/experiment/${id}/recent_log`).catch((error) => {
if (error.data.code === 3404) {
logs.value = []
Expand All @@ -136,39 +249,40 @@ const errorLogs = ref([])
// 设置日志
logs.value = data.logs || []
if (data.error) errorLogs.value = data.error
// addTaskToBrowserMainThread(() => {
// // 滚动到底部
// logAreaRef.value.scrollTop = logAreaRef.value.scrollHeight
// })
})()
// ---------------------------------- 搜索 ----------------------------------
const searchValue = ref('')
// 保证渲染后再获取行高,再计算渲染范围
addTaskToBrowserMainThread(() => {
// 计算
computeRange(document.querySelector('.log-container'))
computeLineHeight()
const search = (value) => {
searchValue.value = value.toLowerCase()
}
// ---------------------------------- 下载 ----------------------------------
const filename = 'print.log'
// 判断是否出现滚动条,如果有滚动条,滚动到底部
if (document.querySelector('.log-container').scrollHeight > document.querySelector('.log-container').clientHeight) {
document.querySelector('.log-container').scrollTop = document.querySelector('.log-container').scrollHeight
}
})
})
</script>
<style lang="scss" scoped>
.log-container {
@apply bg-higher w-full rounded p-4;
@apply bg-higher w-full rounded p-4 h-[76vh] overflow-auto relative;
font-size: 13px;
line-height: 16px;
font-family: 'JetBrains Mono', monospace;
letter-spacing: 0.1px;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
.log-area {
@apply overflow-auto h-full break-all;
@apply relative h-full break-all;
&::-webkit-scrollbar-track {
background: transparent;
}
.log-board {
@apply absolute pb-5 w-full;
}
}
.log-line {
Expand Down
Loading

0 comments on commit a52669b

Please sign in to comment.