feat: enhance the async-profiling duration options (#472)

This commit is contained in:
Forgottener 2025-06-02 17:18:58 +08:00 committed by GitHub
parent 1f651cf528
commit e4a43d91e2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 59 additions and 6 deletions

View File

@ -401,5 +401,10 @@ const msg = {
recordsTTL: "Records TTL", recordsTTL: "Records TTL",
clusterNodes: "Cluster Nodes", clusterNodes: "Cluster Nodes",
debuggingConfigDump: "Dump Effective Configurations", debuggingConfigDump: "Dump Effective Configurations",
customDuration: "Custom Duration",
maxDuration: "Max Duration",
minutes: "Minutes",
invalidProfilingDurationRange: "Please enter a valid duration between 1 and 900 seconds",
taskCreatedSuccessfully: "Task created successfully",
}; };
export default msg; export default msg;

View File

@ -401,5 +401,10 @@ const msg = {
recordsTTL: "Records TTL", recordsTTL: "Records TTL",
clusterNodes: "Cluster Nodes", clusterNodes: "Cluster Nodes",
debuggingConfigDump: "Dump Effective Configurations", debuggingConfigDump: "Dump Effective Configurations",
customDuration: "Duración Personalizada",
maxDuration: "Duración Máxima",
minutes: "Minutos",
invalidProfilingDurationRange: "Por favor ingrese una duración válida entre 1 y 900 segundos",
taskCreatedSuccessfully: "Tarea creada exitosamente",
}; };
export default msg; export default msg;

View File

@ -399,5 +399,10 @@ const msg = {
recordsTTL: "Records TTL", recordsTTL: "Records TTL",
clusterNodes: "集群节点", clusterNodes: "集群节点",
debuggingConfigDump: "转储有效配置", debuggingConfigDump: "转储有效配置",
customDuration: "自定义时长",
maxDuration: "最大时长",
minutes: "分钟",
invalidProfilingDurationRange: "请输入1到900秒之间的有效时长",
taskCreatedSuccessfully: "任务创建成功",
}; };
export default msg; export default msg;

View File

@ -25,12 +25,25 @@ limitations under the License. -->
:options="asyncProfilingStore.instances" :options="asyncProfilingStore.instances"
placeholder="Select instances" placeholder="Select instances"
@change="changeInstances" @change="changeInstances"
:filterable="false" :filterable="true"
/> />
</div> </div>
<div> <div>
<div class="label">{{ t("duration") }}</div> <div class="label">{{ t("duration") }}</div>
<Radio class="mb-5" :value="duration" :options="DurationOptions" @change="changeDuration" /> <Radio class="mb-5" :value="duration" :options="DurationOptions" @change="changeDuration" />
<div v-if="duration === DurationOptions[5].value" class="custom-duration">
<div class="label">{{ t("customDuration") }} ({{ t("seconds") }})</div>
<el-input
size="small"
class="profile-input"
v-model="customDurationSeconds"
type="number"
:min="1"
:max="900"
placeholder="Enter duration in seconds (1-900)"
/>
<div class="hint">{{ t("maxDuration") }}: 900 {{ t("seconds") }} (15 {{ t("minutes") }})</div>
</div>
</div> </div>
<div> <div>
<div class="label">{{ t("profilingEvents") }}</div> <div class="label">{{ t("profilingEvents") }}</div>
@ -113,6 +126,7 @@ limitations under the License. -->
const execArgs = ref<string>(""); const execArgs = ref<string>("");
const loading = ref<boolean>(false); const loading = ref<boolean>(false);
const PartofEvents = [ProfilingEvents[3], ProfilingEvents[4], ProfilingEvents[5]]; const PartofEvents = [ProfilingEvents[3], ProfilingEvents[4], ProfilingEvents[5]];
const customDurationSeconds = ref<number>(60);
function changeDuration(val: string) { function changeDuration(val: string) {
duration.value = val; duration.value = val;
@ -138,10 +152,22 @@ limitations under the License. -->
} }
async function createTask() { async function createTask() {
let finalDuration: number;
if (duration.value === DurationOptions[5].value) {
if (!customDurationSeconds.value || customDurationSeconds.value < 1 || customDurationSeconds.value > 900) {
ElMessage.error(t("invalidProfilingDurationRange"));
return;
}
finalDuration = customDurationSeconds.value;
} else {
finalDuration = Number(duration.value);
}
const params = { const params = {
serviceId: selectorStore.currentService.id, serviceId: selectorStore.currentService.id,
serviceInstanceIds: serviceInstanceIds.value, serviceInstanceIds: serviceInstanceIds.value,
duration: Number(duration.value) * 60, duration: finalDuration,
events: asyncEvents.value, events: asyncEvents.value,
execArgs: execArgs.value, execArgs: execArgs.value,
}; };
@ -158,7 +184,7 @@ limitations under the License. -->
return; return;
} }
emits("close"); emits("close");
ElMessage.success("Task created successfully"); ElMessage.success(t("taskCreatedSuccessfully"));
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@ -184,4 +210,13 @@ limitations under the License. -->
width: 600px; width: 600px;
margin-top: 50px; margin-top: 50px;
} }
.custom-duration {
margin-top: 10px;
}
.hint {
font-size: $font-size-smaller;
color: var(--text-color-placeholder);
}
</style> </style>

View File

@ -16,9 +16,12 @@
*/ */
export const DurationOptions = [ export const DurationOptions = [
{ value: "5", label: "5 min" }, { value: "30", label: "30 sec" },
{ value: "10", label: "10 min" }, { value: "60", label: "1 min" },
{ value: "15", label: "15 min" }, { value: "300", label: "5 min" },
{ value: "600", label: "10 min" },
{ value: "900", label: "15 min" },
{ value: "custom", label: "Custom" },
]; ];
export const ProfilingEvents = ["CPU", "ALLOC", "LOCK", "WALL", "CTIMER", "ITIMER"]; export const ProfilingEvents = ["CPU", "ALLOC", "LOCK", "WALL", "CTIMER", "ITIMER"];