mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-26 10:21:52 +00:00
ui: adds agent logs page in server show
This commit is contained in:
committed by
Aiden McClelland
parent
327c79350e
commit
a9735fd777
@@ -0,0 +1,28 @@
|
||||
import { NgModule } from '@angular/core'
|
||||
import { CommonModule } from '@angular/common'
|
||||
import { Routes, RouterModule } from '@angular/router'
|
||||
|
||||
import { IonicModule } from '@ionic/angular'
|
||||
|
||||
import { ServerLogsPage } from './server-logs.page'
|
||||
import { PwaBackComponentModule } from 'src/app/components/pwa-back-button/pwa-back.component.module'
|
||||
import { BadgeMenuComponentModule } from 'src/app/components/badge-menu-button/badge-menu.component.module'
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
path: '',
|
||||
component: ServerLogsPage,
|
||||
},
|
||||
]
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonModule,
|
||||
IonicModule,
|
||||
RouterModule.forChild(routes),
|
||||
PwaBackComponentModule,
|
||||
BadgeMenuComponentModule,
|
||||
],
|
||||
declarations: [ServerLogsPage],
|
||||
})
|
||||
export class ServerLogsPageModule { }
|
||||
@@ -0,0 +1,22 @@
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-buttons slot="start">
|
||||
<pwa-back-button></pwa-back-button>
|
||||
</ion-buttons>
|
||||
<ion-title>Logs</ion-title>
|
||||
<ion-buttons slot="end" class="ion-padding-end">
|
||||
<ion-button (click)="getLogs()" color="primary">
|
||||
<ion-icon name="refresh-outline"></ion-icon>
|
||||
</ion-button>
|
||||
<badge-menu-button></badge-menu-button>
|
||||
</ion-buttons>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content class="ion-padding" color="light">
|
||||
<ion-item *ngIf="error" style="margin-bottom: 16px;">
|
||||
<ion-text class="ion-text-wrap" color="danger">{{ error }}</ion-text>
|
||||
</ion-item>
|
||||
<ion-spinner *ngIf="$loading$ | async" class="center" name="lines" color="warning"></ion-spinner>
|
||||
<p style="white-space: pre-line;">{{ logs }}</p>
|
||||
</ion-content>
|
||||
@@ -0,0 +1,45 @@
|
||||
import { Component, ViewChild } from '@angular/core'
|
||||
import { ActivatedRoute } from '@angular/router'
|
||||
import { ApiService } from 'src/app/services/api/api.service'
|
||||
import { IonContent } from '@ionic/angular'
|
||||
import { pauseFor } from 'src/app/util/misc.util'
|
||||
import { markAsLoadingDuringP } from 'src/app/services/loader.service'
|
||||
import { BehaviorSubject } from 'rxjs'
|
||||
|
||||
@Component({
|
||||
selector: 'server-logs',
|
||||
templateUrl: './server-logs.page.html',
|
||||
styleUrls: ['./server-logs.page.scss'],
|
||||
})
|
||||
export class ServerLogsPage {
|
||||
@ViewChild(IonContent, { static: false }) private content: IonContent
|
||||
$loading$ = new BehaviorSubject(true)
|
||||
error = ''
|
||||
logs: string
|
||||
|
||||
constructor (
|
||||
private readonly apiService: ApiService,
|
||||
) { }
|
||||
|
||||
async ngOnInit () {
|
||||
markAsLoadingDuringP(this.$loading$, Promise.all([
|
||||
this.getLogs(),
|
||||
pauseFor(600),
|
||||
]))
|
||||
}
|
||||
|
||||
async getLogs () {
|
||||
this.logs = ''
|
||||
this.$loading$.next(true)
|
||||
try {
|
||||
this.logs = await this.apiService.getServerLogs()
|
||||
this.error = ''
|
||||
setTimeout(async () => await this.content.scrollToBottom(100), 200)
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
this.error = e.message
|
||||
} finally {
|
||||
this.$loading$.next(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,11 @@ const routes: Routes = [
|
||||
canActivate: [AuthGuard],
|
||||
loadChildren: () => import('./server-metrics/server-metrics.module').then(m => m.ServerMetricsPageModule),
|
||||
},
|
||||
{
|
||||
path: 'logs',
|
||||
canActivate: [AuthGuard],
|
||||
loadChildren: () => import('./server-logs/server-logs.module').then(m => m.ServerLogsPageModule),
|
||||
},
|
||||
{
|
||||
path: 'config',
|
||||
canActivate: [AuthGuard],
|
||||
|
||||
@@ -47,6 +47,11 @@
|
||||
<ion-label><ion-text color="primary">Monitor</ion-text></ion-label>
|
||||
</ion-item>
|
||||
|
||||
<ion-item [routerLink]="['logs']">
|
||||
<ion-icon slot="start" name="newspaper-outline" color="primary"></ion-icon>
|
||||
<ion-label><ion-text color="primary">Logs</ion-text></ion-label>
|
||||
</ion-item>
|
||||
|
||||
<ion-item lines="none" [routerLink]="['config']">
|
||||
<ion-icon slot="start" name="cog-outline" color="primary"></ion-icon>
|
||||
<ion-label><ion-text color="primary">Config</ion-text></ion-label>
|
||||
|
||||
@@ -39,6 +39,7 @@ export abstract class ApiService {
|
||||
abstract getExternalDisks (): Promise<DiskInfo[]>
|
||||
abstract getAppConfig (appId: string): Promise<{ spec: ConfigSpec, config: object, rules: Rules[]}>
|
||||
abstract getAppLogs (appId: string, params?: ReqRes.GetAppLogsReq): Promise<string[]>
|
||||
abstract getServerLogs (): Promise<string>
|
||||
abstract installApp (appId: string, version: string, dryRun?: boolean): Promise<AppInstalledFull & { breakages: DependentBreakage[] } >
|
||||
abstract uninstallApp (appId: string, dryRun?: boolean): Promise<{ breakages: DependentBreakage[] }>
|
||||
abstract startApp (appId: string): Promise<Unit>
|
||||
@@ -76,7 +77,9 @@ export module ReqRes {
|
||||
export type GetAppInstalledRes = ApiAppInstalledFull
|
||||
export type GetAppConfigRes = ApiAppConfig
|
||||
export type GetAppLogsReq = { after?: string, before?: string, page?: string, perPage?: string }
|
||||
export type GetServerLogsReq = { }
|
||||
export type GetAppLogsRes = string[]
|
||||
export type GetServerLogsRes = string
|
||||
export type GetAppMetricsRes = AppMetricsVersioned<number>
|
||||
export type GetAppsInstalledRes = AppInstalledPreview[]
|
||||
export type PostInstallAppReq = { version: string }
|
||||
|
||||
@@ -123,6 +123,10 @@ export class LiveApiService extends ApiService {
|
||||
return this.authRequest<ReqRes.GetAppLogsRes>( { method: Method.GET, url: `/apps/${appId}/logs`, params: params as any })
|
||||
}
|
||||
|
||||
async getServerLogs (): Promise<string> {
|
||||
return this.authRequest<ReqRes.GetServerLogsRes>( { method: Method.GET, url: `/logs` })
|
||||
}
|
||||
|
||||
async getAppMetrics (appId: string): Promise<AppMetrics> {
|
||||
return this.authRequest<ReqRes.GetAppMetricsRes | string>( { method: Method.GET, url: `/apps/${appId}/metrics` })
|
||||
.then(parseMetricsPermissive)
|
||||
|
||||
@@ -113,6 +113,10 @@ export class MockApiService extends ApiService {
|
||||
return mockGetAppLogs()
|
||||
}
|
||||
|
||||
async getServerLogs (): Promise<string> {
|
||||
return mockGetServerLogs()
|
||||
}
|
||||
|
||||
async installApp (appId: string, version: string, dryRun: boolean): Promise<AppInstalledFull & { breakages: DependentBreakage[] }> {
|
||||
return mockInstallApp(appId)
|
||||
}
|
||||
@@ -271,6 +275,11 @@ async function mockGetAppLogs (): Promise<ReqRes.GetAppLogsRes> {
|
||||
return mockApiAppLogs
|
||||
}
|
||||
|
||||
async function mockGetServerLogs (): Promise<ReqRes.GetServerLogsRes> {
|
||||
await pauseFor(1000)
|
||||
return mockApiServerLogs.join('\n')
|
||||
}
|
||||
|
||||
async function mockGetAppMetrics (): Promise<ReqRes.GetAppMetricsRes> {
|
||||
await pauseFor(1000)
|
||||
return mockApiAppMetricsV1
|
||||
@@ -610,6 +619,91 @@ const mockApiAppLogs: string[] = [
|
||||
'****** FINISH *****',
|
||||
]
|
||||
|
||||
const mockApiServerLogs: string[] = [
|
||||
'****** START *****',
|
||||
'[ng] ℹ 「wdm」: Compiled successfully.',
|
||||
'[ng] ℹ 「wdm」: Compiling...',
|
||||
'[ng] Date: 2019-12-26T14:20:30.872Z - Hash: 2b2e5abb3cba2164aea0',
|
||||
'[ng] 114 unchanged chunks',
|
||||
'[ng] chunk {app-logs-app-logs-module} app-logs-app-logs-module.js, app-logs-app-logs-module.js.map (app-logs-app-logs-module) 7.86 kB [rendered]',
|
||||
'[ng] Time: 1244ms',
|
||||
'[ng] ℹ 「wdm」: Compiled successfully.',
|
||||
'[ng] ℹ 「wdm」: Compiling...',
|
||||
'[ng] Date: 2019-12-26T14:21:01.685Z - Hash: bb3f5d0e11f2cd2dd57b',
|
||||
'[ng] 114 unchanged chunks',
|
||||
'[ng] chunk {app-logs-app-logs-module} app-logs-app-logs-module.js, app-logs-app-logs-module.js.map (app-logs-app-logs-module) 7.86 kB [rendered]',
|
||||
'[ng] Time: 1185ms',
|
||||
'[ng] ℹ 「wdm」: Compiled successfully.',
|
||||
'[ng] ℹ 「wdm」: Compiling...',
|
||||
'[ng] Date: 2019-12-26T14:23:13.812Z - Hash: 9342e11e6b8e16ad2f70',
|
||||
'[ng] 114 unchanged chunks',
|
||||
'[ng] ℹ 「wdm」: Compiled successfully.',
|
||||
'[ng] ℹ 「wdm」: Compiling...',
|
||||
'[ng] Date: 2019-12-26T14:20:30.872Z - Hash: 2b2e5abb3cba2164aea0',
|
||||
'[ng] 114 unchanged chunks',
|
||||
'[ng] chunk {app-logs-app-logs-module} app-logs-app-logs-module.js, app-logs-app-logs-module.js.map (app-logs-app-logs-module) 7.86 kB [rendered]',
|
||||
'[ng] Time: 1244ms',
|
||||
'[ng] ℹ 「wdm」: Compiled successfully.',
|
||||
'[ng] ℹ 「wdm」: Compiling...',
|
||||
'[ng] Date: 2019-12-26T14:21:01.685Z - Hash: bb3f5d0e11f2cd2dd57b',
|
||||
'[ng] 114 unchanged chunks',
|
||||
'[ng] chunk {app-logs-app-logs-module} app-logs-app-logs-module.js, app-logs-app-logs-module.js.map (app-logs-app-logs-module) 7.86 kB [rendered]',
|
||||
'[ng] Time: 1185ms',
|
||||
'[ng] ℹ 「wdm」: Compiled successfully.',
|
||||
'[ng] ℹ 「wdm」: Compiling...',
|
||||
'[ng] Date: 2019-12-26T14:23:13.812Z - Hash: 9342e11e6b8e16ad2f70',
|
||||
'[ng] 114 unchanged chunks',
|
||||
'[ng] ℹ 「wdm」: Compiled successfully.',
|
||||
'[ng] ℹ 「wdm」: Compiling...',
|
||||
'[ng] Date: 2019-12-26T14:20:30.872Z - Hash: 2b2e5abb3cba2164aea0',
|
||||
'[ng] 114 unchanged chunks',
|
||||
'[ng] chunk {app-logs-app-logs-module} app-logs-app-logs-module.js, app-logs-app-logs-module.js.map (app-logs-app-logs-module) 7.86 kB [rendered]',
|
||||
'[ng] Time: 1244ms',
|
||||
'[ng] ℹ 「wdm」: Compiled successfully.',
|
||||
'[ng] ℹ 「wdm」: Compiling...',
|
||||
'[ng] Date: 2019-12-26T14:21:01.685Z - Hash: bb3f5d0e11f2cd2dd57b',
|
||||
'[ng] 114 unchanged chunks',
|
||||
'[ng] chunk {app-logs-app-logs-module} app-logs-app-logs-module.js, app-logs-app-logs-module.js.map (app-logs-app-logs-module) 7.86 kB [rendered]',
|
||||
'[ng] Time: 1185ms',
|
||||
'[ng] ℹ 「wdm」: Compiled successfully.',
|
||||
'[ng] ℹ 「wdm」: Compiling...',
|
||||
'[ng] Date: 2019-12-26T14:23:13.812Z - Hash: 9342e11e6b8e16ad2f70',
|
||||
'[ng] 114 unchanged chunks',
|
||||
'[ng] ℹ 「wdm」: Compiled successfully.',
|
||||
'[ng] ℹ 「wdm」: Compiling...',
|
||||
'[ng] Date: 2019-12-26T14:20:30.872Z - Hash: 2b2e5abb3cba2164aea0',
|
||||
'[ng] 114 unchanged chunks',
|
||||
'[ng] chunk {app-logs-app-logs-module} app-logs-app-logs-module.js, app-logs-app-logs-module.js.map (app-logs-app-logs-module) 7.86 kB [rendered]',
|
||||
'[ng] Time: 1244ms',
|
||||
'[ng] ℹ 「wdm」: Compiled successfully.',
|
||||
'[ng] ℹ 「wdm」: Compiling...',
|
||||
'[ng] Date: 2019-12-26T14:21:01.685Z - Hash: bb3f5d0e11f2cd2dd57b',
|
||||
'[ng] 114 unchanged chunks',
|
||||
'[ng] chunk {app-logs-app-logs-module} app-logs-app-logs-module.js, app-logs-app-logs-module.js.map (app-logs-app-logs-module) 7.86 kB [rendered]',
|
||||
'[ng] Time: 1185ms',
|
||||
'[ng] ℹ 「wdm」: Compiled successfully.',
|
||||
'[ng] ℹ 「wdm」: Compiling...',
|
||||
'[ng] Date: 2019-12-26T14:23:13.812Z - Hash: 9342e11e6b8e16ad2f70',
|
||||
'[ng] 114 unchanged chunks',
|
||||
'[ng] ℹ 「wdm」: Compiled successfully.',
|
||||
'[ng] ℹ 「wdm」: Compiling...',
|
||||
'[ng] Date: 2019-12-26T14:20:30.872Z - Hash: 2b2e5abb3cba2164aea0',
|
||||
'[ng] 114 unchanged chunks',
|
||||
'[ng] chunk {app-logs-app-logs-module} app-logs-app-logs-module.js, app-logs-app-logs-module.js.map (app-logs-app-logs-module) 7.86 kB [rendered]',
|
||||
'[ng] Time: 1244ms',
|
||||
'[ng] ℹ 「wdm」: Compiled successfully.',
|
||||
'[ng] ℹ 「wdm」: Compiling...',
|
||||
'[ng] Date: 2019-12-26T14:21:01.685Z - Hash: bb3f5d0e11f2cd2dd57b',
|
||||
'[ng] 114 unchanged chunks',
|
||||
'[ng] chunk {app-logs-app-logs-module} app-logs-app-logs-module.js, app-logs-app-logs-module.js.map (app-logs-app-logs-module) 7.86 kB [rendered]',
|
||||
'[ng] Time: 1185ms',
|
||||
'[ng] ℹ 「wdm」: Compiled successfully.',
|
||||
'[ng] ℹ 「wdm」: Compiling...',
|
||||
'[ng] Date: 2019-12-26T14:23:13.812Z - Hash: 9342e11e6b8e16ad2f70',
|
||||
'[ng] 114 unchanged chunks',
|
||||
'****** FINISH *****',
|
||||
]
|
||||
|
||||
const mockApiAppMetricsV1: AppMetricsVersioned<2> = {
|
||||
version: 2,
|
||||
data: {
|
||||
|
||||
Reference in New Issue
Block a user