fix: logs issues (#1889)

* changed debounce interval to 600ms

Co-authored-by: Pranay Prateek <pranay@signoz.io>
Co-authored-by: Ankit Nayan <ankit@signoz.io>
This commit is contained in:
Palash Gupta 2022-12-26 16:45:28 +05:30 committed by GitHub
parent ac446294e7
commit d1d2829d2b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 47 additions and 67 deletions

View File

@ -5,19 +5,14 @@ import {
} from '@ant-design/icons'; } from '@ant-design/icons';
import { Button, Divider, Select } from 'antd'; import { Button, Divider, Select } from 'antd';
import React, { memo } from 'react'; import React, { memo } from 'react';
import { connect, useDispatch, useSelector } from 'react-redux'; import { useDispatch, useSelector } from 'react-redux';
import { bindActionCreators, Dispatch } from 'redux';
import { ThunkDispatch } from 'redux-thunk';
import { getLogs } from 'store/actions/logs/getLogs';
import { AppState } from 'store/reducers'; import { AppState } from 'store/reducers';
import AppActions from 'types/actions';
import { import {
GET_NEXT_LOG_LINES, GET_NEXT_LOG_LINES,
GET_PREVIOUS_LOG_LINES, GET_PREVIOUS_LOG_LINES,
RESET_ID_START_AND_END, RESET_ID_START_AND_END,
SET_LOG_LINES_PER_PAGE, SET_LOG_LINES_PER_PAGE,
} from 'types/actions/logs'; } from 'types/actions/logs';
import { GlobalReducer } from 'types/reducer/globalTime';
import { ILogsReducer } from 'types/reducer/logs'; import { ILogsReducer } from 'types/reducer/logs';
import { Container } from './styles'; import { Container } from './styles';
@ -26,20 +21,10 @@ const { Option } = Select;
const ITEMS_PER_PAGE_OPTIONS = [25, 50, 100, 200]; const ITEMS_PER_PAGE_OPTIONS = [25, 50, 100, 200];
interface LogControlsProps { function LogControls(): JSX.Element | null {
getLogs: (props: Parameters<typeof getLogs>[0]) => ReturnType<typeof getLogs>; const { logLinesPerPage, liveTail } = useSelector<AppState, ILogsReducer>(
} (state) => state.logs,
function LogControls({ getLogs }: LogControlsProps): JSX.Element | null {
const { maxTime, minTime } = useSelector<AppState, GlobalReducer>(
(state) => state.globalTime,
); );
const {
logLinesPerPage,
idStart,
idEnd,
liveTail,
searchFilter: { queryString },
} = useSelector<AppState, ILogsReducer>((state) => state.logs);
const dispatch = useDispatch(); const dispatch = useDispatch();
const handleLogLinesPerPageChange = (e: number): void => { const handleLogLinesPerPageChange = (e: number): void => {
@ -53,18 +38,6 @@ function LogControls({ getLogs }: LogControlsProps): JSX.Element | null {
dispatch({ dispatch({
type: RESET_ID_START_AND_END, type: RESET_ID_START_AND_END,
}); });
if (liveTail === 'STOPPED')
getLogs({
q: queryString,
limit: logLinesPerPage,
orderBy: 'timestamp',
order: 'desc',
timestampStart: minTime,
timestampEnd: maxTime,
...(idStart ? { idGt: idStart } : {}),
...(idEnd ? { idLt: idEnd } : {}),
});
}; };
const handleNavigatePrevious = (): void => { const handleNavigatePrevious = (): void => {
@ -106,16 +79,4 @@ function LogControls({ getLogs }: LogControlsProps): JSX.Element | null {
); );
} }
interface DispatchProps { export default memo(LogControls);
getLogs: (
props: Parameters<typeof getLogs>[0],
) => (dispatch: Dispatch<AppActions>) => void;
}
const mapDispatchToProps = (
dispatch: ThunkDispatch<unknown, unknown, AppActions>,
): DispatchProps => ({
getLogs: bindActionCreators(getLogs, dispatch),
});
export default connect(null, mapDispatchToProps)(memo(LogControls));

View File

@ -1,7 +1,14 @@
import { Input, InputRef, Popover } from 'antd'; import { Input, InputRef, Popover } from 'antd';
import useUrlQuery from 'hooks/useUrlQuery'; import useUrlQuery from 'hooks/useUrlQuery';
import getStep from 'lib/getStep'; import getStep from 'lib/getStep';
import React, { useCallback, useEffect, useRef, useState } from 'react'; import { debounce } from 'lodash-es';
import React, {
useCallback,
useEffect,
useMemo,
useRef,
useState,
} from 'react';
import { connect, useDispatch, useSelector } from 'react-redux'; import { connect, useDispatch, useSelector } from 'react-redux';
import { bindActionCreators, Dispatch } from 'redux'; import { bindActionCreators, Dispatch } from 'redux';
import { ThunkDispatch } from 'redux-thunk'; import { ThunkDispatch } from 'redux-thunk';
@ -22,12 +29,31 @@ function SearchFilter({
getLogsAggregate, getLogsAggregate,
}: SearchFilterProps): JSX.Element { }: SearchFilterProps): JSX.Element {
const { const {
queryString,
updateParsedQuery, updateParsedQuery,
updateQueryString, updateQueryString,
queryString,
} = useSearchParser(); } = useSearchParser();
const [searchText, setSearchText] = useState(queryString);
const [showDropDown, setShowDropDown] = useState(false); const [showDropDown, setShowDropDown] = useState(false);
const searchRef = useRef<InputRef>(null); const searchRef = useRef<InputRef>(null);
const { logLinesPerPage, idEnd, idStart, liveTail } = useSelector<
AppState,
ILogsReducer
>((state) => state.logs);
const { maxTime, minTime } = useSelector<AppState, GlobalReducer>(
(state) => state.globalTime,
);
const dispatch = useDispatch<Dispatch<AppActions>>();
// keep sync with url queryString
useEffect(() => {
setSearchText(queryString);
}, [queryString]);
const debouncedupdateQueryString = useMemo(
() => debounce(updateQueryString, 300),
[updateQueryString],
);
const onDropDownToggleHandler = useCallback( const onDropDownToggleHandler = useCallback(
(value: boolean) => (): void => { (value: boolean) => (): void => {
@ -36,17 +62,6 @@ function SearchFilter({
[], [],
); );
const { logLinesPerPage, idEnd, idStart, liveTail } = useSelector<
AppState,
ILogsReducer
>((state) => state.logs);
const { maxTime, minTime } = useSelector<AppState, GlobalReducer>(
(state) => state.globalTime,
);
const dispatch = useDispatch<Dispatch<AppActions>>();
const handleSearch = useCallback( const handleSearch = useCallback(
(customQuery) => { (customQuery) => {
if (liveTail === 'PLAYING') { if (liveTail === 'PLAYING') {
@ -102,10 +117,14 @@ function SearchFilter({
const urlQuery = useUrlQuery(); const urlQuery = useUrlQuery();
const urlQueryString = urlQuery.get('q'); const urlQueryString = urlQuery.get('q');
const debouncedHandleSearch = useMemo(() => debounce(handleSearch, 600), [
handleSearch,
]);
useEffect(() => { useEffect(() => {
handleSearch(urlQueryString || ''); debouncedHandleSearch(urlQueryString || '');
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
}, [urlQueryString, maxTime, minTime]); }, [urlQueryString, maxTime, minTime, idEnd, idStart]);
return ( return (
<Container> <Container>
@ -132,9 +151,11 @@ function SearchFilter({
<Input.Search <Input.Search
ref={searchRef} ref={searchRef}
placeholder="Search Filter" placeholder="Search Filter"
value={queryString} value={searchText}
onChange={(e): void => { onChange={(e): void => {
updateQueryString(e.target.value); const { value } = e.target;
setSearchText(value);
debouncedupdateQueryString(value);
}} }}
allowClear allowClear
onSearch={handleSearch} onSearch={handleSearch}

View File

@ -23,12 +23,10 @@ export function useSearchParser(): {
const updateQueryString = useCallback( const updateQueryString = useCallback(
(updatedQueryString) => { (updatedQueryString) => {
if (updatedQueryString) { history.replace({
history.push({ pathname: history.location.pathname,
pathname: history.location.pathname, search: updatedQueryString ? `?q=${updatedQueryString}` : '',
search: updatedQueryString ? `?q=${updatedQueryString}` : '', });
});
}
dispatch({ dispatch({
type: SET_SEARCH_QUERY_STRING, type: SET_SEARCH_QUERY_STRING,