diff --git a/esp/src/src-react/components/Logs.tsx b/esp/src/src-react/components/Logs.tsx index 86f7297abc1..0ec5a9b4699 100644 --- a/esp/src/src-react/components/Logs.tsx +++ b/esp/src/src-react/components/Logs.tsx @@ -1,18 +1,20 @@ import * as React from "react"; import { CommandBar, ContextualMenuItemType, ICommandBarItemProps } from "@fluentui/react"; -import { useConst } from "@fluentui/react-hooks"; -import { GetLogsExRequest, TargetAudience, LogType } from "@hpcc-js/comms"; -import { Level } from "@hpcc-js/util"; -import { CreateLogsQueryStore } from "src/ESPLog"; +import { GetLogsExRequest, LogaccessService, TargetAudience, LogType } from "@hpcc-js/comms"; +import { Level, scopedLogger } from "@hpcc-js/util"; import nlsHPCC from "src/nlsHPCC"; import { logColor, wuidToDate, wuidToTime } from "src/Utility"; import { HolyGrail } from "../layouts/HolyGrail"; import { pushParams } from "../util/history"; -import { FluentPagedGrid, FluentPagedFooter, useCopyButtons, useFluentStoreState, FluentColumns } from "./controls/Grid"; +import { FluentGrid, useCopyButtons, useFluentStoreState, FluentColumns } from "./controls/Grid"; import { Filter } from "./forms/Filter"; import { Fields } from "./forms/Fields"; import { ShortVerticalDivider } from "./Common"; +export const service = new LogaccessService({ baseUrl: "" }); + +const logger = scopedLogger("src-react/components/Logs.tsx"); + const eightHours = 8 * 60 * 60 * 1000; const startTimeOffset = 1 * 60 * 60 * 1000; const endTimeOffset = 23 * 60 * 60 * 1000; @@ -43,6 +45,14 @@ const FilterFields: Fields = { processid: { type: "string", label: nlsHPCC.ProcessID }, threadid: { type: "string", label: nlsHPCC.ThreadID }, message: { type: "string", label: nlsHPCC.Message }, + LogLineLimit: { + type: "dropdown", label: nlsHPCC.LogLineLimit, options: [ + { key: 100, text: "100" }, + { key: 250, text: "250" }, + { key: 500, text: "500" }, + { key: 1000, text: "1000" }, + ] + }, StartDate: { type: "datetime", label: nlsHPCC.FromDate }, EndDate: { type: "datetime", label: nlsHPCC.ToDate }, }; @@ -92,17 +102,38 @@ export const Logs: React.FunctionComponent = ({ const hasFilter = React.useMemo(() => Object.keys(filter).length > 0, [filter]); const [showFilter, setShowFilter] = React.useState(false); + const [data, setData] = React.useState([]); const { selection, setSelection, - pageNum, setPageNum, - pageSize, setPageSize, - total, setTotal, + setTotal, refreshTable } = useFluentStoreState({ page }); const now = React.useMemo(() => new Date(), []); // Grid --- - const gridStore = useConst(() => CreateLogsQueryStore()); + const columns = React.useMemo((): FluentColumns => { + return { + timestamp: { label: nlsHPCC.TimeStamp, width: 140, sortable: false, }, + message: { label: nlsHPCC.Message, width: 600, sortable: false, }, + components: { label: nlsHPCC.ContainerName, width: 150, sortable: false }, + instance: { label: nlsHPCC.PodName, width: 150, sortable: false }, + audience: { label: nlsHPCC.Audience, width: 60, sortable: false, }, + class: { + label: nlsHPCC.Class, width: 40, sortable: false, + formatter: level => { + const colors = logColor(levelMap(level)); + const styles = { backgroundColor: colors.background, padding: "2px 6px", color: colors.foreground }; + return {level}; + } + }, + workunits: { label: nlsHPCC.JobID, width: 50, sortable: false, hidden: wuid !== undefined, }, + processid: { label: nlsHPCC.ProcessID, width: 75, sortable: false, }, + logid: { label: nlsHPCC.Sequence, width: 70, sortable: false, }, + threadid: { label: nlsHPCC.ThreadID, width: 60, sortable: false, }, + }; + }, [wuid]); + + const copyButtons = useCopyButtons(columns, selection, "logaccess"); const query = React.useMemo(() => { if (wuid !== undefined) { @@ -120,6 +151,9 @@ export const Logs: React.FunctionComponent = ({ //assign a reasonable default start date if one isn't set filter.StartDate = new Date(now.getTime() - eightHours); } + if (typeof filter.EndDate === "string") { + filter.EndDate = new Date(filter.EndDate + ":00Z"); + } if (!filter.EndDate) { filter.EndDate = new Date(now.getTime() + endTimeOffset); } @@ -127,35 +161,17 @@ export const Logs: React.FunctionComponent = ({ return formatQuery(filter); }, [filter, now, wuid]); - const columns = React.useMemo((): FluentColumns => { - return { - timestamp: { label: nlsHPCC.TimeStamp, width: 140, sortable: false, }, - message: { label: nlsHPCC.Message, sortable: false, }, - components: { label: nlsHPCC.ContainerName, width: 150, sortable: false }, - instance: { label: nlsHPCC.PodName, width: 150, sortable: false }, - audience: { label: nlsHPCC.Audience, width: 60, sortable: false, }, - class: { - label: nlsHPCC.Class, width: 40, sortable: false, - formatter: level => { - const colors = logColor(levelMap(level)); - const styles = { backgroundColor: colors.background, padding: "2px 6px", color: colors.foreground }; - return {level}; - } - }, - workunits: { label: nlsHPCC.JobID, width: 50, sortable: false, hidden: wuid !== undefined, }, - processid: { label: nlsHPCC.ProcessID, width: 75, sortable: false, }, - logid: { label: nlsHPCC.Sequence, width: 70, sortable: false, }, - threadid: { label: nlsHPCC.ThreadID, width: 60, sortable: false, }, - }; - }, [wuid]); - - const copyButtons = useCopyButtons(columns, selection, "logaccess"); + const refreshData = React.useCallback(() => { + service.GetLogsEx(query as any).then(response => { + setData(response.lines); + }).catch(err => logger.error(err)); + }, [query]); // Command Bar --- const buttons = React.useMemo((): ICommandBarItemProps[] => [ { key: "refresh", text: nlsHPCC.Refresh, iconProps: { iconName: "Refresh" }, - onClick: () => refreshTable.call() + onClick: () => refreshData() }, { key: "divider_1", itemType: ContextualMenuItemType.Divider, onRender: () => }, { @@ -164,7 +180,11 @@ export const Logs: React.FunctionComponent = ({ setShowFilter(true); } }, - ], [hasFilter, refreshTable]); + ], [hasFilter, refreshData]); + + React.useEffect(() => { + refreshData(); + }, [refreshData]); // Filter --- const filterFields: Fields = React.useMemo(() => { @@ -183,12 +203,9 @@ export const Logs: React.FunctionComponent = ({ header={} main={
- { @@ -198,18 +215,9 @@ export const Logs: React.FunctionComponent = ({ } }} refresh={refreshTable} - > + >
} - footer={} - footerStyles={{}} />; }; \ No newline at end of file diff --git a/system/jlib/jdebug.cpp b/system/jlib/jdebug.cpp index 79c9c36bbb7..4dcc7a141cf 100644 --- a/system/jlib/jdebug.cpp +++ b/system/jlib/jdebug.cpp @@ -1541,8 +1541,8 @@ void getMemStats(StringBuffer &out, unsigned &memused, unsigned &memtot) muval = 100; // ! - out.appendf("MU=%3u%% MAL=%" I64F "d MMP=%" I64F "d SBK=%" I64F "d TOT=%uK RAM=%uK SWP=%uK", - muval, total, mmapmem, sbrkmem, (unsigned)(virttot/1024), mu, su); + out.appendf("MU=%3u%% MAL=%" I64F "d MMP=%" I64F "d SBK=%" I64F "d TOT=%uK RAM=%uK SWP=%uK FLT=%" I64F "u CTX=%" I64F "u", + muval, total, mmapmem, sbrkmem, (unsigned)(virttot/1024), mu, su, processInfo.getMajorFaults(), processInfo.getNumContextSwitches()); #ifdef _USE_MALLOC_HOOK if (totalMem) out.appendf(" TM=%" I64F "d",totalMem);