Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 42 additions & 9 deletions dashboard-ui/src/lib/console/logfeed.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,13 @@ interface PauseCommand extends BaseCommand {
type: 'pause';
}

type Command = HeadCommand | TailCommand | SeekCommand | PlayCommand | PauseCommand;

interface GrepCommand extends BaseCommand {
type: 'grep';
filter: string;
}

type Command = HeadCommand | TailCommand | SeekCommand | PlayCommand | PauseCommand | GrepCommand;

/**
* State
Expand Down Expand Up @@ -203,6 +209,9 @@ export const useLogFeedControls = () => {
pause: () => {
postMessage({ type: 'pause' });
},
grep: (filter: string) => {
postMessage({ type: 'grep', filter });
}
};
};

Expand Down Expand Up @@ -502,7 +511,7 @@ type LogFeedContentProps = {
const LogFeedContentImpl: React.ForwardRefRenderFunction<LogFeedContentHandle, LogFeedContentProps> = (
props: LogFeedContentProps,
ref: React.ForwardedRef<LogFeedContentHandle>,
) => {
) => {
const { hasMoreBefore, hasMoreAfter, loadMoreBefore, loadMoreAfter } = props;
let { items } = props;

Expand Down Expand Up @@ -836,7 +845,7 @@ type LogFeedRecordFetcherHandle = {
const LogFeedRecordFetcherImpl: React.ForwardRefRenderFunction<LogFeedRecordFetcherHandle, LogFeedRecordFetcherProps> = (
props: LogFeedRecordFetcherProps,
ref: React.ForwardedRef<LogFeedRecordFetcherHandle>,
) => {
) => {
const kubeContext = useKubeContext();

const { node, pod, container, defaultFollowAfter, onFollowData } = props;
Expand Down Expand Up @@ -1234,10 +1243,25 @@ export const LogFeedViewer = ({
const afterBufferRef = useRef(new Array<LogRecord>());
const cursorMapRef = useRef(new Map<string, PageInfo>());
const isSendFollowToBufferRef = useRef(true);
const grepFilterRef = useRef("")

const batchSize = 300;

const filterLogRecords = (records: LogRecord[]) => {
if (grepFilterRef.current === "") return records;
records = records.filter((record) => record.message.match(grepFilterRef.current))
records.forEach((record) => {
record.message = record.message.replace(grepFilterRef.current, `\u001b[31;43m${grepFilterRef.current}\u001b[0m`)
})
return records
}

const handleOnFollowData = (record: LogRecord) => {
var records = filterLogRecords([record]);
if (records.length === 0) {
return
}
record = records[0]
if (isSendFollowToBufferRef.current) {
afterBufferRef.current.push(record);
} else {
Expand Down Expand Up @@ -1265,8 +1289,9 @@ export const LogFeedViewer = ({

// update content
const newRecords = beforeBufferRef.current.splice(-1 * batchSize);
const filterdRecords = filterLogRecords(newRecords)

setLogRecords((oldRecords) => [...newRecords, ...oldRecords]);
setLogRecords((oldRecords) => [...filterdRecords, ...oldRecords]);
setHasMoreBefore(beforeBufferRef.current.length > 0 || hasPreviousPageSome(cursorMap));
};

Expand All @@ -1289,7 +1314,8 @@ export const LogFeedViewer = ({

// update content
const newRecords = afterBufferRef.current.splice(0, batchSize);
setLogRecords((oldRecords) => [...oldRecords, ...newRecords]);
const filterdRecords = filterLogRecords(newRecords)
setLogRecords((oldRecords) => [...oldRecords, ...filterdRecords]);

const newHasMoreAfter = afterBufferRef.current.length > 0 || hasNextPageSome(cursorMap);
if (!newHasMoreAfter) isSendFollowToBufferRef.current = false;
Expand Down Expand Up @@ -1328,7 +1354,8 @@ export const LogFeedViewer = ({
[afterBufferRef.current, cursorMapRef.current] = await client.head({ since: 'beginning', first: batchSize });

// update content
setLogRecords(afterBufferRef.current.splice(0, batchSize));
var filterdRecords = filterLogRecords(afterBufferRef.current.splice(0, batchSize))
setLogRecords(filterdRecords);

newHasMoreAfter = afterBufferRef.current.length > 0 || hasNextPageSome(cursorMapRef.current);
if (!newHasMoreAfter) isSendFollowToBufferRef.current = false;
Expand All @@ -1351,7 +1378,8 @@ export const LogFeedViewer = ({
[beforeBufferRef.current, cursorMapRef.current] = await client.tail({ last: batchSize });

// update content
setLogRecords(beforeBufferRef.current.splice(-1 * batchSize));
var filterdRecords = filterLogRecords(beforeBufferRef.current.splice(-1 * batchSize))
setLogRecords(filterdRecords);
setHasMoreBefore(beforeBufferRef.current.length > 0 || hasPreviousPageSome(cursorMapRef.current));

contentRef.current?.scrollTo('last');
Expand All @@ -1369,9 +1397,9 @@ export const LogFeedViewer = ({

// execute query and reset state
[afterBufferRef.current, cursorMapRef.current] = await client.head({ since: ev.data.sinceTS, first: batchSize });

// update content
setLogRecords(afterBufferRef.current.splice(0, batchSize));
var filterdRecords = filterLogRecords(afterBufferRef.current.splice(0, batchSize))
setLogRecords(filterdRecords);

newHasMoreAfter = afterBufferRef.current.length > 0 || hasNextPageSome(cursorMapRef.current);
if (!newHasMoreAfter) isSendFollowToBufferRef.current = false;
Expand Down Expand Up @@ -1405,6 +1433,11 @@ export const LogFeedViewer = ({
case 'pause':
setIsFollow(false);
break;

case 'grep':
grepFilterRef.current = ev.data.filter;
break;

default:
throw new Error('not implemented');
}
Expand Down
24 changes: 24 additions & 0 deletions dashboard-ui/src/pages/console.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,7 @@ const Header = () => {
const feed = useLogFeedMetadata();

const buttonCN = 'rounded-lg h-[40px] w-[40px] flex items-center justify-center enabled:hover:bg-chrome-200 disabled:opacity-30';
const inputCN = 'rounded-lg h-[40px] w-[200px] flex items-center justify-center enabled:hover:bg-chrome-200 disabled:opacity-30';

const handleDateRangeDropdownChange = (args: DateRangeDropdownOnChangeArgs) => {
if (args.since) {
Expand All @@ -407,6 +408,21 @@ const Header = () => {
controls.tail();
};

const handleFilterInputChange = (ev: any) => {
controls.grep(ev.currentTarget.value);
const mode = searchParams.get('mode')
if (mode === 'seek') {
const since = searchParams.get('since');
if (since) {
controls.seek(since);
}
} else if (mode === 'head') {
controls.head();
} else {
controls.tail();
}
};

return (
<div className="flex justify-between items-end p-1">
<div className="flex px-2">
Expand Down Expand Up @@ -459,6 +475,14 @@ const Header = () => {
>
<SkipForwardIcon size={24} strokeWidth={1.5} className="text-chrome-foreground" />
</button>
<input
type="text"
className={inputCN}
aria-label="Filter keyword"
placeholder='Filter keyword'
onInput ={handleFilterInputChange}
>
</input>
</div>
<div className="h-full flex flex-col justify-end items-end">
<SettingsButton />
Expand Down