482 lines
13 KiB
Vue
482 lines
13 KiB
Vue
<template>
|
|
<div class="space-y-4 p-5">
|
|
<div class="flex space-x-4">
|
|
<FormControl
|
|
class="ml-auto w-32"
|
|
type="select"
|
|
:options="durationOptions"
|
|
v-model="duration"
|
|
/>
|
|
</div>
|
|
<ErrorMessage
|
|
:message="
|
|
$resources.analytics.error || $resources.advancedAnalytics.error
|
|
"
|
|
/>
|
|
|
|
<div class="grid grid-cols-1 gap-5 sm:grid-cols-2">
|
|
<AnalyticsCard title="每日使用量">
|
|
<LineChart
|
|
type="time"
|
|
title="使用计数器"
|
|
:key="usageCounterData"
|
|
:data="usageCounterData"
|
|
unit="seconds"
|
|
:chartTheme="[$theme.colors.purple[500]]"
|
|
:loading="$resources.analytics.loading"
|
|
:showCard="false"
|
|
class="h-[15.55rem] p-2 pb-3"
|
|
/>
|
|
</AnalyticsCard>
|
|
|
|
<AnalyticsCard title="运行时间">
|
|
<SiteUptime
|
|
:data="$resources.analytics?.data?.uptime"
|
|
:loading="$resources.analytics.loading"
|
|
class="h-[15.55rem] p-2 pb-3"
|
|
/>
|
|
</AnalyticsCard>
|
|
|
|
<AnalyticsCard title="请求">
|
|
<LineChart
|
|
type="time"
|
|
title="请求"
|
|
:key="requestCountData"
|
|
:data="requestCountData"
|
|
unit="requests"
|
|
:chartTheme="[$theme.colors.green[500]]"
|
|
:loading="$resources.analytics.loading"
|
|
:showCard="false"
|
|
class="h-[15.55rem] p-2 pb-3"
|
|
/>
|
|
<template #action>
|
|
<router-link
|
|
class="text-base text-gray-600 hover:text-gray-700"
|
|
:to="{ name: 'Site Performance Request Logs' }"
|
|
>
|
|
请求日志报告 →
|
|
</router-link>
|
|
</template>
|
|
</AnalyticsCard>
|
|
|
|
<AnalyticsCard title="请求 CPU 使用率">
|
|
<LineChart
|
|
type="time"
|
|
title="请求 CPU 使用率"
|
|
:key="requestTimeData"
|
|
:data="requestTimeData"
|
|
unit="seconds"
|
|
:chartTheme="[$theme.colors.yellow[500]]"
|
|
:loading="$resources.analytics.loading"
|
|
:showCard="false"
|
|
class="h-[15.55rem] p-2 pb-3"
|
|
/>
|
|
</AnalyticsCard>
|
|
</div>
|
|
|
|
<div
|
|
class="!mt-6 flex w-fit cursor-pointer space-x-2"
|
|
@click="toggleAdvancedAnalytics"
|
|
>
|
|
<h2 class="text-lg font-semibold">高级分析</h2>
|
|
<FeatherIcon
|
|
class="h-5 w-5 text-gray-500 hover:text-gray-700"
|
|
:name="showAdvancedAnalytics ? 'chevron-down' : 'chevron-right'"
|
|
/>
|
|
</div>
|
|
|
|
<!-- 高级分析 -->
|
|
<div
|
|
v-if="showAdvancedAnalytics"
|
|
class="grid grid-cols-1 gap-5 sm:grid-cols-2"
|
|
>
|
|
<AnalyticsCard title="后台任务">
|
|
<LineChart
|
|
type="time"
|
|
title="后台任务"
|
|
:key="jobCountData"
|
|
:data="jobCountData"
|
|
unit="jobs"
|
|
:chartTheme="[$theme.colors.red[500]]"
|
|
:loading="$resources.advancedAnalytics.loading"
|
|
:showCard="false"
|
|
class="h-[15.55rem] p-2 pb-3"
|
|
/>
|
|
</AnalyticsCard>
|
|
|
|
<AnalyticsCard title="后台任务 CPU 使用率">
|
|
<LineChart
|
|
type="time"
|
|
title="后台任务 CPU 使用率"
|
|
:key="jobTimeData"
|
|
:data="jobTimeData"
|
|
unit="seconds"
|
|
:chartTheme="[$theme.colors.blue[500]]"
|
|
:loading="$resources.advancedAnalytics.loading"
|
|
:showCard="false"
|
|
class="h-[15.55rem] p-2 pb-3"
|
|
/>
|
|
</AnalyticsCard>
|
|
|
|
<AnalyticsCard class="sm:col-span-2" title="频繁请求">
|
|
<BarChart
|
|
title="按路径的请求计数"
|
|
:key="requestCountByPathData"
|
|
:data="requestCountByPathData"
|
|
unit="requests"
|
|
:chartTheme="requestChartColors"
|
|
:loading="$resources.advancedAnalytics.loading"
|
|
:showCard="false"
|
|
class="h-[15.55rem] p-2 pb-3"
|
|
/>
|
|
</AnalyticsCard>
|
|
|
|
<AnalyticsCard class="sm:col-span-2" title="最慢请求">
|
|
<BarChart
|
|
:key="requestDurationByPathData"
|
|
:data="requestDurationByPathData"
|
|
unit="秒"
|
|
:chartTheme="requestChartColors"
|
|
:loading="$resources.advancedAnalytics.loading"
|
|
:showCard="false"
|
|
class="h-[15.55rem] p-2 pb-3"
|
|
/>
|
|
</AnalyticsCard>
|
|
|
|
<AnalyticsCard
|
|
class="sm:col-span-2"
|
|
title="单个请求时间(平均)"
|
|
>
|
|
<BarChart
|
|
:key="averageRequestDurationByPathData"
|
|
:data="averageRequestDurationByPathData"
|
|
unit="秒"
|
|
:chartTheme="requestChartColors"
|
|
:loading="$resources.advancedAnalytics.loading"
|
|
:showCard="false"
|
|
class="h-[15.55rem] p-2 pb-3"
|
|
/>
|
|
</AnalyticsCard>
|
|
|
|
<AnalyticsCard class="sm:col-span-2" title="频繁后台任务">
|
|
<BarChart
|
|
:key="backgroundJobCountByMethodData"
|
|
:data="backgroundJobCountByMethodData"
|
|
unit="任务"
|
|
:chartTheme="requestChartColors"
|
|
:loading="$resources.advancedAnalytics.loading"
|
|
:showCard="false"
|
|
class="h-[15.55rem] p-2 pb-3"
|
|
/>
|
|
</AnalyticsCard>
|
|
|
|
<AnalyticsCard class="sm:col-span-2" title="最慢后台任务">
|
|
<BarChart
|
|
:key="backgroundJobDurationByMethodData"
|
|
:data="backgroundJobDurationByMethodData"
|
|
unit="秒"
|
|
:chartTheme="requestChartColors"
|
|
:loading="$resources.advancedAnalytics.loading"
|
|
:showCard="false"
|
|
class="h-[15.55rem] p-2 pb-3"
|
|
/>
|
|
</AnalyticsCard>
|
|
|
|
<AnalyticsCard
|
|
class="sm:col-span-2"
|
|
title="单个后台任务时间(平均)"
|
|
>
|
|
<BarChart
|
|
:key="averageBackgroundJobDurationByMethodData"
|
|
:data="averageBackgroundJobDurationByMethodData"
|
|
unit="秒"
|
|
:chartTheme="requestChartColors"
|
|
:loading="$resources.advancedAnalytics.loading"
|
|
:showCard="false"
|
|
class="h-[15.55rem] p-2 pb-3"
|
|
/>
|
|
</AnalyticsCard>
|
|
|
|
<AnalyticsCard class="sm:col-span-2" title="频繁慢查询">
|
|
<template #action>
|
|
<Tooltip text="显示详细报告">
|
|
<router-link
|
|
class="ml-2 mr-auto text-base text-gray-600 hover:text-gray-700"
|
|
:to="{ name: 'Site Performance Slow Queries' }"
|
|
>
|
|
→
|
|
</router-link>
|
|
</Tooltip>
|
|
<TabButtons
|
|
:buttons="[{ label: '非规范化' }, { label: '规范化' }]"
|
|
v-model="slowLogsFrequencyType"
|
|
/>
|
|
</template>
|
|
<BarChart
|
|
:key="slowLogsCountData"
|
|
:data="slowLogsCountData"
|
|
unit="查询"
|
|
:chartTheme="requestChartColors"
|
|
:loading="$resources.advancedAnalytics.loading"
|
|
:showCard="false"
|
|
class="h-[15.55rem] p-2 pb-3"
|
|
/>
|
|
</AnalyticsCard>
|
|
|
|
<AnalyticsCard class="sm:col-span-2" title="最慢查询">
|
|
<template #action>
|
|
<Tooltip text="显示详细报告">
|
|
<router-link
|
|
class="ml-2 mr-auto text-base text-gray-600 hover:text-gray-700"
|
|
:to="{ name: 'Site Performance Slow Queries' }"
|
|
>
|
|
→
|
|
</router-link>
|
|
</Tooltip>
|
|
<TabButtons
|
|
:buttons="[{ label: '非规范化' }, { label: '规范化' }]"
|
|
v-model="slowLogsDurationType"
|
|
/>
|
|
</template>
|
|
<BarChart
|
|
:key="slowLogsDurationData"
|
|
:data="slowLogsDurationData"
|
|
unit="秒"
|
|
:chartTheme="requestChartColors"
|
|
:loading="$resources.advancedAnalytics.loading"
|
|
:showCard="false"
|
|
class="h-[15.55rem] p-2 pb-3"
|
|
/>
|
|
</AnalyticsCard>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import dayjs from '../../utils/dayjs';
|
|
import LineChart from '@/components/charts/LineChart.vue';
|
|
import BarChart from '@/components/charts/BarChart.vue';
|
|
import SiteUptime from './SiteUptime.vue';
|
|
import AlertBanner from '../AlertBanner.vue';
|
|
import AnalyticsCard from './AnalyticsCard.vue';
|
|
|
|
export default {
|
|
name: 'SiteAnalytics',
|
|
props: ['name'],
|
|
components: {
|
|
BarChart,
|
|
LineChart,
|
|
SiteUptime,
|
|
AlertBanner,
|
|
AnalyticsCard,
|
|
},
|
|
data() {
|
|
return {
|
|
duration: '24h',
|
|
showAdvancedAnalytics: false,
|
|
localTimezone: dayjs.tz.guess(),
|
|
slowLogsDurationType: 'Denormalized',
|
|
slowLogsFrequencyType: 'Denormalized',
|
|
durationOptions: [
|
|
{ label: '时长', value: null, disabled: true },
|
|
{ label: '1小时', value: '1h' },
|
|
{ label: '6小时', value: '6h' },
|
|
{ label: '24小时', value: '24h' },
|
|
{ label: '7天', value: '7d' },
|
|
{ label: '15天', value: '15d' },
|
|
],
|
|
};
|
|
},
|
|
resources: {
|
|
analytics() {
|
|
return {
|
|
url: 'jcloud.api.analytics.get',
|
|
params: {
|
|
name: this.name,
|
|
timezone: this.localTimezone,
|
|
duration: this.duration,
|
|
},
|
|
auto: true,
|
|
};
|
|
},
|
|
advancedAnalytics() {
|
|
return {
|
|
url: 'jcloud.api.analytics.get_advanced_analytics',
|
|
params: {
|
|
name: this.name,
|
|
timezone: this.localTimezone,
|
|
duration: this.duration,
|
|
},
|
|
auto: this.showAdvancedAnalytics,
|
|
};
|
|
},
|
|
slowLogsCount() {
|
|
return {
|
|
url: 'jcloud.api.analytics.get_slow_logs_by_query',
|
|
params: {
|
|
name: this.name,
|
|
agg_type: 'count',
|
|
timezone: this.localTimezone,
|
|
duration: this.duration,
|
|
normalize: this.slowLogsFrequencyType === 'Normalized',
|
|
},
|
|
auto: this.showAdvancedAnalytics,
|
|
};
|
|
},
|
|
slowLogsDuration() {
|
|
return {
|
|
url: 'jcloud.api.analytics.get_slow_logs_by_query',
|
|
params: {
|
|
name: this.name,
|
|
agg_type: 'duration',
|
|
timezone: this.localTimezone,
|
|
duration: this.duration,
|
|
normalize: this.slowLogsDurationType === 'Normalized',
|
|
},
|
|
auto: this.showAdvancedAnalytics,
|
|
};
|
|
},
|
|
},
|
|
computed: {
|
|
requestChartColors() {
|
|
return [
|
|
this.$theme.colors.green[500],
|
|
this.$theme.colors.red[500],
|
|
this.$theme.colors.yellow[500],
|
|
this.$theme.colors.pink[500],
|
|
this.$theme.colors.purple[500],
|
|
this.$theme.colors.blue[500],
|
|
this.$theme.colors.teal[500],
|
|
this.$theme.colors.cyan[500],
|
|
this.$theme.colors.gray[500],
|
|
this.$theme.colors.orange[500],
|
|
];
|
|
},
|
|
usageCounterData() {
|
|
let data = this.$resources.analytics.data?.usage_counter;
|
|
if (!data) return;
|
|
|
|
let plan_limit = this.$resources.analytics.data?.plan_limit;
|
|
|
|
return {
|
|
datasets: [data.map((d) => [+new Date(d.date), d.value / 1000000])],
|
|
// 每日限制标记
|
|
markLine: {
|
|
data: [
|
|
{
|
|
name: '每日计算限制',
|
|
yAxis: plan_limit,
|
|
label: {
|
|
formatter: '{b}: {c} 秒',
|
|
position: 'middle',
|
|
},
|
|
lineStyle: {
|
|
color: '#f5222d',
|
|
},
|
|
},
|
|
],
|
|
symbol: ['none', 'none'],
|
|
},
|
|
};
|
|
},
|
|
requestCountData() {
|
|
let requestCount = this.$resources.analytics.data?.request_count;
|
|
if (!requestCount) return;
|
|
|
|
return {
|
|
datasets: [requestCount.map((d) => [+new Date(d.date), d.value])],
|
|
};
|
|
},
|
|
requestCountByPathData() {
|
|
let requestCountByPath =
|
|
this.$resources.advancedAnalytics.data?.request_count_by_path;
|
|
if (!requestCountByPath) return;
|
|
|
|
return requestCountByPath;
|
|
},
|
|
requestDurationByPathData() {
|
|
let requestDurationByPath =
|
|
this.$resources.advancedAnalytics.data?.request_duration_by_path;
|
|
if (!requestDurationByPath) return;
|
|
|
|
return requestDurationByPath;
|
|
},
|
|
averageRequestDurationByPathData() {
|
|
let averageRequestDurationByPath =
|
|
this.$resources.advancedAnalytics.data
|
|
?.average_request_duration_by_path;
|
|
if (!averageRequestDurationByPath) return;
|
|
|
|
return averageRequestDurationByPath;
|
|
},
|
|
backgroundJobCountByMethodData() {
|
|
let backgroundJobCountByMethod =
|
|
this.$resources.advancedAnalytics.data?.background_job_count_by_method;
|
|
if (!backgroundJobCountByMethod) return;
|
|
|
|
return backgroundJobCountByMethod;
|
|
},
|
|
backgroundJobDurationByMethodData() {
|
|
let backgroundJobDurationByMethod =
|
|
this.$resources.advancedAnalytics.data
|
|
?.background_job_duration_by_method;
|
|
if (!backgroundJobDurationByMethod) return;
|
|
|
|
return backgroundJobDurationByMethod;
|
|
},
|
|
averageBackgroundJobDurationByMethodData() {
|
|
let averageBackgroundJobDurationByMethod =
|
|
this.$resources.advancedAnalytics.data
|
|
?.average_background_job_duration_by_method;
|
|
if (!averageBackgroundJobDurationByMethod) return;
|
|
|
|
return averageBackgroundJobDurationByMethod;
|
|
},
|
|
slowLogsDurationData() {
|
|
const slowLogs = this.$resources.slowLogsDuration.data;
|
|
if (!slowLogs) return;
|
|
|
|
return slowLogs;
|
|
},
|
|
slowLogsCountData() {
|
|
const slowLogs = this.$resources.slowLogsCount.data;
|
|
if (!slowLogs) return;
|
|
|
|
return slowLogs;
|
|
},
|
|
requestTimeData() {
|
|
let requestCpuTime = this.$resources.analytics.data?.request_cpu_time;
|
|
if (!requestCpuTime) return;
|
|
|
|
return {
|
|
datasets: [
|
|
requestCpuTime.map((d) => [+new Date(d.date), d.value / 1000000]),
|
|
],
|
|
};
|
|
},
|
|
jobCountData() {
|
|
let jobCount = this.$resources.advancedAnalytics.data?.job_count;
|
|
if (!jobCount) return;
|
|
|
|
return {
|
|
datasets: [jobCount.map((d) => [+new Date(d.date), d.value])],
|
|
};
|
|
},
|
|
jobTimeData() {
|
|
let jobCpuTime = this.$resources.advancedAnalytics.data?.job_cpu_time;
|
|
if (!jobCpuTime) return;
|
|
|
|
return {
|
|
datasets: [
|
|
jobCpuTime.map((d) => [+new Date(d.date), d.value / 1000000]),
|
|
],
|
|
};
|
|
},
|
|
},
|
|
methods: {
|
|
toggleAdvancedAnalytics() {
|
|
this.showAdvancedAnalytics = !this.showAdvancedAnalytics;
|
|
},
|
|
},
|
|
};
|
|
</script> |