Skip to content

Commit

Permalink
[##11962] Handle not OK data & ThreadDump open button
Browse files Browse the repository at this point in the history
  • Loading branch information
jihea-park committed Jan 31, 2025
1 parent 6509131 commit 73e5947
Show file tree
Hide file tree
Showing 7 changed files with 287 additions and 73 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,33 +23,36 @@ import { AgentActiveData } from './AgentActiveTable';
export const DefaultValue = { yMax: 100 };

export interface AgentActiveChartProps {
loading?: boolean;
data?: AgentActiveData[];
setting?: AgentActiveSettingType;
clickedActiveThread?: string;
setClickedActiveThread?: React.Dispatch<React.SetStateAction<string>>;
}

const TICK_COUNT = 4;
const DefaultReferenceLineLength = 50;
const chartConfig = {
slow: {
label: 'slow',
color: '#e67f22',
},
'5s': {
label: '5s',
color: '#ffba00',
'1s': {
label: '1s',
color: '#34b994',
},
'3s': {
label: '3s',
color: '#51afdf',
},
'1s': {
label: '1s',
color: '#34b994',
'5s': {
label: '5s',
color: '#ffba00',
},
slow: {
label: 'slow',
color: '#e67f22',
},
} satisfies ChartConfig;

export const AgentActiveChart = ({
loading,
data,
setting,
clickedActiveThread,
Expand Down Expand Up @@ -91,28 +94,41 @@ export const AgentActiveChart = ({
tickLine={false}
axisLine={false}
tickMargin={10}
ticks={Array.from({ length: TICK_COUNT + 1 }, (_, index) =>
Math.ceil((yMax / TICK_COUNT) * index),
)}
allowDecimals={false}
domain={() => [0, yMax]}
/>
<ChartTooltip content={<ChartTooltipContent />} />
<ChartLegend content={<ChartLegendContent />} />
{Object.keys(chartConfig).map((key) => (
<Bar
key={key}
dataKey={key}
stackId="agentActiveThread"
fill={chartConfig[key as keyof typeof chartConfig].color}
>
{data?.map((entry, index) => (
<Cell
key={`cell-${index}`}
opacity={
clickedActiveThread ? (entry.server === clickedActiveThread ? 1 : 0.3) : 1
}
/>
))}
</Bar>
))}
<ChartTooltip
content={
<ChartTooltipContent
isReverse={true}
valueFormatter={(value) => ((value as number) < 0 ? '-' : value)}
/>
}
/>
<ChartLegend content={<ChartLegendContent isReverse={true} />} />
{Object.keys(chartConfig)
.reverse()
.map((key) => (
<Bar
key={key}
dataKey={key}
stackId="agentActiveThread"
fill={chartConfig[key as keyof typeof chartConfig].color}
hide={loading}
>
{data?.map((entry, index) => (
<Cell
key={`cell-${index}`}
opacity={
clickedActiveThread ? (entry.server === clickedActiveThread ? 1 : 0.3) : 1
}
/>
))}
</Bar>
))}
{Array.from({ length: ReferenceLineLength }, (_, index) => {
return (
<ReferenceLine
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,12 @@ export interface AgentActiveSettingProps {
defaultValues?: AgentActiveSettingType;
}

export const DefaultValue = { yMax: 100, isSplit: true };
export const DefaultValue = { yMax: 100, isSplit: true, inactivityThreshold: 5 };

const FormSchema = z.object({
yMax: z.coerce.number(),
yMax: z.coerce.number().min(1),
isSplit: z.boolean(),
inactivityThreshold: z.coerce.number().min(0), // minutes
});

export type AgentActiveSettingType = z.infer<typeof FormSchema>;
Expand All @@ -51,6 +52,7 @@ export const AgentActiveSetting = ({
defaultValues: {
yMax: defaultValues?.yMax,
isSplit: defaultValues?.isSplit,
inactivityThreshold: defaultValues?.inactivityThreshold,
},
});

Expand All @@ -77,15 +79,21 @@ export const AgentActiveSetting = ({
>
<div className="mb-3 font-semibold">Agent request chart Setting</div>
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="w-2/3 space-y-6">
<form onSubmit={form.handleSubmit(onSubmit)} className="w-full space-y-6">
<FormField
control={form.control}
name="yMax"
render={({ field }) => (
<FormItem>
<FormLabel className="text-xs text-muted-foreground">Max of Y axis</FormLabel>
<FormControl>
<Input type="number" className="w-24 h-7" onKeyDown={handleKeyDown} {...field} />
<Input
type="number"
className="w-24 h-7"
onKeyDown={handleKeyDown}
min={1}
{...field}
/>
</FormControl>
<FormMessage />
</FormItem>
Expand All @@ -111,6 +119,27 @@ export const AgentActiveSetting = ({
</FormItem>
)}
/>
<FormField
control={form.control}
name="inactivityThreshold"
render={({ field }) => (
<FormItem>
<FormLabel className="text-xs text-muted-foreground">
Inactivity Threshold (m)
</FormLabel>
<FormControl>
<Input
type="number"
className="w-24 h-7"
onKeyDown={handleKeyDown}
min={0}
{...field}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<div className="flex justify-end gap-1 mt-6">
<Button className="text-xs h-7" variant="outline" onClick={handleClickClose}>
Cancel
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,35 @@ import { VirtualizedDataTable } from '../DataTable';
import { ColumnDef } from '@tanstack/react-table';
import { cn } from '@pinpoint-fe/ui/lib';
import React from 'react';
import { TooltipContent, TooltipProvider, Tooltip, TooltipTrigger, Button } from '../ui';
import * as TooltipPrimitive from '@radix-ui/react-tooltip';
import { HiMiniExclamationCircle } from 'react-icons/hi2';
import { BASE_PATH, colors } from '@pinpoint-fe/ui/constants';
import { RxExternalLink } from 'react-icons/rx';
import { getThreadDumpPath } from '@pinpoint-fe/ui/utils';
import { useSearchParameters } from '@pinpoint-fe/ui/hooks';

export type AgentActiveData = {
server: string;
'1s': number;
'3s': number;
'5s': number;
slow: number;
message?: string;
};

const SIZE = 50;

export const AgentActiveTable = ({
loading,
data,
clickedActiveThread,
}: {
loading?: boolean;
data: AgentActiveData[];
clickedActiveThread?: string;
}) => {
const { application } = useSearchParameters();
const focusRowId = React.useMemo(() => {
return data.findIndex((d) => d.server === clickedActiveThread);
}, [data, clickedActiveThread]);
Expand All @@ -28,7 +39,42 @@ export const AgentActiveTable = ({
{
accessorKey: 'server',
header: 'Server',
size: 200,
size: 230,
cell: ({ getValue, row }) => {
const value = getValue<string>() || '';
const message = row?.original?.message || '';

return (
<div className="flex items-center gap-1">
<span>{value}</span>
<Button
className="text-muted-foreground p-0 w-4 h-4 mr-1.5"
variant="ghost"
onClick={() => {
window.open(`${BASE_PATH}${getThreadDumpPath(application)}?agentId=${value}`);
}}
>
<RxExternalLink />
</Button>
{true && (
<TooltipProvider delayDuration={0}>
<Tooltip>
<TooltipTrigger asChild>
<div>
<HiMiniExclamationCircle color={colors.red[500]} size={16} />
</div>
</TooltipTrigger>
<TooltipPrimitive.Portal>
<TooltipContent>
<p>{message}</p>
</TooltipContent>
</TooltipPrimitive.Portal>
</Tooltip>
</TooltipProvider>
)}
</div>
);
},
},
{
accessorKey: 'slow',
Expand All @@ -40,6 +86,11 @@ export const AgentActiveTable = ({
},
cell: ({ getValue }) => {
const value = getValue<number>() || 0;

if (value === -1) {
return '-';
}

return (
<span
className={cn({
Expand All @@ -61,6 +112,9 @@ export const AgentActiveTable = ({
},
cell: ({ getValue }) => {
const value = getValue<number>() || 0;
if (value === -1) {
return '-';
}
return (
<span
className={cn({
Expand All @@ -80,6 +134,13 @@ export const AgentActiveTable = ({
headerClassName: 'flex justify-end',
cellClassName: 'text-right',
},
cell: ({ getValue }) => {
const value = getValue<number>() || 0;
if (value === -1) {
return '-';
}
return value;
},
},
{
accessorKey: '1s',
Expand All @@ -89,15 +150,23 @@ export const AgentActiveTable = ({
headerClassName: 'flex justify-end',
cellClassName: 'text-right',
},
cell: ({ getValue }) => {
const value = getValue<number>() || 0;
if (value === -1) {
return '-';
}
return value;
},
},
];

return (
<div className="block h-[-webkit-fill-available] max-w-[50%] w-auto">
<VirtualizedDataTable
loading={loading}
tableClassName="[&>tbody]:text-xs w-auto"
columns={columns}
data={data || []}
data={loading ? [] : data || []}
focusRowIndex={focusRowId}
rowClassName={(row) => {
if (row?.id === String(focusRowId)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ export const AgentActiveThreadFetcher = () => {
</div>
<div className="flex flex-grow w-full h-[-webkit-fill-available] overflow-hidden">
<AgentActiveThreadView
applicationName={applicationName}
activeThreadCounts={activeThreadCounts?.result}
setting={setting}
/>
Expand Down
Loading

0 comments on commit 73e5947

Please sign in to comment.