Skip to content

Commit c094ee1

Browse files
authored
Merge pull request #44 from moda20/Feature/Add-log-files-management-to-the-loki-logs-drawer
2 parents 3698e3f + a0fc829 commit c094ee1

9 files changed

Lines changed: 90 additions & 17 deletions

File tree

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
},
2222
"dependencies": {
2323
"@hookform/resolvers": "^3.9.1",
24-
"@melloware/react-logviewer": "^6.3.4",
24+
"@melloware/react-logviewer": "^6.3.5",
2525
"@monaco-editor/react": "^4.7.0",
2626
"@radix-ui/react-alert-dialog": "^1.1.2",
2727
"@radix-ui/react-avatar": "^1.1.10",

src/components/custom/DrawerLokiLogs.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,8 +180,10 @@ export default function DrawerLokiLogs(props: DrawerLokiLogsProps) {
180180
(e: any) => e.fullMessage,
181181
)}
182182
wrapLines={false}
183+
follow={false}
183184
scrollToLine={1}
184185
extraLines={4}
186+
enableLinks={true}
185187
/>
186188
</TabsContent>
187189
)

src/components/custom/general/FileItem.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ export interface FileItemProps {
1515
canPreview?: boolean
1616
className?: string
1717
index?: number
18+
style?: React.CSSProperties
1819
}
1920

