Merge branch 'apache:main' into main

This commit is contained in:
Brandon Fergerson 2022-05-24 19:43:10 +04:00 committed by GitHub
commit d3f8ceeccf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
31 changed files with 601 additions and 155 deletions

View File

@ -23,6 +23,7 @@ export enum TimeType {
export const Languages = [
{ label: "English", value: "en" },
{ label: "Chinese", value: "zh" },
{ label: "Spanish", value: "es" },
];
export const RoutesMap: { [key: string]: string } = {

View File

@ -45,6 +45,5 @@ export const Alarm = {
endTime
}
}
total
}`,
};

View File

@ -75,9 +75,9 @@ export const queryEBPFSchedules = {
export const analysisEBPFResult = {
variable:
"$scheduleIdList: [ID!]!, $timeRanges: [EBPFProfilingAnalyzeTimeRange!]!",
"$scheduleIdList: [ID!]!, $timeRanges: [EBPFProfilingAnalyzeTimeRange!]!, $aggregateType: EBPFProfilingAnalyzeAggregateType",
query: `
analysisEBPFResult: analysisEBPFProfilingResult(scheduleIdList: $scheduleIdList, timeRanges: $timeRanges) {
analysisEBPFResult: analysisEBPFProfilingResult(scheduleIdList: $scheduleIdList, timeRanges: $timeRanges, aggregateType: $aggregateType) {
tip
trees {
elements {

View File

@ -35,6 +35,5 @@ export const FetchEvents = {
startTime
endTime
}
total
}`,
};

View File

@ -30,7 +30,6 @@ export const QueryBrowserErrorLogs = {
stack
grade
}
total
}`,
};
@ -54,7 +53,6 @@ export const QueryServiceLogs = {
value
}
}
total
}`,
};

View File

@ -27,7 +27,6 @@ export const Traces = {
isError
traceIds
}
total
}`,
};

View File

@ -41,7 +41,7 @@ limitations under the License. -->
<el-icon class="menu-icons" :style="{ marginRight: '12px' }">
<Icon size="lg" :iconName="menu.meta.icon" />
</el-icon>
<span :class="isCollapse ? 'collapse' : ''">
<span class="title" :class="isCollapse ? 'collapse' : ''">
{{ t(menu.meta.title) }}
</span>
</router-link>
@ -57,7 +57,7 @@ limitations under the License. -->
:to="m.path"
:exact="m.meta.exact || false"
>
<span>{{ t(m.meta.title) }}</span>
<span class="title">{{ t(m.meta.title) }}</span>
</router-link>
</el-menu-item>
</el-menu-item-group>
@ -82,7 +82,7 @@ limitations under the License. -->
:to="menu.children[0].path"
:exact="menu.meta.exact"
>
<span>{{ t(menu.meta.title) }}</span>
<span class="title">{{ t(menu.meta.title) }}</span>
</router-link>
</template>
</el-menu-item>
@ -208,4 +208,11 @@ span.collapse {
width: 100%;
height: 60px;
}
.title {
display: inline-block;
max-width: 110px;
text-overflow: ellipsis;
overflow: hidden;
}
</style>

View File

@ -17,10 +17,12 @@
import { createI18n } from "vue-i18n";
import zh from "./lang/zh";
import en from "./lang/en";
import es from "./lang/es";
const messages = {
en,
zh,
es,
};
const savedLanguage = window.localStorage.getItem("language");

View File

