feat(logs): render logs in table

This commit is contained in:
kunish 2023-09-01 22:07:02 +08:00
parent 4a16271bb0
commit 7eee024cdc
No known key found for this signature in database
GPG Key ID: 647A12B4F782C430
4 changed files with 90 additions and 22 deletions

View File

@ -7,7 +7,6 @@ mode: rule
log-level: info log-level: info
ipv6: true ipv6: true
external-controller: 0.0.0.0:9090 external-controller: 0.0.0.0:9090
external-ui: ui
global-client-fingerprint: random global-client-fingerprint: random
profile: profile:

View File

@ -1,11 +1,21 @@
import { createEventSignal } from '@solid-primitives/event-listener' import { createEventSignal } from '@solid-primitives/event-listener'
import { createReconnectingWS } from '@solid-primitives/websocket' import { createReconnectingWS } from '@solid-primitives/websocket'
import {
ColumnDef,
createSolidTable,
flexRender,
getCoreRowModel,
} from '@tanstack/solid-table'
import { For, createEffect, createSignal } from 'solid-js' import { For, createEffect, createSignal } from 'solid-js'
import { secret, wsEndpointURL } from '~/signals' import { secret, wsEndpointURL } from '~/signals'
import { Log } from '~/types'
type LogWithSeq = Log & { seq: number }
export default () => { export default () => {
let seq = 0
const [search, setSearch] = createSignal('') const [search, setSearch] = createSignal('')
const [logs, setLogs] = createSignal<string[]>([]) const [logs, setLogs] = createSignal<LogWithSeq[]>([])
const ws = createReconnectingWS(`${wsEndpointURL()}/logs?token=${secret()}`) const ws = createReconnectingWS(`${wsEndpointURL()}/logs?token=${secret()}`)
@ -21,11 +31,37 @@ export default () => {
} }
setLogs((logs) => setLogs((logs) =>
[ [{ ...(JSON.parse(data) as Log), seq }, ...logs].slice(0, 100),
...logs,
(JSON.parse(data) as { type: string; payload: string }).payload,
].slice(-100),
) )
seq++
})
const columns: ColumnDef<LogWithSeq>[] = [
{
accessorKey: 'Sequence',
accessorFn: (row) => row.seq,
},
{
accessorKey: 'Type',
accessorFn: (row) => row.type,
},
{
accessorKey: 'Payload',
accessorFn: (row) => row.payload,
},
]
const table = createSolidTable({
get data() {
return search()
? logs().filter((log) =>
log.payload.toLowerCase().includes(search().toLowerCase()),
)
: logs()
},
columns,
getCoreRowModel: getCoreRowModel(),
}) })
return ( return (
@ -37,21 +73,49 @@ export default () => {
/> />
<div class="overflow-x-auto whitespace-nowrap"> <div class="overflow-x-auto whitespace-nowrap">
<For <table class="table table-zebra-zebra table-xs bg-base-200">
each={ <thead>
search() <For each={table.getHeaderGroups()}>
? logs().filter((log) => {(headerGroup) => (
log.toLowerCase().includes(search().toLowerCase()), <tr>
) <For each={headerGroup.headers}>
: logs() {(header) => (
} <th class="bg-base-300">
> <div>
{(log) => ( {header.isPlaceholder
<div class="flex gap-4"> ? null
<div class="flex-shrink-0">{log}</div> : flexRender(
header.column.columnDef.header,
header.getContext(),
)}
</div> </div>
</th>
)} )}
</For> </For>
</tr>
)}
</For>
</thead>
<tbody>
<For each={table.getRowModel().rows}>
{(row) => (
<tr>
<For each={row.getVisibleCells()}>
{(cell) => (
<td>
{flexRender(
cell.column.columnDef.cell,
cell.getContext(),
)}
</td>
)}
</For>
</tr>
)}
</For>
</tbody>
</table>
</div> </div>
</div> </div>
) )

View File

@ -195,7 +195,7 @@ export default () => {
</TrafficWidget> </TrafficWidget>
</div> </div>
<div class="mx-auto grid w-full max-w-screen-lg grid-cols-1 gap-4"> <div class="mx-auto grid h-full w-full max-w-screen-xl grid-cols-1 gap-4">
<SolidApexCharts <SolidApexCharts
type="area" type="area"
options={trafficChartOptions()} options={trafficChartOptions()}

5
src/types.d.ts vendored
View File

@ -100,6 +100,11 @@ export type Connection = {
} }
} }
export type Log = {
type: string
payload: string
}
export type Config = { export type Config = {
port: number port: number
'socks-port': number 'socks-port': number