Feature/tor logs (#3077)

* add tor logs, rework services page, other small things

* feat: sortable service table and mobile view

---------

Co-authored-by: waterplea <alexander@inkin.ru>
This commit is contained in:
Matt Hill
2025-12-16 12:47:43 -07:00
committed by GitHub
parent e35b643e51
commit 5d8331b7f7
26 changed files with 443 additions and 506 deletions

View File

@@ -73,14 +73,14 @@ export namespace RR {
uptime: number // seconds
}
export type GetServerLogsReq = FetchLogsReq // server.logs & server.kernel-logs
export type GetServerLogsReq = FetchLogsReq // server.logs & server.kernel-logs & net.tor.logs
export type GetServerLogsRes = FetchLogsRes
export type FollowServerLogsReq = {
limit?: number // (optional) default is 50. Ignored if cursor provided
boot?: number | string | null // (optional) number is offset (0: current, -1 prev, +1 first), string is a specific boot id, null is all. Default is undefined
cursor?: string // the last known log. Websocket will return all logs since this log
} // server.logs.follow & server.kernel-logs.follow
} // server.logs.follow & server.kernel-logs.follow & net.tor.follow-logs
export type FollowServerLogsRes = {
startCursor: string
guid: string

View File

@@ -86,6 +86,8 @@ export abstract class ApiService {
params: RR.GetServerLogsReq,
): Promise<RR.GetServerLogsRes>
abstract getTorLogs(params: RR.GetServerLogsReq): Promise<RR.GetServerLogsRes>
abstract getKernelLogs(
params: RR.GetServerLogsReq,
): Promise<RR.GetServerLogsRes>
@@ -94,6 +96,10 @@ export abstract class ApiService {
params: RR.FollowServerLogsReq,
): Promise<RR.FollowServerLogsRes>
abstract followTorLogs(
params: RR.FollowServerLogsReq,
): Promise<RR.FollowServerLogsRes>
abstract followKernelLogs(
params: RR.FollowServerLogsReq,
): Promise<RR.FollowServerLogsRes>

View File

@@ -206,6 +206,10 @@ export class LiveApiService extends ApiService {
return this.rpcRequest({ method: 'server.logs', params })
}
async getTorLogs(params: RR.GetServerLogsReq): Promise<RR.GetServerLogsRes> {
return this.rpcRequest({ method: 'net.tor.logs', params })
}
async getKernelLogs(
params: RR.GetServerLogsReq,
): Promise<RR.GetServerLogsRes> {
@@ -218,6 +222,12 @@ export class LiveApiService extends ApiService {
return this.rpcRequest({ method: 'server.logs.follow', params })
}
async followTorLogs(
params: RR.FollowServerLogsReq,
): Promise<RR.FollowServerLogsRes> {
return this.rpcRequest({ method: 'net.tor.logs.follow', params })
}
async followKernelLogs(
params: RR.FollowServerLogsReq,
): Promise<RR.FollowServerLogsRes> {

View File

@@ -290,6 +290,17 @@ export class MockApiService extends ApiService {
}
}
async getTorLogs(params: RR.GetServerLogsReq): Promise<RR.GetServerLogsRes> {
await pauseFor(2000)
const entries = this.randomLogs(params.limit)
return {
entries,
startCursor: 'start-cursor',
endCursor: 'end-cursor',
}
}
async getKernelLogs(
params: RR.GetServerLogsReq,
): Promise<RR.GetServerLogsRes> {
@@ -313,6 +324,16 @@ export class MockApiService extends ApiService {
}
}
async followTorLogs(
params: RR.FollowServerLogsReq,
): Promise<RR.FollowServerLogsRes> {
await pauseFor(2000)
return {
startCursor: 'start-cursor',
guid: 'logs-guid',
}
}
async followKernelLogs(
params: RR.FollowServerLogsReq,
): Promise<RR.FollowServerLogsRes> {

View File

@@ -222,6 +222,167 @@ export const mockPatchData: DataModel = {
kiosk: true,
},
packageData: {
lnd: {
stateInfo: {
state: 'installed',
manifest: {
...Mock.MockManifestLnd,
version: '0.11.0:0.0.1',
},
},
s9pk: '/media/startos/data/package-data/archive/installed/asdfasdf.s9pk',
icon: '/assets/img/service-icons/lnd.png',
lastBackup: null,
statusInfo: {
desired: { main: 'stopped' },
error: null,
health: {},
started: null,
},
actions: {
config: {
name: 'Config',
description: 'LND needs configuration before starting',
warning: null,
visibility: 'enabled',
allowedStatuses: 'any',
hasInput: true,
group: null,
},
connect: {
name: 'Connect',
description: 'View LND connection details',
warning: null,
visibility: 'enabled',
allowedStatuses: 'any',
hasInput: true,
group: 'Connecting',
},
},
serviceInterfaces: {
grpc: {
id: 'grpc',
masked: false,
name: 'GRPC',
description:
'Used by dependent services and client wallets for connecting to your node',
type: 'api',
addressInfo: {
username: null,
hostId: 'qrstuv',
internalPort: 10009,
scheme: null,
sslScheme: 'grpc',
suffix: '',
},
},
lndconnect: {
id: 'lndconnect',
masked: true,
name: 'LND Connect',
description:
'Used by client wallets adhering to LND Connect protocol to connect to your node',
type: 'api',
addressInfo: {
username: null,
hostId: 'qrstuv',
internalPort: 10009,
scheme: null,
sslScheme: 'lndconnect',
suffix: 'cert=askjdfbjadnaskjnd&macaroon=ksjbdfnhjasbndjksand',
},
},
p2p: {
id: 'p2p',
masked: false,
name: 'P2P',
description:
'Used for connecting to other nodes on the Bitcoin network',
type: 'p2p',
addressInfo: {
username: null,
hostId: 'rstuvw',
internalPort: 8333,
scheme: 'bitcoin',
sslScheme: null,
suffix: '',
},
},
},
currentDependencies: {
bitcoind: {
title: Mock.BitcoinDep.title,
icon: Mock.BitcoinDep.icon,
kind: 'running',
versionRange: '>=26.0.0',
healthChecks: [],
},
'btc-rpc-proxy': {
title: Mock.ProxyDep.title,
icon: Mock.ProxyDep.icon,
kind: 'running',
versionRange: '>2.0.0',
healthChecks: [],
},
},
hosts: {},
storeExposedDependents: [],
registry: 'https://registry.start9.com/',
developerKey: 'developer-key',
tasks: {
config: {
active: true,
task: {
packageId: 'lnd',
actionId: 'config',
severity: 'critical',
reason: 'LND needs configuration before starting',
},
},
connect: {
active: true,
task: {
packageId: 'lnd',
actionId: 'connect',
severity: 'important',
reason: 'View LND connection details',
},
},
'bitcoind/config': {
active: true,
task: {
packageId: 'bitcoind',
actionId: 'config',
severity: 'critical',
reason: 'LND likes BTC a certain way',
input: {
kind: 'partial',
value: {
color: '#ffffff',
testnet: false,
},
},
},
},
'bitcoind/rpc': {
active: true,
task: {
packageId: 'bitcoind',
actionId: 'rpc',
severity: 'important',
reason: `LND want's its own RPC credentials`,
input: {
kind: 'partial',
value: {
rpcsettings: {
rpcuser: 'lnd',
},
},
},
},
},
},
},
bitcoind: {
stateInfo: {
state: 'installed',
@@ -511,166 +672,5 @@ export const mockPatchData: DataModel = {
},
},
},
lnd: {
stateInfo: {
state: 'installed',
manifest: {
...Mock.MockManifestLnd,
version: '0.11.0:0.0.1',
},
},
s9pk: '/media/startos/data/package-data/archive/installed/asdfasdf.s9pk',
icon: '/assets/img/service-icons/lnd.png',
lastBackup: null,
statusInfo: {
desired: { main: 'stopped' },
error: null,
health: {},
started: null,
},
actions: {
config: {
name: 'Config',
description: 'LND needs configuration before starting',
warning: null,
visibility: 'enabled',
allowedStatuses: 'any',
hasInput: true,
group: null,
},
connect: {
name: 'Connect',
description: 'View LND connection details',
warning: null,
visibility: 'enabled',
allowedStatuses: 'any',
hasInput: true,
group: 'Connecting',
},
},
serviceInterfaces: {
grpc: {
id: 'grpc',
masked: false,
name: 'GRPC',
description:
'Used by dependent services and client wallets for connecting to your node',
type: 'api',
addressInfo: {
username: null,
hostId: 'qrstuv',
internalPort: 10009,
scheme: null,
sslScheme: 'grpc',
suffix: '',
},
},
lndconnect: {
id: 'lndconnect',
masked: true,
name: 'LND Connect',
description:
'Used by client wallets adhering to LND Connect protocol to connect to your node',
type: 'api',
addressInfo: {
username: null,
hostId: 'qrstuv',
internalPort: 10009,
scheme: null,
sslScheme: 'lndconnect',
suffix: 'cert=askjdfbjadnaskjnd&macaroon=ksjbdfnhjasbndjksand',
},
},
p2p: {
id: 'p2p',
masked: false,
name: 'P2P',
description:
'Used for connecting to other nodes on the Bitcoin network',
type: 'p2p',
addressInfo: {
username: null,
hostId: 'rstuvw',
internalPort: 8333,
scheme: 'bitcoin',
sslScheme: null,
suffix: '',
},
},
},
currentDependencies: {
bitcoind: {
title: Mock.BitcoinDep.title,
icon: Mock.BitcoinDep.icon,
kind: 'running',
versionRange: '>=26.0.0',
healthChecks: [],
},
'btc-rpc-proxy': {
title: Mock.ProxyDep.title,
icon: Mock.ProxyDep.icon,
kind: 'running',
versionRange: '>2.0.0',
healthChecks: [],
},
},
hosts: {},
storeExposedDependents: [],
registry: 'https://registry.start9.com/',
developerKey: 'developer-key',
tasks: {
config: {
active: true,
task: {
packageId: 'lnd',
actionId: 'config',
severity: 'critical',
reason: 'LND needs configuration before starting',
},
},
connect: {
active: true,
task: {
packageId: 'lnd',
actionId: 'connect',
severity: 'important',
reason: 'View LND connection details',
},
},
'bitcoind/config': {
active: true,
task: {
packageId: 'bitcoind',
actionId: 'config',
severity: 'critical',
reason: 'LND likes BTC a certain way',
input: {
kind: 'partial',
value: {
color: '#ffffff',
testnet: false,
},
},
},
},
'bitcoind/rpc': {
active: true,
task: {
packageId: 'bitcoind',
actionId: 'rpc',
severity: 'important',
reason: `LND want's its own RPC credentials`,
input: {
kind: 'partial',
value: {
rpcsettings: {
rpcuser: 'lnd',
},
},
},
},
},
},
},
},
}