@ -136,6 +136,7 @@ const msg = {
targetType: "Target Type",
ebpfTip: "Don't have a process for profiling",
processSelect: "Click to select processes",
page: "Page",
hourTip: "Select Hour",
minuteTip: "Select Minute",
secondTip: "Select Second",

333
src/locales/lang/es.ts Normal file
View File

@ -0,0 +1,333 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
const msg = {
general: "Servicio General",
services: "Servicios",
service: "Servicio",
traces: "Trazas",
metrics: "Métricas",
serviceMesh: "Malla de Servicios",
infrastructure: "Infraestructura",
virtualMachine: "Máquina Virtual",
dashboardNew: "Nuevo Panel",
dashboardList: "Listado Paneles",
logs: "Logs",
events: "Eventos",
alerts: "Alertas",
settings: "Ajustes",
dashboards: "Paneles",
profiles: "Perfiles",
database: "Base de Datos",
serviceName: "Nombre Servicio",
technologies: "Tecnologías",
generalServicePanel: "Panel Servicio General",
health: "Salud",
groupName: "Nombre Grupo",
topologies: "Topologías",
dataPanel: "Plano de Datos",
controlPanel: "Plano de Control",
eventList: "Listado Eventos",
newDashboard: "Crear panel nuevo",
dashboardEdit: "Editar el panel",
edit: "Editar",
delete: "Eliminar",
confirm: "Confirmar",
layer: "Capa",
endpoint: "Endpoint",
instance: "Instancia",
create: "Crear",
loading: "Cargando",
selectVisualization: "Visualiza tus métricas",
visualization: "Visualizaciones",
graphStyles: "Estilo de gráficas",
widgetOptions: "Opciones widget",
standardOptions: "Opciones estandar",
max: "Máx",
min: "Mín",
plus: "Más",
minus: "Menoss",
multiply: "Multiplcar",
divide: "Dividir",
convertToMilliseconds: "Convertir Unix Timestamp(milisegundos)",
convertToSeconds: "Convertir Unix Timestamp(segundos)",
smooth: "Suabe",
showSymbol: "Mostrar Símbolo",
step: "Paso",
showValues: "Mostrar Valores",
fontSize: "Tamaño Fuente",
showBackground: "Mostrar Fondo",
areaOpacity: "Opacidad Área",
editGraph: "Editar Opciones",
dashboardName: "Selecciona Nombre del Panel",
linkDashboard: "Nombre del panel relacionado con llamadas de la topología",
linkServerMetrics: "Métricas de servidor relacionadas con llamadas de la topología",
linkClientMetrics: "Métricas de cliente relacionadas con llamadas de la topología",
nodeDashboard: "Nombre del panel relacionado con nodos de la topología",
nodeMetrics: "Mêtricas relacionas con nodos de la topología",
instanceDashboard: "Nombre del panel relacionado con instancias de servicio",
endpointDashboard: "Nombre del panel relacionado con endpoints",
callSettings: "Ajustes Llamada",
nodeSettings: "Ajustes Nodo",
conditions: "Condiciones",
legendSettings: "Ajustes Leyenda",
setLegend: "Poner Leyenda",
backgroundColors: "Colores Fondo",
fontColors: "Colores Fuente",
iconTheme: "Tema Iconos",
default: "Por Defecto",
topSlow: "Top 5 lentos",
topChildren: "Top 5 hijos",
taskList: "Listado Tareas",
sampledTraces: "Trazas Muestreadas",
editTab: "Habilitar edición nombre pestanyas",
label: "Nombre Servicio",
id: "ID Servicio",
setRoot: "Ponerlo a raíz",
setNormal: "Ponerlo a normal",
export: "Exportar Plantilla Panel",
import: "Importar Plantilla Panel",
yes: "Sí",
no: "No",
tableHeaderCol1: "Nombre de la primera columna de la tabla",
tableHeaderCol2: "Nombre de la segunda columna de la tabla",
showXAxis: "Mostrar Eje X",
showYAxis: "Mostrar Eje Y",
nameError: "El nombre del panel no puede ser duplicado",
showGroup: "Mostrar Grupo",
noRoot: "Por favor ponga la raíz del panel",
noWidget: "Por favor añada widgets.",
rename: "Renombrar",
deleteTitle: "¿Está seguro que quiere eliminarlo?",
rootTitle: "¿Está seguro que quiere establecerlo?",
selfObservability: "Autoobservabilidad",
satellite: "Satéllite",
skyWalkingServer: "Servidor SkyWalking",
functions: "Funciones",
browser: "Navegador",
linux: "Linux",
editWarning: "Estás entrando en modo edición",
viewWarning: "Estás entrando en modo visualización",
virtualDatabase: "Base de Datos Virtual",
reloadDashboards: "Recargar Panel",
kubernetesService: "Servicio",
kubernetesCluster: "Cluster",
kubernetes: "Kubernetes",
textUrl: "Hipervínculo de Texto",
textAlign: "Alineación de Texto",
metricLabel: "Etiqueta de Métrica",
showUnit: "Mostrar Unidad",
noGraph: "Ningún Gráfico",
taskId: "ID Tarea",
triggerType: "Tipo de Disparador",
targetType: "Tipo de Objetivo",
ebpfTip: "Le falta el proceso para perfilar",
processSelect: "Click para seleccionar proceso",
page: "Página",
hourTip: "Seleccione Hora",
minuteTip: "Seleccione Minuto",
secondTip: "Seleccione Segundo",
second: "s",
yearSuffix: "Año",
monthsHead: "Ene_Feb_Mar_Abr_May_Jun_Jul_Ago_Set_Oct_Nov_Dic",
months: "Ene_Feb_Mar_Abr_May_Jun_Jul_Ago_Set_Oct_Nov_Dic",
weeks: "Lun_Mar_Mier_Jue_Vie_Sáb_Dom",
hello: "Hola",
helloMessage: "Bienvenido de vuelta, Apache SkyWalking APM System !",
username: "Usuario",
password: "Contraseña",
title: "Título",
width: "Ancho",
height: "Alto",
dashboard: "Panel",
topology: "Topología",
trace: "Traza",
alarm: "Alarmas",
auto: "Auto",
reload: "Recargar",
version: "Versión",
copy: "Copiar",
reset: "Resetear",
apply: "Aplicar",
template: "Plantilla",
cancel: "Cancelar",
createTab: "Crear Pestanya",
tabName: "Nombre de la Pestaña",
detectPoint: "Detectar Punto",
name: "Nombre",
types: "Tipos",
all: "Todo",
endpoints: "Endpoints",
cache: "Cache",
serviceinstance: "InstanciaServicio",
databaseaccess: "AccesoBaseDeDatos",
servicerelation: "RelaciónServicio",
serviceinstancerelation: "RelaciónInstanciaServicio",
endpointrelation: "RelaciónEndpoint",
status: "Estado",
endpointName: "Nombre Endpoint",
search: "Buscar",
clear: "Limpiar",
more: "Más",
traceID: "ID Traza",
range: "Rango",
timeRange: "Rango de Tiempo",
duration: "Duración",
startTime: "Hora Inicio",
start: "Incio",
spans: "Lapso",
spanInfo: "Info Lapso",
spanType: "Tipo de Lapso",
time: "Tiempo",
tags: "Etiquetas",
component: "Componente",
table: "Tabla",
list: "Lista",
tree: "Árbol",
filterScope: "Alcance de Filtro",
searchKeyword: "Palabra Clave",
quarterHourCutTip: "Últimos 15 mins",
halfHourCutTip: "Últimos 30 mins",
hourCutTip: "Última 1 hora",
dayCutTip: "Último 1 día",
weekCutTip: "Última 1 semana",
monthCutTip: "Última 1 mes",
serverZone: "Zona Horaria Servidor OAP",
exportImage: "Exportar imagen",
object: "Objecto",
profile: "Perfil",
newTask: "Nueva Tarea",
monitorTime: "Tiempo Monitorización",
monitorDuration: "Duración Monitorización",
minThreshold: "Mínn Umbral Duración",
dumpPeriod: "Volcar Periodo",
createTask: "Crear Tarea",
maxSamplingCount: "Máx Cantidad Mostreo",
analyze: "Analizar",
noData: "Ningún Dato",
taskInfo: "Información Tarea",
task: "Tarea",
operationType: "Tipo Operación",
operationTime: "Tiempo Operación",
taskView: "Ver Tarea",
includeChildren: "Incluir Hijos",
excludeChildren: "Excluir Hijos",
view: "Ver",
timeTips: "Intervalo de tiempo no puede excedir 60 dias",
entityType: "Tipo Entidad",
maxItemNum: "Máx número artículos",
unknownMetrics: "Métrica desconocida",
labels: "Etiquetas",
aggregation: "Cálculo",
unit: "Unidad",
labelsIndex: "Subíndice Etiqueta",
group: "Grupo Servicio",
browserView: "Navegador",
sortOrder: "Orden de clasificación",
chartType: "Tipo Gráfico",
currentDepth: "Profundidad actual",
showDepth: "Mostrar Selector Profundidad",
defaultDepth: "Profundidad Por Defecto",
traceTagsTip: `Solamente etiquetas definidas en core/default/searchableTracesTags pueden ser buscadas.
Más información en la página de Vocabulario de Configuración`,
logTagsTip: `Solamente etiquetas definidas en core/default/searchableLogsTags pueden ser buscadas.
Más información en la página de Vocabulario de Configuración`,
alarmTagsTip: `Solamente etiquetas definidas en core/default/searchableAlarmTags pueden ser buscadas.
Más información en la página de Vocabulario de Configuración`,
tagsLink: "Página de Vocabulario de Configuración",
addTag: "Por favor introduzca una etiqueta",
log: "Registro de Datos",
logCategory: "Categoría Registro de Datos",
errorCatalog: "Catálogo de Errores",
logDetail: "Detalle Registro de Datos",
timeReload: "Aviso: El intervalo de tiempo tiene que ser mayor que 0",
errorInfo: "Info Error",
stack: "Pila",
serviceVersion: "Versión Servicio",
errorPage: "Página de Error",
category: "Categoría",
grade: "Grado",
relatedTraceLogs: "Registro de Datos Relacionados",
setConditions: "Más Condiciones",
metricName: "Seleccionar Nombre Métrica",
keywordsOfContent: "Claves de Contenido",
excludingKeywordsOfContent: "Excluir Claves de Contenido",
return: "Volver",
isError: "Error",
contentType: "Tipo de Contenido",
content: "Contenido",
viewLogs: "Ver Registro de Datos",
logsTagsTip: `Solamente etiquetas definidas en core/default/searchableLogsTags pueden ser buscadas.
Más información en la página de Vocabulario de Configuración`,
keywordsOfContentLogTips:
"El almacenamiento actual del servidor SkyWalking OAP no lo soporta.",
setEvent: "Establecer Evento",
viewAttributes: "Ver",
serviceEvents: "Eventos Servico",
select: "Seleccionar",
eventID: "ID Evento",
eventName: "Nombre Evento",
endTime: "Hora Finalización",
instanceEvents: "Eventos Instancia",
endpointEvents: "Eventos Endpoint",
enableEvents: "Habilitar Eventos",
disableEvents: "Deshabilitar Eventos",
eventSeries: "Serie de Eventos",
eventsType: "Tipo de Evento",
eventsMessage: "Mensaje del Evento",
eventsParameters: "Parámetro del Evento",
eventDetail: "Detalle del Evento",
value: "Valor",
show: "Mostrar",
hide: "Oculatr",
statistics: "Estadísticas",
message: "Mensaje",
tooltipsContent: "Contenido de Información de Herramienta",
alarmDetail: "Detalle Alarma",
scope: "Alcance",
destService: "Servicio Destinación",
destServiceInstance: "Instancia Servicio Destinación",
destEndpoint: "Endpoint Destinación",
eventSource: "Fuente Envento",
modalTitle: "Inspección",
selectRedirectPage: "Quiere inspeccionar las Trazas or Registros de datos del servicio %s?",
logAnalysis: "Lenguaje de Análisis de Registro de Datos",
logDataBody: "Contenido del Registro de Datos",
addType: "Por favor introduzca un tipo",
traceContext: "Registro de datos con contexto de traza",
traceSegmentId: "ID Segmento Traza",
spanId: "ID Lapso",
inputTraceSegmentId: "Por favor introduzca el ID del segmento de la traza",
inputSpanId: "Por favor introduzca el ID del lapso",
inputTraceId: "Por favor introduzca el ID de la traza",
dsl: "Entrada de guión para LAL",
logContentType: "Tipo del registro de datos",
logRespContent: "Contenido Registro de Datos",
analysis: "Análisis",
waitLoading: "Cargando",
dslEmpty: "Entrada de guión de LAL no puede estar vacio",
logContentEmpty: "El contenido del registro de datos no puede estar vacio.",
debug: "Debugar",
addTraceID: "Por favor introduzca el ID de la traza",
addTags: "Por favor introduzaca una etiqueta",
addKeywordsOfContent: "Por favor introduzca una clave de contenido",
addExcludingKeywordsOfContent: "Por favor introduzca una clave excluyente de contenido",
noticeTag: "Por favor presione Intro después de introducir una etiqueta(clave=valor).",
conditionNotice:
"Aviso: Por favor presione Intro después de introducir una clave de contenido, excluir clave de contenido(clave=valor).",
language: "Lenguaje",
};
export default msg;

View File

@ -134,6 +134,7 @@ const msg = {
targetType: "目标类型",
processSelect: "点击选择进程",
ebpfTip: "没有进程可以分析",
page: "页面",
hourTip: "选择小时",
minuteTip: "选择分钟",
secondTip: "选择秒数",

View File

@ -22,7 +22,6 @@ import {
EBPFTaskList,
AnalyzationTrees,
} from "@/types/ebpf";
import { Trace, Span } from "@/types/trace";
import { store } from "@/store";
import graphql from "@/graphql";
import { AxiosResponse } from "axios";
@ -35,6 +34,7 @@ interface EbpfStore {
labels: Option[];
couldProfiling: boolean;
tip: string;
selectedTask: Recordable<EBPFTaskList>;
}
export const ebpfStore = defineStore({
@ -47,14 +47,18 @@ export const ebpfStore = defineStore({
labels: [{ value: "", label: "" }],
couldProfiling: false,
tip: "",
selectedTask: {},
}),
actions: {
setCurrentSpan(span: Span) {
this.currentSpan = span;
setSelectedTask(task: EBPFTaskList) {
this.selectedTask = task;
},
setCurrentSchedule(s: Trace) {
setCurrentSchedule(s: EBPFProfilingSchedule) {
this.currentSchedule = s;
},
setAnalyzeTrees(tree: AnalyzationTrees[]) {
this.analyzeTrees = tree;
},
async getCreateTaskData(serviceId: string) {
const res: AxiosResponse = await graphql
.query("getCreateTaskData")
@ -93,7 +97,7 @@ export const ebpfStore = defineStore({
if (res.data.errors) {
return res.data;
}
this.taskList = res.data.data.queryEBPFTasks.reverse() || [];
this.taskList = res.data.data.queryEBPFTasks || [];
if (!this.taskList.length) {
return res.data;
}
@ -118,13 +122,14 @@ export const ebpfStore = defineStore({
this.eBPFSchedules = eBPFSchedules;
if (!eBPFSchedules.length) {
this.eBPFSchedules = [];
this.analyzeTrees = [];
}
this.analyzeTrees = [];
return res.data;
},
async getEBPFAnalyze(params: {
scheduleIdList: string[];
timeRanges: Array<{ start: number; end: number }>;
aggregateType: string;
}) {
if (!params.scheduleIdList.length) {
return new Promise((resolve) => resolve({}));

View File

@ -25,7 +25,6 @@ import { useAppStoreWithOut } from "@/store/modules/app";
interface eventState {
loading: boolean;
events: Event[];
total: number;
services: Service[];
instances: Instance[];
endpoints: Endpoint[];
@ -37,12 +36,11 @@ export const eventStore = defineStore({
state: (): eventState => ({
loading: false,
events: [],
total: 0,
services: [{ value: "", label: "All" }],
instances: [{ value: "", label: "All" }],
endpoints: [{ value: "", label: "All" }],
condition: {
paging: { pageNum: 1, pageSize: 15, needTotal: true },
paging: { pageNum: 1, pageSize: 15 },
},
}),
actions: {
@ -117,7 +115,6 @@ export const eventStore = defineStore({
return item;
}
);
this.total = res.data.data.fetchEvents.total;
}
return res.data;
},

View File

@ -31,7 +31,6 @@ interface LogState {
selectorStore: any;
supportQueryLogsByKeywords: boolean;
logs: any[];
logsTotal: number;
loadLogs: boolean;
}
@ -43,12 +42,11 @@ export const logStore = defineStore({
endpoints: [{ value: "0", label: "All" }],
conditions: {
queryDuration: useAppStoreWithOut().durationTime,
paging: { pageNum: 1, pageSize: 15, needTotal: true },
paging: { pageNum: 1, pageSize: 15 },
},
supportQueryLogsByKeywords: true,
selectorStore: useSelectorStore(),
logs: [],
logsTotal: 0,
loadLogs: false,
}),
actions: {
@ -131,7 +129,6 @@ export const logStore = defineStore({
}
this.logs = res.data.data.queryLogs.logs;
this.logsTotal = res.data.data.queryLogs.total;
return res.data;
},
async getBrowserLogs() {
@ -145,7 +142,6 @@ export const logStore = defineStore({
return res.data;
}
this.logs = res.data.data.queryBrowserErrorLogs.logs;
this.logsTotal = res.data.data.queryBrowserErrorLogs.total;
return res.data;
},
async getLogTagKeys() {

View File

@ -28,12 +28,10 @@ interface TraceState {
instances: Instance[];
endpoints: Endpoint[];
traceList: Trace[];
traceTotal: number;
traceSpans: Span[];
currentTrace: Trace | any;
conditions: any;
traceSpanLogs: any[];
traceSpanLogsTotal: number;
selectorStore: any;
}
@ -45,16 +43,14 @@ export const traceStore = defineStore({
endpoints: [{ value: "0", label: "All" }],
traceList: [],
traceSpans: [],
traceTotal: 0,
currentTrace: {},
conditions: {
queryDuration: useAppStoreWithOut().durationTime,
traceState: "ALL",
queryOrder: "BY_START_TIME",
paging: { pageNum: 1, pageSize: 15, needTotal: true },
paging: { pageNum: 1, pageSize: 20 },
},
traceSpanLogs: [],
traceSpanLogsTotal: 0,
selectorStore: useSelectorStore(),
}),
actions: {
@ -115,7 +111,6 @@ export const traceStore = defineStore({
return res.data;
}
if (!res.data.data.data.traces.length) {
this.traceTotal = 0;
this.traceList = [];
this.setCurrentTrace({});
this.setTraceSpans([]);
@ -128,7 +123,6 @@ export const traceStore = defineStore({
});
return d;
});
this.traceTotal = res.data.data.data.total;
this.setCurrentTrace(res.data.data.data.traces[0] || {});
return res.data;
},
@ -148,11 +142,9 @@ export const traceStore = defineStore({
.params(params);
if (res.data.errors) {
this.traceSpanLogs = [];
this.traceSpanLogsTotal = 0;
return res.data;
}
this.traceSpanLogs = res.data.data.queryLogs.logs || [];
this.traceSpanLogsTotal = res.data.data.queryLogs.total;
return res.data;
},
async getTagKeys() {

View File

@ -194,10 +194,11 @@ const setUTCMin = () => {
}
.label {
width: 160px;
width: 180px;
display: inline-block;
font-weight: 500;
color: #000;
line-height: 25px;
}
}
</style>

View File

@ -39,8 +39,8 @@ limitations under the License. -->
<el-pagination
v-model:currentPage="pageNum"
v-model:page-size="pageSize"
layout="prev, jumper, total, next"
:total="alarmStore.total"
layout="prev, pager, next"
:total="total"
@current-change="changePage"
:pager-count="5"
small
@ -55,7 +55,7 @@ limitations under the License. -->
</nav>
</template>
<script lang="ts" setup>
import { ref } from "vue";
import { ref, computed } from "vue";
import { useI18n } from "vue-i18n";
import ConditionTags from "@/views/components/ConditionTags.vue";
import { AlarmOptions } from "./data";
@ -70,6 +70,11 @@ const pageSize = 20;
const entity = ref<string>("");
const keyword = ref<string>("");
const pageNum = ref<number>(1);
const total = computed(() =>
alarmStore.alarms.length === pageSize
? pageSize * pageNum.value + 1
: pageSize * pageNum.value
);
refreshAlarms({ pageNum: 1 });
@ -79,7 +84,6 @@ async function refreshAlarms(param: { pageNum: number; tagsMap?: any }) {
paging: {
pageNum: param.pageNum,
pageSize,
needTotal: true,
},
tags: param.tagsMap,
};

View File

@ -94,6 +94,8 @@ function setCurrentLog(log: any) {
font-size: 12px;
height: 100%;
border-bottom: 1px solid #eee;
width: 100%;
overflow: auto;
}
.log-header {

View File

@ -46,11 +46,13 @@ import EBPFStack from "./components/EBPFStack.vue";
.item {
width: 100%;
overflow: auto;
height: calc(100% - 70px);
height: calc(100% - 100px);
padding-bottom: 10px;
}
.schedules {
height: 60px;
height: 90px;
border-bottom: 1px solid #ccc;
padding-right: 10px;
}
</style>

View File

@ -13,74 +13,87 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. -->
<template>
<div class="filters flex-h">
<Selector
:value="selectedLabels"
:options="labels"
size="small"
placeholder="Please select labels"
@change="changeLabels"
class="inputs mr-10"
:multiple="true"
/>
<el-button type="primary" size="small">
<span>{{ duration[0] }}</span>
<span> ~ </span>
<span>{{ duration[1] }}</span>
</el-button>
<el-popover placement="bottom" :width="680" trigger="click">
<template #reference>
<el-button type="primary" size="small">
{{ t("processSelect") }}
</el-button>
</template>
<el-input
v-model="searchText"
placeholder="Please input name"
class="input-with-search"
<div class="filters">
<div class="mb-10 flex-h">
<Selector
:value="selectedLabels"
:options="labels"
size="small"
@change="searchProcesses(0)"
>
<template #append>
<el-button size="small">
<Icon size="sm" iconName="search" />
placeholder="Please select labels"
@change="changeLabels"
class="inputs mr-10"
:multiple="true"
/>
<div class="mr-5 duration" v-if="duration.length">
<span>{{ duration[0] }}</span>
<span> ~ </span>
<span>{{ duration[1] }}</span>
</div>
</div>
<div class="flex-h">
<Selector
v-if="ebpfStore.selectedTask.targetType === 'OFF_CPU'"
:value="aggregateType"
:options="AggregateTypes"
size="small"
placeholder="Please select a type"
@change="changeAggregateType"
class="selector mr-10"
/>
<el-popover placement="bottom" :width="680" trigger="click">
<template #reference>
<el-button type="primary" size="small">
{{ t("processSelect") }}
</el-button>
</template>
</el-input>
<el-table
:data="currentProcesses"
ref="multipleTableRef"
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" width="55" />
<el-table-column
v-for="(h, index) of TableHeader"
:property="h.property"
:label="h.label"
:key="index"
width="150"
/>
<el-table-column width="300" label="Attributes">
<template #default="scope">
{{ scope.row.attributes.map((d: {name: string, value: string}) => `${d.name}=${d.value}`).join("; ") }}
<el-input
v-model="searchText"
placeholder="Please input name"
class="input-with-search"
size="small"
@change="searchProcesses(0)"
>
<template #append>
<el-button size="small">
<Icon size="sm" iconName="search" />
</el-button>
</template>
</el-table-column>
</el-table>
<el-pagination
class="pagination"
background
small
layout="prev, pager, next"
:page-size="pageSize"
:total="processes.length"
@current-change="changePage"
@prev-click="changePage"
@next-click="changePage"
/>
</el-popover>
<el-button type="primary" size="small" @click="analyzeEBPF">
{{ t("analyze") }}
</el-button>
</el-input>
<el-table
:data="currentProcesses"
ref="multipleTableRef"
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" width="55" />
<el-table-column
v-for="(h, index) of TableHeader"
:property="h.property"
:label="h.label"
:key="index"
width="150"
/>
<el-table-column width="300" label="Attributes">
<template #default="scope">
{{ scope.row.attributes.map((d: {name: string, value: string}) => `${d.name}=${d.value}`).join("; ") }}
</template>
</el-table-column>
</el-table>
<el-pagination
class="pagination"
background
small
layout="prev, pager, next"
:page-size="pageSize"
:total="processes.length"
@current-change="changePage"
@prev-click="changePage"
@next-click="changePage"
/>
</el-popover>
<el-button type="primary" size="small" @click="analyzeEBPF">
{{ t("analyze") }}
</el-button>
</div>
</div>
</template>
<script lang="ts" setup>
@ -88,7 +101,7 @@ import { ref, watch } from "vue";
import dayjs from "dayjs";
import { useI18n } from "vue-i18n";
import { Option } from "@/types/app";
import { TableHeader } from "./data";
import { TableHeader, AggregateTypes } from "./data";
import { useEbpfStore } from "@/store/modules/ebpf";
import { EBPFProfilingSchedule, Process } from "@/types/ebpf";
import { ElMessage, ElTable } from "element-plus";
@ -103,6 +116,7 @@ const processes = ref<Process[]>([]);
const currentProcesses = ref<Process[]>([]);
const selectedLabels = ref<string[]>(["0"]);
const searchText = ref<string>("");
const aggregateType = ref<string>(AggregateTypes[0].value);
const duration = ref<string[]>([]);
const dateFormat = (date: number, pattern = "YYYY-MM-DD HH:mm:ss") =>
dayjs(date).format(pattern);
@ -112,6 +126,11 @@ function changeLabels(opt: any[]) {
selectedLabels.value = arr;
}
function changeAggregateType(opt: any[]) {
aggregateType.value = opt[0].value;
ebpfStore.setAnalyzeTrees([]);
}
const handleSelectionChange = (arr: Process[]) => {
selectedProcesses.value = arr.map((d: Process) => d.id);
};
@ -152,6 +171,7 @@ async function analyzeEBPF() {
const res = await ebpfStore.getEBPFAnalyze({
scheduleIdList,
timeRanges,
aggregateType: aggregateType.value,
});
if (res.data.errors) {
ElMessage.error(res.data.errors);
@ -159,7 +179,7 @@ async function analyzeEBPF() {
}
}
function visTimeline() {
function getSchedules() {
labels.value = [{ label: "All", value: "0" }];
selectedLabels.value = ["0"];
processes.value = [];
@ -170,11 +190,16 @@ function visTimeline() {
processes.value.push(d.process);
return [d.startTime / 10000, d.endTime / 10000];
});
const arr = ranges.flat(1);
const min = Math.min(...arr);
const max = Math.max(...arr);
duration.value = [dateFormat(min * 10000), dateFormat(max * 10000)];
if (ranges.length) {
const arr = ranges.flat(1);
const min = Math.min(...arr);
const max = Math.max(...arr);
duration.value = [dateFormat(min * 10000), dateFormat(max * 10000)];
} else {
duration.value = [];
}
searchProcesses(0);
analyzeEBPF();
}
function changePage(pageIndex: number) {
@ -216,7 +241,7 @@ function searchAttribute(
watch(
() => ebpfStore.eBPFSchedules,
() => {
visTimeline();
getSchedules();
}
);
</script>
@ -235,7 +260,7 @@ watch(
}
.inputs {
width: 300px;
width: 350px;
}
.input-with-search {
@ -246,4 +271,12 @@ watch(
.pagination {
margin-top: 10px;
}
.selector {
width: 120px;
}
.duration {
line-height: 30px;
}
</style>

View File

@ -68,12 +68,13 @@ function drawGraph() {
root.value = param[0];
root.dumpCount = param[1];
stackTree.value = root;
const w = (graph.value && graph.value.getBoundingClientRect().width) || 10;
const width = (graph.value && graph.value.getBoundingClientRect().width) || 0;
const w = width < 800 ? 802 : width;
flameChart.value = flamegraph()
.width(w - 15)
.cellHeight(18)
.transitionDuration(750)
.minFrameSize(5)
.minFrameSize(1)
.transitionEase(d3.easeCubic as any)
.sort(true)
.title("")

View File

@ -86,6 +86,7 @@ import { useSelectorStore } from "@/store/modules/selectors";
import { useAppStoreWithOut } from "@/store/modules/app";
import { ElMessage } from "element-plus";
import { InitTaskField, TargetTypes } from "./data";
/* global defineEmits */
const emits = defineEmits(["close"]);
const eBPFStore = useEbpfStore();
@ -97,6 +98,7 @@ const type = ref<string>(TargetTypes[0].value);
const monitorTime = ref<string>(InitTaskField.monitorTimeEn[0].value);
const monitorDuration = ref<number>(10);
const time = ref<Date>(appStore.durationRow.start);
const disabled = ref<boolean>(false);
function changeMonitorTime(opt: string) {
monitorTime.value = opt;
@ -111,19 +113,24 @@ function changeType(opt: any[]) {
}
async function createTask() {
if (disabled.value) {
return;
}
disabled.value = true;
const date = monitorTime.value === "0" ? new Date() : time.value;
const params = {
serviceId: selectorStore.currentService.id,
processLabels: labels.value,
startTime: date.getTime(),
duration: monitorDuration.value * 60,
targetType: "ON_CPU",
targetType: type.value,
};
const res = await eBPFStore.createTask(params);
if (res.errors) {
ElMessage.error(res.errors);
return;
}
disabled.value = false;
if (!res.data.createTaskData.status) {
ElMessage.error(res.data.createTaskData.errorReason);
return;

View File

@ -34,7 +34,15 @@ limitations under the License. -->
}"
>
<div class="ell">
<span>{{ i.processLabels.join(" ") }}</span>
<span>
{{
i.targetType +
": " +
(i.processLabels.length
? i.processLabels.join(" ")
: `All Processes`)
}}
</span>
<a class="profile-btn r" @click="viewDetail = true">
<Icon iconName="view" size="middle" />
</a>
@ -74,7 +82,9 @@ limitations under the License. -->
</div>
<div class="mb-10 clear item">
<span class="g-sm-4 grey">{{ t("labels") }}:</span>
<span class="g-sm-8 wba">{{ selectedTask.processLabels }}</span>
<span class="g-sm-8 wba">
{{ selectedTask.processLabels.join(";") }}
</span>
</div>
<div class="mb-10 clear item">
<span class="g-sm-4 grey">{{ t("monitorTime") }}:</span>
@ -117,6 +127,7 @@ const viewDetail = ref<boolean>(false);
async function changeTask(item: EBPFTaskList) {
selectedTask.value = item;
ebpfStore.setSelectedTask(item);
const res = await ebpfStore.getEBPFSchedules({
taskId: item.taskId,
});
@ -128,6 +139,7 @@ watch(
() => ebpfStore.taskList,
() => {
selectedTask.value = ebpfStore.taskList[0] || {};
ebpfStore.setSelectedTask(selectedTask.value);
}
);
</script>

View File

@ -28,7 +28,15 @@ export const NewTaskField = {
maxSamplingCount: { key: 5, label: "5" },
};
export const TargetTypes = [{ label: "ON_CPU", value: "ON_CPU" }];
export const TargetTypes = [
{ label: "ON_CPU", value: "ON_CPU" },
{ label: "OFF_CPU", value: "OFF_CPU" },
];
export const AggregateTypes = [
{ label: "Count", value: "COUNT" },
{ label: "Duration", value: "DURATION" },
];
export const InitTaskField = {
monitorTimeEn: [

View File

@ -37,9 +37,9 @@ limitations under the License. -->
/>
</div>
<div class="mr-5" v-if="dashboardStore.entity !== EntityType[2].value">
<span class="grey mr-5"
>{{ isBrowser ? t("page") : t("endpoint") }}:</span
>
<span class="grey mr-5">
{{ isBrowser ? t("page") : t("endpoint") }}:
</span>
<Selector
size="small"
:value="state.endpoint.value"
@ -226,10 +226,16 @@ function searchLogs() {
endpointId: endpoint || state.endpoint.id || undefined,
serviceInstanceId: instance || state.instance.id || undefined,
queryDuration: appStore.durationTime,
keywordsOfContent: keywordsOfContent.value,
excludingKeywordsOfContent: excludingKeywordsOfContent.value,
keywordsOfContent:
dashboardStore.layerId === "BROWSER"
? undefined
: keywordsOfContent.value,
excludingKeywordsOfContent:
dashboardStore.layerId === "BROWSER"
? undefined
: excludingKeywordsOfContent.value,
tags: tagsMap.value.length ? tagsMap.value : undefined,
paging: { pageNum: 1, pageSize: 15, needTotal: true },
paging: { pageNum: 1, pageSize: 15 },
relatedTrace: traceId.value ? { traceId: traceId.value } : undefined,
});
queryLogs();

View File

@ -26,8 +26,10 @@ limitations under the License. -->
<el-pagination
v-model:currentPage="logStore.conditions.paging.pageNum"
v-model:page-size="pageSize"
layout="prev, pager, next, jumper"
:total="logStore.logsTotal"
:small="true"
layout="prev, pager, next"
:pager-count="5"
:total="total"
@current-change="updatePage"
:style="`float: right`"
/>
@ -35,7 +37,7 @@ limitations under the License. -->
</div>
</template>
<script lang="ts" setup>
import { ref } from "vue";
import { ref, computed } from "vue";
import { useI18n } from "vue-i18n";
import LogTable from "@/views/dashboard/related/components/LogTable/Index.vue";
import { useLogStore } from "@/store/modules/log";
@ -49,9 +51,14 @@ const type = ref<string>(
dashboardStore.layerId === "BROWSER" ? "browser" : "service"
);
const pageSize = ref<number>(15);
const total = computed(() =>
logStore.logs.length === pageSize.value
? pageSize.value * logStore.conditions.paging.pageNum + 1
: pageSize.value * logStore.conditions.paging.pageNum
);
function updatePage(p: number) {
logStore.setLogCondition({
paging: { pageNum: p, pageSize: pageSize.value, needTotal: true },
paging: { pageNum: p, pageSize: pageSize.value },
});
queryLogs();
}

View File

@ -44,7 +44,9 @@ limitations under the License. -->
v-model:currentPage="pageNum"
v-model:page-size="pageSize"
:small="true"
:total="traceStore.traceSpanLogsTotal"
layout="prev, pager, next"
:pager-count="5"
:total="total"
@current-change="turnLogsPage"
/>
<LogTable
@ -146,7 +148,7 @@ limitations under the License. -->
</template>
<script lang="ts">
import dayjs from "dayjs";
import { ref, defineComponent } from "vue";
import { ref, defineComponent, computed } from "vue";
import { useI18n } from "vue-i18n";
import { useTraceStore } from "@/store/modules/trace";
import { Option } from "@/types/app";
@ -171,6 +173,11 @@ export default defineComponent({
const displayMode = ref<string>("List");
const pageNum = ref<number>(1);
const pageSize = 10;
const total = computed(() =>
traceStore.traceList.length === pageSize
? pageSize * pageNum.value + 1
: pageSize * pageNum.value
);
const dateFormat = (date: number, pattern = "YYYY-MM-DD HH:mm:ss") =>
dayjs(date).format(pattern);
const showTraceLogs = ref<boolean>(false);
@ -202,7 +209,7 @@ export default defineComponent({
relatedTrace: {
traceId: traceId.value || traceStore.currentTrace.traceIds[0].value,
},
paging: { pageNum: pageNum.value, pageSize, needTotal: true },
paging: { pageNum: pageNum.value, pageSize },
},
});
if (res.errors) {
@ -227,6 +234,7 @@ export default defineComponent({
pageSize,
pageNum,
loading,
total,
};
},
});

View File

@ -72,9 +72,19 @@ limitations under the License. -->
</div>
<div class="mr-10">
<span class="sm b grey mr-5">{{ t("duration") }}:</span>
<el-input size="small" class="inputs mr-5" v-model="minTraceDuration" />
<el-input
size="small"
class="inputs mr-5"
v-model="minTraceDuration"
type="number"
/>
<span class="grey mr-5">-</span>
<el-input size="small" class="inputs" v-model="maxTraceDuration" />
<el-input
size="small"
class="inputs"
v-model="maxTraceDuration"
type="number"
/>
</div>
</div>
<div class="flex-h">
@ -100,8 +110,8 @@ const selectorStore = useSelectorStore();
const dashboardStore = useDashboardStore();
const traceStore = useTraceStore();
const traceId = ref<string>("");
const minTraceDuration = ref<string>("");
const maxTraceDuration = ref<string>("");
const minTraceDuration = ref<number>();
const maxTraceDuration = ref<number>();
const tagsList = ref<string[]>([]);
const tagsMap = ref<Option[]>([]);
const state = reactive<any>({
@ -174,11 +184,11 @@ function searchTraces() {
serviceInstanceId: instance || state.instance.id || undefined,
traceState: state.status.value || "ALL",
queryDuration: appStore.durationTime,
minTraceDuration: appStore.minTraceDuration || undefined,
maxTraceDuration: appStore.maxTraceDuration || undefined,
minTraceDuration: Number(minTraceDuration.value),
maxTraceDuration: Number(maxTraceDuration.value),
queryOrder: "BY_DURATION",
tags: tagsMap.value.length ? tagsMap.value : undefined,
paging: { pageNum: 1, pageSize: 15, needTotal: true },
paging: { pageNum: 1, pageSize: 20 },
});
queryTraces();
}

View File

@ -17,9 +17,9 @@ limitations under the License. -->
v-model:currentPage="traceStore.conditions.paging.pageNum"
v-model:page-size="pageSize"
:small="true"
layout="prev, pager, next, jumper"
:total="traceStore.traceTotal"
v-model:pager-count="pageCount"
layout="prev, pager, next"
:pager-count="5"
:total="total"
@current-change="updatePage"
/>
<div class="selectors">
@ -71,7 +71,7 @@ limitations under the License. -->
<script lang="ts" setup>
import dayjs from "dayjs";
import { ref } from "vue";
import { ref, computed } from "vue";
import { useI18n } from "vue-i18n";
import { useTraceStore } from "@/store/modules/trace";
import { ElMessage } from "element-plus";
@ -83,8 +83,12 @@ const { t } = useI18n();
const traceStore = useTraceStore();
const loading = ref<boolean>(false);
const selectedKey = ref<string>("");
const pageSize = ref<number>(15);
const pageCount = ref<number>(5);
const pageSize = ref<number>(20);
const total = computed(() =>
traceStore.traceList.length === pageSize.value
? pageSize.value * traceStore.conditions.paging.pageNum + 1
: pageSize.value * traceStore.conditions.paging.pageNum
);
const dateFormat = (date: number, pattern = "YYYY-MM-DD HH:mm:ss") =>
dayjs(date).format(pattern);
@ -96,7 +100,7 @@ function searchTrace() {
function updatePage(p: number) {
traceStore.setTraceCondition({
paging: { pageNum: p, pageSize: pageSize.value, needTotal: true },
paging: { pageNum: p, pageSize: pageSize.value },
});
searchTrace();
}
@ -104,7 +108,7 @@ function updatePage(p: number) {
function changeSort(opt: Option[] | any) {
traceStore.setTraceCondition({
queryOrder: opt[0].value,
paging: { pageNum: 1, pageSize: pageSize.value, needTotal: true },
paging: { pageNum: 1, pageSize: pageSize.value },
});
searchTrace();
}
@ -167,7 +171,7 @@ async function queryTraces() {
}
.list {
width: 400px;
width: 300px;
}
.trace-tr {

View File

@ -91,7 +91,9 @@ limitations under the License. -->
v-model:currentPage="pageNum"
v-model:page-size="pageSize"
:small="true"
:total="traceStore.traceSpanLogsTotal"
layout="prev, pager, next"
:pager-count="5"
:total="total"
@current-change="turnPage"
/>
<LogTable
@ -106,7 +108,7 @@ limitations under the License. -->
</el-dialog>
</template>
<script lang="ts" setup>
import { ref } from "vue";
import { ref, computed } from "vue";
import { useI18n } from "vue-i18n";
import type { PropType } from "vue";
import dayjs from "dayjs";
@ -124,6 +126,11 @@ const traceStore = useTraceStore();
const pageNum = ref<number>(1);
const showRelatedLogs = ref<boolean>(false);
const pageSize = 10;
const total = computed(() =>
traceStore.traceList.length === pageSize
? pageSize * pageNum.value + 1
: pageSize * pageNum.value
);
const dateFormat = (date: number, pattern = "YYYY-MM-DD HH:mm:ss") =>
dayjs(date).format(pattern);
async function getTaceLogs() {
@ -135,7 +142,7 @@ async function getTaceLogs() {
segmentId: props.currentSpan.segmentId,
spanId: props.currentSpan.spanId,
},
paging: { pageNum: pageNum.value, pageSize, needTotal: true },
paging: { pageNum: pageNum.value, pageSize },
},
});
if (res.errors) {

View File

@ -75,8 +75,8 @@ limitations under the License. -->
<el-pagination
v-model:currentPage="pageNum"
v-model:page-size="pageSize"
layout="prev, jumper, total, next"
:total="eventStore.total"
layout="prev, pager, next"
:total="total"
@current-change="updatePage"
:pager-count="5"
small
@ -92,7 +92,7 @@ limitations under the License. -->
</nav>
</template>
<script lang="ts" setup>
import { ref, reactive } from "vue";
import { ref, reactive, computed } from "vue";
import { useI18n } from "vue-i18n";
import { EventTypes } from "./data";
import { useEventStore } from "@/store/modules/event";
@ -119,6 +119,11 @@ const state = reactive<{
instance: "",
endpoint: "",
});
const total = computed(() =>
eventStore.events.length === pageSize
? pageSize * pageNum.value + 1
: pageSize * pageNum.value
);
getSelectors();
@ -180,7 +185,6 @@ async function queryEvents() {
paging: {
pageNum: pageNum.value,
pageSize: pageSize,
needTotal: true,
},
source: {
service: state.service || "",