2021
export default function FileItem({
@@ -26,13 +27,18 @@ export default function FileItem({
2627
canDelete,
2728
canPreview,
2829
className,
30+
style,
2931
}: FileItemProps) {
3032
const titleName = item.fileName.split("/").pop()
3133
const parsedCreatedAt = useMemo(() => {
3234
return `${moment(item.createAt).format("YYYY-MM-DD HH")}h`
3335
}, [item])
3436
return (
35-
<div key={index} className={cn("flex flex-col gap-2 w-full", className)}>
37+
<div
38+
key={index}
39+
className={cn("flex flex-col gap-2 w-full", className)}
40+
style={style}
41+
>
3642
{item.blockId && item.index === 0 && (
3743
<div className="flex flex-row gap-1.5 items-center">
3844
<div className="separator h-[0.1px] bg-foreground opacity-50 w-1/6"></div>

src/components/custom/general/LogFileList.tsx

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ export default function LogFileList(props: LogfileListProps) {
2020
count: props.logFiles.length,
2121
getScrollElement: () => parentRef.current,
2222
estimateSize: () => 68.5,
23-
overscan: 68.5,
23+
overscan: 24,
2424
gap: 8,
2525
lanes: 1,
2626
})
@@ -56,8 +56,14 @@ export default function LogFileList(props: LogfileListProps) {
5656
height: `${rowVirtualizer.getTotalSize()}px`,
5757
}}
5858
>
59-
{rowVirtualizer.getVirtualItems().map(virtualRow => (
60-
<FileItem className="mb-2" {...FileList[virtualRow.index]} />
59+
{rowVirtualizer.getVirtualItems().map((virtualRow, index) => (
60+
<FileItem
61+
className="mb-2 absolute"
62+
style={{
63+
transform: `translateY(${virtualRow.start}px)`,
64+
}}
65+
{...FileList[virtualRow?.index ?? index]}
66+
/>
6167
))}
6268
</div>
6369
</div>

src/components/custom/general/LogViewer.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,11 @@ export const LiveLogViewer: React.FC<LiveLogViewerProps> = ({
5454
!askForLogs
5555
)
5656
return onScroll
57+
const listRef = internalRef.current.listRef.current
5758
if (
5859
fetchedCountRef.current < buffer.length &&
59-
internalRef.current.listRef.current.findEndIndex() + 50 >
60+
listRef.findItemIndex(listRef.scrollOffset + listRef.viewportSize) +
61+
50 >
6062
buffer.length
6163
) {
6264
fetchedCountRef.current = buffer.length

src/components/sheet-action-dialog.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,6 @@ export default function SheetActionDialog(
7575
>
7676
{props.children}
7777
</div>
78-
<SheetFooter></SheetFooter>
7978
</SheetContent>
8079
</Sheet>
8180
)

src/features/system/eventLog.tsx

Lines changed: 52 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,18 @@ import { useSocketLogs } from "@/lib/socketUtils"
33
import { Card, CardContent, CardHeader } from "@/components/ui/card"
44
import { LiveLogViewer } from "@/components/custom/general/LogViewer"
55
import { DatePickerWithPresets } from "@/components/ui/date-picker-presets"
6-
import { useCallback, useState } from "react"
6+
import { useCallback, useMemo, useState } from "react"
77
import type { DateRange } from "react-day-picker"
88
import { defaultLogPeriod } from "@/features/jobsTable/interfaces"
9+
import TabButtonGroup from "@/components/custom/general/TabButtonGroup"
10+
import LogFileList from "@/components/custom/general/LogFileList"
11+
import { useJobLogs } from "@/hooks/useLogs"
12+
import Spinner from "@/components/custom/LoadingOverlay"
913

14+
const tabList = ["Events", "Files"]
1015
export function EventLog() {
1116
const [period, setPeriod] = useState<DateRange>(defaultLogPeriod)
17+
const [activeLogTypeTab, setActiveLogTypeTab] = useState<string>(tabList[0])
1218
const { latestLogs, logs } = useSocketLogs({
1319
actions: [MiscNotificationTopics.EventLog],
1420
format: (data: any) => ({
@@ -25,6 +31,18 @@ export function EventLog() {
2531
setPeriod(period ?? defaultLogPeriod)
2632
}, [])
2733

34+
const isEventsTabActive = useMemo(
35+
() => activeLogTypeTab === "Events",
36+
[activeLogTypeTab],
37+
)
38+
39+
const {
40+
systemLogFiles,
41+
loading: logFileLoading,
42+
readLogFile,
43+
downloadLogFile,
44+
} = useJobLogs({})
45+
2846
return (
2947
<div className="flex flex-col gap-4 h-full">
3048
<div className={"flex flex-col gap-1 mb-4"}>
@@ -39,21 +57,45 @@ export function EventLog() {
3957
<div className="text-l font-bold tracking-tight italic flex-col gap-2 items-left">
4058
<div>Event logs</div>
4159
<div className="italic text-sm">
42-
All system event logs, updated in real time
60+
{isEventsTabActive
61+
? "All system event logs, updated in real time"
62+
: "All system event log files"}
4363
</div>
4464
</div>
45-
<DatePickerWithPresets
46-
onChange={onPeriodFilterChange}
47-
defaultValue={period}
48-
/>
65+
<div className="flex gap-2">
66+
<DatePickerWithPresets
67+
onChange={onPeriodFilterChange}
68+
defaultValue={period}
69+
disabled={!isEventsTabActive}
70+
/>
71+
<TabButtonGroup
72+
tabList={tabList}
73+
setActiveTab={setActiveLogTypeTab}
74+
activeTab={activeLogTypeTab}
75+
/>
76+
</div>
4977
</CardHeader>
5078
<CardContent className="p-4 pt-0 h-full">
5179
<div className="flex flex-col gap-2 h-full">
5280
<div className="space-y-1 rounded bg-background text-foreground text-sm min-h-[500px] w-full flex-grow">
53-
<LiveLogViewer
54-
initialLogs={logs.map(e => e.fullMessage)}
55-
newLogs={latestLogs.map(e => e.fullMessage)}
56-
/>
81+
{isEventsTabActive ? (
82+
<LiveLogViewer
83+
initialLogs={logs.map(e => e.fullMessage)}
84+
newLogs={latestLogs.map(e => e.fullMessage)}
85+
/>
86+
) : (
87+
<Spinner
88+
isLoading={logFileLoading}
89+
className="flex flex-col max-h-[calc(100vh-18rem)]"
90+
>
91+
<LogFileList
92+
logFiles={systemLogFiles}
93+
readLogFile={readLogFile}
94+
originName="System"
95+
downloadLogFile={downloadLogFile}
96+
/>
97+
</Spinner>
98+
)}
5799
</div>
58100
</div>
59101
</CardContent>

src/hooks/useLogs.tsx

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { useCallback, useEffect, useState } from "react"
33
import {
44
downloadLogfile,
55
getJobLogs,
6+
getSystemLogFiles as getSysLogFiles,
67
readLogfile as readLogService,
78
} from "@/services/components/logsService"
89

@@ -12,6 +13,7 @@ export interface useLogsHookProps {
1213

1314
export function useJobLogs({ jobId }: useLogsHookProps) {
1415
const [logFiles, setLogFiles] = useState<LogFileMetadata[]>([])
16+
const [systemLogFiles, setSystemLogFiles] = useState<LogFileMetadata[]>([])
1517
const [loading, setLoading] = useState(false)
1618

1719
const getJobLogFiles = useCallback(() => {
@@ -20,12 +22,22 @@ export function useJobLogs({ jobId }: useLogsHookProps) {
2022
})
2123
}, [jobId])
2224

25+
const getSystemLogFiles = useCallback(() => {
26+
return getSysLogFiles().then(d => {
27+
setSystemLogFiles([...d.sysEvents.data, ...d.scheduleEvents.data])
28+
})
29+
}, [])
30+
2331
useEffect(() => {
2432
setLoading(true)
2533
if (jobId) {
2634
getJobLogFiles().finally(() => {
2735
setLoading(false)
2836
})
37+
} else {
38+
getSystemLogFiles().finally(() => {
39+
setLoading(false)
40+
})
2941
}
3042
}, [getJobLogFiles, jobId])
3143

@@ -66,6 +78,7 @@ export function useJobLogs({ jobId }: useLogsHookProps) {
6678
return {
6779
logFiles,
6880
loading,
81+
systemLogFiles,
6982
readLogFile,
7083
downloadLogFile,
7184
}

src/services/components/logsService.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@ export const getJobLogs = (jobId: number) => {
5959
})
6060
}
6161

62+
export const getSystemLogFiles = (): Promise<any> => {
63+
return axios.get("/files/logs/systemLogfiles")
64+
}
6265
export const readLogfile = (
6366
fileName: string,
6467
limit: number,

0 commit comments

Comments
 (0)