From e8ab9638b5dc0aa98bc2cb12f94ecaacc588fcc7 Mon Sep 17 00:00:00 2001 From: fufuu Date: Fri, 3 May 2024 11:08:31 +0200 Subject: [PATCH 001/126] clean init --- environments/environment.prod.ts | 40 ------------------------- environments/environment.ts | 51 -------------------------------- 2 files changed, 91 deletions(-) delete mode 100644 environments/environment.prod.ts delete mode 100644 environments/environment.ts diff --git a/environments/environment.prod.ts b/environments/environment.prod.ts deleted file mode 100644 index 35a4cb4..0000000 --- a/environments/environment.prod.ts +++ /dev/null @@ -1,40 +0,0 @@ - -import { Application } from "src/app/shared/model/conf.model"; - -export const environment = { - production: false, - url: "http://localhost:9006" -}; - -export const application: Application = { - default_env: 'prd', - session: { - api: { - default_period: makePeriod(0) - }, - main: { - default_period: makePeriod(0) - } - }, - dashboard: { - default_period: makePeriod(6), - api : { - default_period: undefined - }, - app: { - default_period: undefined - }, - database: { - default_period: undefined - }, - user: { - default_period: undefined - } - } -} - -export function makePeriod(dayBetween: number, shiftEnd: number = 0): { start: Date, end: Date } { - var s = new Date(); - return {start: new Date(s.getFullYear(), s.getMonth(), s.getDate() - dayBetween), end: new Date(s.getFullYear(), s.getMonth(), s.getDate() + shiftEnd)}; -} - diff --git a/environments/environment.ts b/environments/environment.ts deleted file mode 100644 index 099aae8..0000000 --- a/environments/environment.ts +++ /dev/null @@ -1,51 +0,0 @@ -// This file can be replaced during build by using the `fileReplacements` array. -// `ng build --prod` replaces `environment.ts` with `environment.prod.ts`. -// The list of file replacements can be found in `angular.json`. - -import { Application } from "src/app/shared/model/conf.model"; - -export const environment = { - production: false, - url: "http://localhost:9006" -}; - -export const application: Application = { - default_env: 'prd', - session: { - api: { - default_period: makePeriod(0) - }, - main: { - default_period: makePeriod(0) - } - }, - dashboard: { - default_period: makePeriod(6), - api : { - default_period: undefined - }, - app: { - default_period: undefined - }, - database: { - default_period: undefined - }, - user: { - default_period: undefined - } - } -} - -export function makePeriod(dayBetween: number, shiftEnd: number = 0): { start: Date, end: Date } { - var s = new Date(); - return {start: new Date(s.getFullYear(), s.getMonth(), s.getDate() - dayBetween), end: new Date(s.getFullYear(), s.getMonth(), s.getDate() + shiftEnd)}; -} - -/* - * For easier debugging in development mode, you can import the following file - * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`. - * - * This import should be commented out in production mode because it will have a negative impact - * on performance if an error is thrown. - */ -// import 'zone.js/plugins/zone-error'; // Included with Angular CLI. \ No newline at end of file From 1ed95c32e5e81f4c900dc892f0e26e599e196f5e Mon Sep 17 00:00:00 2001 From: YoussefDahi Date: Fri, 17 May 2024 16:22:57 +0200 Subject: [PATCH 002/126] model update adjustements / added db-request-detail --- src/app/app.module.ts | 6 + src/app/shared/services/trace.service.ts | 4 + src/app/shared/util.ts | 8 +- .../db-request-detail.component.html | 138 +++++++ .../db-request-detail.component.scss | 78 ++++ .../db-request-detail.component.ts | 350 ++++++++++++++++++ .../session-detail.component.html | 12 +- .../session-detail.component.scss | 3 +- .../session-detail.component.ts | 22 +- .../stats-database.component.ts | 30 +- src/app/views/views.module.ts | 4 +- 11 files changed, 622 insertions(+), 33 deletions(-) create mode 100644 src/app/views/db-request-detail/db-request-detail.component.html create mode 100644 src/app/views/db-request-detail/db-request-detail.component.scss create mode 100644 src/app/views/db-request-detail/db-request-detail.component.ts diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 36355a3..a8dea1c 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -23,6 +23,7 @@ import { StatsDatabaseComponent } from './views/stats-database/stats-database.co import { StatsAppComponent } from './views/stats-app/stats-app.component'; import { StatsApiComponent } from './views/stats-api/stats-api.component'; import { StatsUserComponent } from './views/stats-user/stats-user.component'; +import { DbRequestDetailComponent } from './views/db-request-detail/db-request-detail.component'; registerLocaleData(localeFr, 'fr-FR'); const routes: Route[] = [ @@ -53,6 +54,11 @@ const routes: Route[] = [ return 'Detail de l\'API'; } }, + { + path: 'api/:id/db/:dbid', + component: DbRequestDetailComponent, + title: 'Detail de la requête SQL' + }, { path: '**', pathMatch: 'full', redirectTo: `/session/api` } ] }, diff --git a/src/app/shared/services/trace.service.ts b/src/app/shared/services/trace.service.ts index a2b4222..3636946 100644 --- a/src/app/shared/services/trace.service.ts +++ b/src/app/shared/services/trace.service.ts @@ -29,4 +29,8 @@ export class TraceService { getTreeRequestById(id: string) { return this.http.get(`${localStorage.getItem('server')}/trace/session/request/${id}/tree`); } + + getDbRequestById(id: number){ + return this.http.get(`${localStorage.getItem('server')}/trace/db/request/${id}`); + } } \ No newline at end of file diff --git a/src/app/shared/util.ts b/src/app/shared/util.ts index 6b8f405..905193a 100644 --- a/src/app/shared/util.ts +++ b/src/app/shared/util.ts @@ -50,10 +50,10 @@ export class Utils { return "gray" } - getStateColorBool(failed: boolean) { - if (failed) - return 'red' - return 'green'; + getStateColorBool(completed: boolean) { + if (completed) + return 'green' + return 'red'; } statusBorder(param: any): { [key: string]: string } { diff --git a/src/app/views/db-request-detail/db-request-detail.component.html b/src/app/views/db-request-detail/db-request-detail.component.html new file mode 100644 index 0000000..06cff64 --- /dev/null +++ b/src/app/views/db-request-detail/db-request-detail.component.html @@ -0,0 +1,138 @@ +
+ + + + + settings_suggest + {{selectedSession?.type=='api' || selectedSession?.type =='outcoming' ? (selectedSession?.name|| 'N/A') : '[' + + selectedSession?.launchMode + '] ' + selectedSession?.name || 'N/A'}} + +
+ +
+ +
+ +
+ + +
+ warning{{selectedSession?.exception.message || selectedSession?.exception?.classname}} +
+
+ + + +
+ + person +
+ + {{selectedSession?.user || "N/A"}} + + le {{( selectedSession?.start*1000 ) | date: 'dd/MM/yyyy à HH:mm:ss.SSS': 'fr' }} +
+
+ {{selectedSession?.inDataSize || 0}}o + swap_vert + {{selectedSession?.outDataSize}}o en {{ getElapsedTime(selectedSession?.end, selectedSession?.start) | + number :'1.2-3'}}s +
+
+
+ + + + storage + {{selectedSession?.application?.name}} + +
+ +
+
+ + +
+
+ Database +
+
+ + {{ item.key }} + +
{{ item.value[0].databaseName }} v.{{ + item.value[0].databaseVersion}}
+
+
+ + +
+ +
+ {{selectedSession?.application?.address}} en {{selectedSession?.application?.env}} +
+ + {{selectedSession?.application?.os}} + + + {{selectedSession?.application?.re}} + +
+
+
+ + +
+
+ +
+ view_timeline + Chronologie +
+ +
+ +
+
+ + +
+

+ Aucun détail disponible ..
+ Vérifiez que TraceAPI est bien configuré sur {{ + selectedSession?.host}} +

+
+
+ Chargement en cours... +
\ No newline at end of file diff --git a/src/app/views/db-request-detail/db-request-detail.component.scss b/src/app/views/db-request-detail/db-request-detail.component.scss new file mode 100644 index 0000000..be9cebf --- /dev/null +++ b/src/app/views/db-request-detail/db-request-detail.component.scss @@ -0,0 +1,78 @@ +.header-card { + display: flex; + flex-direction: row; + gap: 0.5em; + margin-bottom: 2em; +} + +a { + color: inherit; + text-decoration: none; +} + +mat-card-title { + display: flex; + align-items: center; + padding: 0 16px; + height: 48px; + .right { + margin-left: auto; + } +} + +mat-card-content { + height: 100%; padding: 0 16px 16px; +} + +mat-card-footer { + padding: 0 16px; + border: 1px solid rgba(0,0,0,.05); + display: flex; + align-items: center; + gap: 0.5em; + font-style: italic; + font-size: 14px; + .right { + margin-left: auto; + display: flex; + align-items: center; + } +} + + +table { + table-layout: auto; +} +.dbfailed { + background-color: red !important; +} + +.progress { + height: 20px; + display: flex; +} + +.progress-bar { + justify-content: center; + overflow: hidden; + color: #fff; + text-align: center; + white-space: nowrap; +} + +.mat-mdc-row .mat-mdc-cell { + cursor: pointer; +} + +.mat-mdc-row:hover .mat-mdc-cell { + background-color: rgb(206, 206, 206); +} + +.mat-mdc-table .mdc-data-table__header-row { + background-color: #d1d1d1; +} + +.url { + color: blue; + text-decoration: solid; +} \ No newline at end of file diff --git a/src/app/views/db-request-detail/db-request-detail.component.ts b/src/app/views/db-request-detail/db-request-detail.component.ts new file mode 100644 index 0000000..a246cf7 --- /dev/null +++ b/src/app/views/db-request-detail/db-request-detail.component.ts @@ -0,0 +1,350 @@ +import { AfterContentInit, Component, ElementRef, Injectable, NgZone, OnDestroy, ViewChild} from '@angular/core'; +import { MatDialog } from '@angular/material/dialog'; +import { MatTableDataSource } from '@angular/material/table'; +import { ActivatedRoute, NavigationExtras, Router} from '@angular/router'; +import { Observable, combineLatest} from "rxjs"; +import { Timeline } from 'vis-timeline'; +import { ExceptionInfo, OutcomingQuery, OutcomingRequest, RunnableStage } from 'src/app/shared/model/trace.model'; +import { Utils } from 'src/app/shared/util'; +import { DatePipe, Location} from '@angular/common'; +import { MatPaginator } from '@angular/material/paginator'; +import { MatSort } from '@angular/material/sort'; +import { TraceService } from 'src/app/shared/services/trace.service'; +import { application } from 'src/environments/environment'; + + +export interface UserData { + id: string; + name: string; + progress: string; + fruit: string; +} + +@Component({ + templateUrl: './db-request-detail.component.html', + styleUrls: ['./db-request-detail.component.scss'], + +}) +export class DbRequestDetailComponent implements AfterContentInit, OnDestroy { + + UtilInstance: Utils = new Utils(); + selectedQuery: any; + isComplete: boolean = true; + isLoading: boolean = false; + data: any[]; + chartOp: any; + resizeSubscription: any; + paramsSubscription: any; + chart: any; + options: any; + container: any; + dataTable: any; + timeLine: any; + queryBySchema :any[]; + env:any; + pipe = new DatePipe('fr-FR') + @ViewChild('timeline') timelineContainer: ElementRef; + @ViewChild('OutcomingRequestPaginator') outcomingRequestPaginator: MatPaginator; + @ViewChild('OutcomingRequestSort') outcomingRequestSort: MatSort; + @ViewChild('OutcomingQueryPaginator') outcomingQueryPaginator: MatPaginator; + @ViewChild('OutcomingQuerySort') outcomingQuerySort: MatSort; + + + constructor(private _activatedRoute: ActivatedRoute, + private _traceService: TraceService, + public dialog: MatDialog, + private zone: NgZone, + private _router: EnvRouter, + private _location: Location) { + + this.paramsSubscription = combineLatest([ + this._activatedRoute.params, + this._activatedRoute.queryParams + ]).subscribe({ + next: ([params, queryParams]) => { + this.getSessionById(params.id); + this.env = queryParams.env || application.default_env; + this._location.replaceState(`${this._router.url.split('?')[0]}?env=${this.env}`) + } + }); + } + + ngAfterContentInit(): void { + } + + + + getSessionById(id: number) { + + this.isLoading = true; + this._traceService.getDbRequestById(id).subscribe({ + next: (d: any) => { + if(d) + { + this.selectedQuery = d; + + //this.groupQueriesBySchema(); + this.configDbactions(this.selectedQuery) + this.visjs(); + this.isLoading = false; + this.isComplete = true; + } else { + this.isLoading = false; + this.isComplete= false; + // navigate to tab incoming + } + }, + error: err => { + this.isLoading = false; + } + }); + } + + visjs() { + + let timeline_end = +this.selectedQuery.end * 1000 + let timeline_start = +this.selectedQuery.start * 1000 + let dataArray: any = [...this.selectedQuery.requests, + ...this.selectedQuery.queries, + ...this.selectedQuery.stages.map((s: any) => ({ ...s, isStage: true }))]; + dataArray.splice(0, 0, {...this.selectedQuery,isStage: true}) + this.sortInnerArrayByDate(dataArray); + + + let data: any; + let groups: any; + let isWebapp = false, title = ''; + if (this.selectedQuery === "main" && this.selectedQuery.launchMode === "WEBAPP") { + groups = [{ id: 0, content: this.selectedQuery?.application?.re }]; + title = 'path'; + isWebapp = true; + } else { + groups = new Set(); + dataArray.forEach((c: any, i: number) => { + groups.add(c['threadName']) + }); + title = 'threadName'; + groups = Array.from(groups).map((g: string) => ({ id: g, content: g })) + } + data = dataArray.map((c: any, i: number) => { + let o = { + id: c.hasOwnProperty('schema') ? -i : c.id, + group: isWebapp ? 0 : c.threadName, + content:c.hasOwnProperty('isStage') ? '' : (c.schema || c.host || 'N/A'), + start: c.start * 1000, + end: c.end * 1000, + title: `${this.pipe.transform(new Date(c.start * 1000), 'HH:mm:ss.SSS')} - ${this.pipe.transform(new Date(c.end * 1000), 'HH:mm:ss.SSS')}
+

${c[title]}: ${this.getElapsedTime(c.end, c.start).toFixed(3)}s

`, + className: c.hasOwnProperty('schema') ? "bdd" : !c.hasOwnProperty('isStage') ? "rest" : "", + type: c.hasOwnProperty('isStage') ? 'background' : 'range' + } + if (o.end > timeline_end){ + timeline_end = o.end + } + return o; + }) + + + if (this.timeLine) { // destroy if exists + this.timeLine.destroy(); + } + + // Create a Timeline + this.timeLine = new Timeline(this.timelineContainer.nativeElement, data, groups + , { + min: timeline_start, + max: timeline_end, + clickToUse: true, + tooltip: { + followMouse: true + }, + margin: { + item: { + horizontal: -1 + } + }, + order: (a, b) => { + return b.start - a.start // inverser l'ordre + } + }); + + let that = this; + this.timeLine.on('select', function (props: any) { + let id = props.items[0]; + if (isNaN(+id)) { + that._router.navigate(['/session', 'api', id]); + } + }); + + if (timeline_end != +this.selectedQuery.end * 1000) { + this.timeLine.addCustomTime(+this.selectedQuery.end * 1000, "async"); + this.timeLine.setCustomTimeMarker("async", "async"); + } + + } + + selectedRequest(event:MouseEvent,row: any) { + if(row){ + if( event.ctrlKey){ + this._router.open(`#/session/api/${row}`,'_blank') + }else { + this._router.navigate(['/session', 'api', row]); + } + } + + } + + getElapsedTime(end: number, start: number,) { + // return (new Date(end * 1000).getTime() - new Date(start * 1000).getTime()) / 1000 + return end - start; + + } + + getRe(re: string) { + return this.UtilInstance.getRe(re); + } + + statusBorder(status: any) { + return this.UtilInstance.statusBorder(status); + } + + + getSessionDetailBorder(session: any) { + + if (session?.type == "api" || session?.type == "outcoming") + return this.UtilInstance.statusBorderCard(session.status) + if (session?.type == "main") + return this.UtilInstance.statusBorderCard(!!session.exception.message) + + } + + getSessionStatusTooltip(session: any) { + if (session?.type == "api" || session?.type == "outcoming") + return session?.status; + if (session?.type == "main") + return !session.exception.message ? "réussi" : "échoué"; + } + + + configDbactions(query: any) { + query.actions.forEach((db: any, i: number) => { + if (query.actions[i + 1]) { + let diffElapsed = new Date(db.end * 1000).getTime() - new Date(query.actions[i + 1].start * 1000).getTime(); + + if (diffElapsed != 0) { + query.actions.splice(i + 1, 0, { 'type': ' ', 'exception': { 'classname': null, 'message': null }, 'start': db.end, 'end': query.actions[i + 1].start }) + } + } + }); + } + + getSessionUrl(selectedSession: any) { + return this.UtilInstance.getSessionUrl(selectedSession); + } + + navigate(event:MouseEvent,targetType: string,extraParam?:string) { + let params: any[] = []; + switch (targetType) { + case "api": + params.push('dashboard', 'api', this.selectedQuery.name); + break; + case "app": + params.push('dashboard', 'app', this.selectedQuery.application.name) + break; + case "tree": + params.push('session/api', this.selectedQuery.id, 'tree') + break; + } + if(event.ctrlKey){ + this._router.open(`#/${params.join('/')}`,'_blank') + }else { + this._router.navigate(params, { + queryParams: { env: this.selectedQuery?.application?.env } + }); + } + } + + sortInnerArrayByDate(innerArray: any[]): any[] { + return innerArray.sort((a, b) => { + if (a.start > b.start) + return 1; + + if (a.start < b.start) + return -1; + + if (a.threadName && b.threadName) + return a.threadName.localeCompare(b.threadName) + + }); + } + + isQueryCompleted(query:any):boolean { + return query.actions.every((a:any) => !a.exception.classname && !a.exception.message); + } + + getCommand(commands:string[]):string{ + let command = "" + if(commands?.length == 1){ + command = `[${commands[0]}]` + }else if(commands?.length > 1) { + command = "[SQL]" + } + return command; + } + + ngOnDestroy() { + if (this.resizeSubscription) { + this.resizeSubscription.unsubscribe(); + } + if (this.paramsSubscription) { + this.paramsSubscription.unsubscribe(); + } + } + + + +} + +@Injectable() +export class EnvRouter { + + private _env: string; + + constructor(private router: Router) { } + + set env(env: string) { + this._env = env + } + + get events(): Observable{ + return this.router.events; + }; + + get url(): string { + return this.router.url; + } + + navigate(commands: any[], extras?: NavigationExtras): Promise { + if (!extras?.queryParams?.env) { + if (this._env) { + if (!extras) { + extras = {} + } + if (!extras.queryParams) { + extras.queryParams = {} + } + extras.queryParams.env = this._env; + } + } + else { + this.env = extras.queryParams.env; + } + return this.router.navigate(commands, extras); + // return Promise.resolve(true); + } + + open(url?: string | URL, target?: string, features?: string): WindowProxy | null{ + return window.open(url,target,features); + } + +} \ No newline at end of file diff --git a/src/app/views/session-detail/session-detail.component.html b/src/app/views/session-detail/session-detail.component.html index 24c202c..cdd9a73 100644 --- a/src/app/views/session-detail/session-detail.component.html +++ b/src/app/views/session-detail/session-detail.component.html @@ -207,8 +207,8 @@ - @@ -220,8 +220,12 @@ - BDD - {{element["schema"] || 'N/A'}} + BDD + + {{getCommand(element.commands)}} +
+ {{element["schema"] || 'N/A'}} +
diff --git a/src/app/views/session-detail/session-detail.component.scss b/src/app/views/session-detail/session-detail.component.scss index 45fcc6e..be9cebf 100644 --- a/src/app/views/session-detail/session-detail.component.scss +++ b/src/app/views/session-detail/session-detail.component.scss @@ -49,11 +49,10 @@ table { .progress { height: 20px; + display: flex; } .progress-bar { - display: flex; - flex-direction: column; justify-content: center; overflow: hidden; color: #fff; diff --git a/src/app/views/session-detail/session-detail.component.ts b/src/app/views/session-detail/session-detail.component.ts index f14ab4c..6f82573 100644 --- a/src/app/views/session-detail/session-detail.component.ts +++ b/src/app/views/session-detail/session-detail.component.ts @@ -4,7 +4,7 @@ import { MatTableDataSource } from '@angular/material/table'; import { ActivatedRoute, NavigationExtras, Router} from '@angular/router'; import { Observable, combineLatest} from "rxjs"; import { Timeline } from 'vis-timeline'; -import { OutcomingQuery, OutcomingRequest, RunnableStage } from 'src/app/shared/model/trace.model'; +import { ExceptionInfo, OutcomingQuery, OutcomingRequest, RunnableStage } from 'src/app/shared/model/trace.model'; import { Utils } from 'src/app/shared/util'; import { DatePipe, Location} from '@angular/common'; import { MatPaginator } from '@angular/material/paginator'; @@ -330,6 +330,20 @@ export class SessionDetailComponent implements AfterContentInit, OnDestroy { }); } + isQueryCompleted(query:any):boolean { + return query.actions.every((a:any) => !a.exception.classname && !a.exception.message); + } + + getCommand(commands:string[]):string{ + let command = "" + if(commands?.length == 1){ + command = `[${commands[0]}]` + }else if(commands?.length > 1) { + command = "[SQL]" + } + return command; + } + ngOnDestroy() { if (this.resizeSubscription) { this.resizeSubscription.unsubscribe(); @@ -338,12 +352,6 @@ export class SessionDetailComponent implements AfterContentInit, OnDestroy { this.paramsSubscription.unsubscribe(); } } - - - - - - } @Injectable() diff --git a/src/app/views/stats-database/stats-database.component.ts b/src/app/views/stats-database/stats-database.component.ts index be52339..fd00845 100644 --- a/src/app/views/stats-database/stats-database.component.ts +++ b/src/app/views/stats-database/stats-database.component.ts @@ -33,7 +33,7 @@ export class StatsDatabaseComponent implements OnInit { env: any; dbNameDataList: any[]; - schema: any; + db: any; dbNameListIsLoading: boolean = false dataIsLoading: boolean = false countOkKo: any[]; @@ -58,7 +58,7 @@ export class StatsDatabaseComponent implements OnInit { }).subscribe({ next: (v: { params: Params, queryParams: Params }) => { - this.schema = v.params.name; + this.db = v.params.name; this.env = v.queryParams.env || application.default_env; let start = v.queryParams.start || (application.dashboard.database.default_period || application.dashboard.default_period || makePeriod(6)).start.toISOString(); let end = v.queryParams.end || (application.dashboard.database.default_period || application.dashboard.default_period || makePeriod(6)).end.toISOString(); @@ -81,13 +81,13 @@ export class StatsDatabaseComponent implements OnInit { this.dbNameListIsLoading = true; this.serverFilterForm.controls.dbnameControl.reset(); this.serverFilterForm.controls.dbnameControl.disable(); - this._statsService.getSessionApi({ 'column.distinct': 'query.schema&query.parent=request.id&order=query.schema.asc', 'request.environement': this.env }).pipe(catchError(error => of(error))) + this._statsService.getSessionApi({ 'column.distinct': 'query.db&query.parent=request.id&order=query.db.asc', 'request.environement': this.env }).pipe(catchError(error => of(error))) .subscribe({ - next: (res: { schema: string }[]) => { - this.dbNameDataList = res.map((s: any) => s.schema) + next: (res: { db: string }[]) => { + this.dbNameDataList = res.map((s: any) => s.db) this.serverFilterForm.controls.dbnameControl.enable(); this.dbNameListIsLoading = false; - this.serverFilterForm.controls.dbnameControl.patchValue(this.schema) + this.serverFilterForm.controls.dbnameControl.patchValue(this.db) }, error: err => { this.dbNameListIsLoading = false; @@ -122,7 +122,7 @@ export class StatsDatabaseComponent implements OnInit { let start = this.serverFilterForm.getRawValue().dateRangePicker.start; let end = new Date(this.serverFilterForm.getRawValue().dateRangePicker.end); end.setDate(end.getDate() + 1); - this.requests = this.DB_REQUEST(this.schema, this.env, start, end) + this.requests = this.DB_REQUEST(this.db, this.env, start, end) Object.keys(this.requests).forEach(k => { this.requests[k].data = []; this.requests[k].isLoading = true; @@ -136,26 +136,26 @@ export class StatsDatabaseComponent implements OnInit { } - DB_REQUEST = (schema: string, env: string, start: Date, end: Date) => { + DB_REQUEST = (db: string, env: string, start: Date, end: Date) => { let now = new Date(); var groupedBy = periodManagement(start, end); return { - dbInfo: { observable: this._statsService.getSessionApi({ 'column.distinct': 'query.host,query.schema,query.driver,query.db_name,query.db_version', 'query.parent': 'request.id', "request.environement": env, "query.schema": schema, 'query.start.ge': start.toISOString(), 'query.start.lt': end.toISOString(), 'request.start.ge': start.toISOString(), 'request.start.lt': end.toISOString() }) }, - countOkKoSlowest: { observable: this._statsService.getSessionApi({ 'column': 'query.count_db_error:countErrorServer,query.count:count,query.count_slowest:countSlowest,query.start.date:date', 'query.parent': 'request.id', "request.environement": env, "query.schema": schema, 'request.start.ge': new Date(now.getFullYear(), now.getMonth(), now.getDate() - 6).toISOString(), 'request.start.lt': now.toISOString(), 'query.start.ge': new Date(now.getFullYear(), now.getMonth(), now.getDate() - 7).toISOString(), 'query.start.lt': now.toISOString()}) }, - countMinMaxAvg: { observable: this._statsService.getSessionApi({ 'column': `query.count_db_succes:countDbSucces,query.elapsedtime.max:max,query.elapsedtime.avg:avg,query.start.${groupedBy}:date,query.start.year:year`, 'query.parent': 'request.id', "request.environement": env, "query.schema": schema, 'request.start.ge': start.toISOString(), 'request.start.lt': end.toISOString(), 'query.start.ge': start.toISOString(), 'query.start.lt': end.toISOString(), 'order': `query.start.year.asc,query.start.${groupedBy}.asc` }).pipe(map(((r: any[]) => { + dbInfo: { observable: this._statsService.getSessionApi({ 'column.distinct': 'query.host,query.db,query.driver,query.db_name,query.db_version', 'query.parent': 'request.id', "request.environement": env, "query.db": db, 'query.start.ge': start.toISOString(), 'query.start.lt': end.toISOString(), 'request.start.ge': start.toISOString(), 'request.start.lt': end.toISOString() }) }, + countOkKoSlowest: { observable: this._statsService.getSessionApi({ 'column': 'query.count_db_error:countErrorServer,query.count:count,query.count_slowest:countSlowest,query.start.date:date', 'query.parent': 'request.id', "request.environement": env, "query.db": db, 'request.start.ge': new Date(now.getFullYear(), now.getMonth(), now.getDate() - 6).toISOString(), 'request.start.lt': now.toISOString(), 'query.start.ge': new Date(now.getFullYear(), now.getMonth(), now.getDate() - 7).toISOString(), 'query.start.lt': now.toISOString()}) }, + countMinMaxAvg: { observable: this._statsService.getSessionApi({ 'column': `query.count_db_succes:countDbSucces,query.elapsedtime.max:max,query.elapsedtime.avg:avg,query.start.${groupedBy}:date,query.start.year:year`, 'query.parent': 'request.id', "request.environement": env, "query.db": db, 'request.start.ge': start.toISOString(), 'request.start.lt': end.toISOString(), 'query.start.ge': start.toISOString(), 'query.start.lt': end.toISOString(), 'order': `query.start.year.asc,query.start.${groupedBy}.asc` }).pipe(map(((r: any[]) => { formatters[groupedBy](r, this._datePipe); return r; }))) }, countRepartitionBySpeedBar: { - observable: this._statsService.getSessionApi({ 'column': `query.count_slowest:elapsedTimeSlowest,query.count_slow:elapsedTimeSlow,query.count_medium:elapsedTimeMedium,query.count_fast:elapsedTimeFast,query.count_fastest:elapsedTimeFastest,query.start.${groupedBy}:date,query.start.year:year`, 'query.parent': 'request.id', "request.environement": env, "query.schema": schema, 'request.start.ge': start.toISOString(), 'request.start.lt': end.toISOString(), 'query.start.ge': start.toISOString(), 'query.start.lt': end.toISOString(), 'order': `query.start.year.asc,query.start.${groupedBy}.asc` }).pipe(map(((r: any[]) => { + observable: this._statsService.getSessionApi({ 'column': `query.count_slowest:elapsedTimeSlowest,query.count_slow:elapsedTimeSlow,query.count_medium:elapsedTimeMedium,query.count_fast:elapsedTimeFast,query.count_fastest:elapsedTimeFastest,query.start.${groupedBy}:date,query.start.year:year`, 'query.parent': 'request.id', "request.environement": env, "query.db": db, 'request.start.ge': start.toISOString(), 'request.start.lt': end.toISOString(), 'query.start.ge': start.toISOString(), 'query.start.lt': end.toISOString(), 'order': `query.start.year.asc,query.start.${groupedBy}.asc` }).pipe(map(((r: any[]) => { formatters[groupedBy](r, this._datePipe); return r; }))) }, - countRepartitionBySpeedPie: { observable: this._statsService.getSessionApi({ 'column': 'query.count_slowest:elapsedTimeSlowest,query.count_slow:elapsedTimeSlow,query.count_medium:elapsedTimeMedium,query.count_fast:elapsedTimeFast,query.count_fastest:elapsedTimeFastest', 'query.parent': 'request.id', "request.environement": env, "query.schema": schema, 'request.start.ge': start.toISOString(), 'request.start.lt': end.toISOString(), 'query.start.ge': start.toISOString(), 'query.start.lt': end.toISOString()}) }, - exceptions: { observable: this._statsService.getSessionApi({ 'column': 'count,dbaction.err_type.coalesce(null),dbaction.err_msg.coalesce(null)', 'dbaction.err_type.not': 'null', 'dbaction.err_msg.not': 'null', 'dbaction.parent': 'query.id', 'query.parent': 'request.id', 'order': 'count.desc', "request.environement": env, "query.schema": schema, 'request.start.ge': start.toISOString(), 'request.start.lt': end.toISOString(), 'query.start.ge': start.toISOString(), 'query.start.lt': end.toISOString() }).pipe(map((d: any) => d.slice(0, 5))) }, - usersInfo: { observable: this._statsService.getSessionApi({ 'column': 'count:countRows,query.user', 'query.parent': 'request.id', "request.environement": env, "query.schema": schema, 'request.start.ge': start.toISOString(), 'request.start.lt': end.toISOString(), 'query.start.ge': start.toISOString(), 'query.start.lt': end.toISOString() }) } + countRepartitionBySpeedPie: { observable: this._statsService.getSessionApi({ 'column': 'query.count_slowest:elapsedTimeSlowest,query.count_slow:elapsedTimeSlow,query.count_medium:elapsedTimeMedium,query.count_fast:elapsedTimeFast,query.count_fastest:elapsedTimeFastest', 'query.parent': 'request.id', "request.environement": env, "query.db": db, 'request.start.ge': start.toISOString(), 'request.start.lt': end.toISOString(), 'query.start.ge': start.toISOString(), 'query.start.lt': end.toISOString()}) }, + exceptions: { observable: this._statsService.getSessionApi({ 'column': 'count,dbaction.err_type.coalesce(null),dbaction.err_msg.coalesce(null)', 'dbaction.err_type.not': 'null', 'dbaction.err_msg.not': 'null', 'dbaction.parent': 'query.id', 'query.parent': 'request.id', 'order': 'count.desc', "request.environement": env, "query.db": db, 'request.start.ge': start.toISOString(), 'request.start.lt': end.toISOString(), 'query.start.ge': start.toISOString(), 'query.start.lt': end.toISOString() }).pipe(map((d: any) => d.slice(0, 5))) }, + usersInfo: { observable: this._statsService.getSessionApi({ 'column': 'count:countRows,query.user', 'query.parent': 'request.id', "request.environement": env, "query.db": db, 'request.start.ge': start.toISOString(), 'request.start.lt': end.toISOString(), 'query.start.ge': start.toISOString(), 'query.start.lt': end.toISOString() }) } } } diff --git a/src/app/views/views.module.ts b/src/app/views/views.module.ts index e2cd096..ac9e15a 100644 --- a/src/app/views/views.module.ts +++ b/src/app/views/views.module.ts @@ -19,6 +19,7 @@ import { StatsApiComponent } from './stats-api/stats-api.component'; import { StatsUserComponent } from './stats-user/stats-user.component'; import { ExceptionTableComponent } from '../shared/components/stats/exception-table/exception-table.component'; import { ChartComponent } from '@oneteme/jquery-apexcharts'; +import { DbRequestDetailComponent } from './db-request-detail/db-request-detail.component'; @NgModule({ imports: [ @@ -44,7 +45,8 @@ import { ChartComponent } from '@oneteme/jquery-apexcharts'; DependentsTableComponent, DependenciesTableComponent, ExceptionTableComponent, - SessionTableComponent + SessionTableComponent, + DbRequestDetailComponent ] }) export class ViewsModule { } From d3d3dc2bcba13cef5e8d28d63bcc554c1b163a42 Mon Sep 17 00:00:00 2001 From: YoussefDahi Date: Fri, 24 May 2024 10:41:34 +0200 Subject: [PATCH 003/126] model update adjustement #2 / added the ability to look up session parent / remove dbaction progress bar from session-detail component --- src/app/shared/services/stats.service.ts | 4 +- src/app/shared/services/trace.service.ts | 17 ++- src/app/shared/util.ts | 16 +-- src/app/views/constants.ts | 54 ++++---- .../session-detail.component.html | 34 ++--- .../session-detail.component.scss | 25 ++-- .../session-detail.component.ts | 131 +++++++++++------- .../views/stats-api/stats-api.component.ts | 4 +- .../views/stats-app/stats-app.component.ts | 4 +- .../stats-database.component.html | 2 +- .../stats-database.component.ts | 16 +-- 11 files changed, 168 insertions(+), 139 deletions(-) diff --git a/src/app/shared/services/stats.service.ts b/src/app/shared/services/stats.service.ts index 27f196b..6872249 100644 --- a/src/app/shared/services/stats.service.ts +++ b/src/app/shared/services/stats.service.ts @@ -13,12 +13,12 @@ export class StatsService { } getSessionApi(params: any) { - let url = `${localStorage.getItem('server')}/stat/incoming/request`; + let url = `${localStorage.getItem('server')}/stat/apisession`; return this.http.get(url, { params: params }); } getSessionMain(params: any) { - let url = `${localStorage.getItem('server')}/stat/session`; + let url = `${localStorage.getItem('server')}/stat/mainsession`; return this.http.get(url, { params: params }); } } \ No newline at end of file diff --git a/src/app/shared/services/trace.service.ts b/src/app/shared/services/trace.service.ts index 3636946..0e59c99 100644 --- a/src/app/shared/services/trace.service.ts +++ b/src/app/shared/services/trace.service.ts @@ -1,10 +1,11 @@ -import { HttpClient } from "@angular/common/http"; +import { HttpClient, HttpErrorResponse } from "@angular/common/http"; import { Injectable } from "@angular/core"; +import { catchError, throwError } from "rxjs"; import { environment } from "src/environments/environment"; @Injectable({ providedIn: 'root' }) export class TraceService { - readonly INCOMING_REQUEST_URL = `${localStorage.getItem('server')}/trace/session/request`; + readonly INCOMING_REQUEST_URL = `${localStorage.getItem('server')}/trace/session/api`; readonly MAIN_REQUEST_URL = `${localStorage.getItem('server')}/trace/session/main`; constructor(private http: HttpClient) { @@ -27,10 +28,18 @@ export class TraceService { } getTreeRequestById(id: string) { - return this.http.get(`${localStorage.getItem('server')}/trace/session/request/${id}/tree`); + return this.http.get(`${localStorage.getItem('server')}/trace/session/api/${id}/tree`); } getDbRequestById(id: number){ - return this.http.get(`${localStorage.getItem('server')}/trace/db/request/${id}`); + return this.http.get(`${localStorage.getItem('server')}/trace/db/${id}`); + } + + getSessionParentByChildId(id: string){ + return this.http.get(`${localStorage.getItem('server')}/trace/session/api/${id}/parent`).pipe(catchError(this.handleError)) + } + + private handleError( error: HttpErrorResponse){ + return throwError(()=>error) } } \ No newline at end of file diff --git a/src/app/shared/util.ts b/src/app/shared/util.ts index 905193a..6e86375 100644 --- a/src/app/shared/util.ts +++ b/src/app/shared/util.ts @@ -56,18 +56,18 @@ export class Utils { return 'red'; } - statusBorder(param: any): { [key: string]: string } { - if (typeof param == "boolean") { - return { 'box-shadow': '4px 0px 0px 0px ' + this.getStateColorBool(param) + ' inset' }; + statusBorder(completed: any): { [key: string]: string } { + if (typeof completed == "boolean") { + return { 'box-shadow': '4px 0px 0px 0px ' + this.getStateColorBool(completed) + ' inset' }; } - return { 'box-shadow': '4px 0px 0px 0px ' + this.getStateColor(param) + ' inset' }; + return { 'box-shadow': '4px 0px 0px 0px ' + this.getStateColor(completed) + ' inset' }; } - statusBorderCard(param: any): { [key: string]: string } { - if (typeof param == "boolean") { - return { 'border-left': '4px solid ' + this.getStateColorBool(param) }; + statusBorderCard(failed: any): { [key: string]: string } { + if (typeof failed == "boolean") { + return { 'border-left': '4px solid ' + this.getStateColorBool(!failed) }; } - return { 'border-left': '4px solid ' + this.getStateColor(param) }; + return { 'border-left': '4px solid ' + this.getStateColor(failed) }; } convertSeconds = (seconds: number): string => { diff --git a/src/app/views/constants.ts b/src/app/views/constants.ts index f854197..9b1cb8a 100644 --- a/src/app/views/constants.ts +++ b/src/app/views/constants.ts @@ -361,37 +361,37 @@ export class FilterConstants { { key: 'status', label: 'Status', type: 'select', row: 3, col: 1, options: [{ status: '200' }, { status: '201' }, { status: '202' }, { status: '400' }, { status: '401' }, { status: '403' }, { status: '404' }, { status: '405' }, { status: '409' }, { status: '415' }, { status: '500' }, { status: '503' }], op: Operation.like }, { key: 'method', label: 'Method', type: 'select', width: 20, row: 1, col: 1, options: [{ method: 'GET' }, { method: 'PUT' }, { method: 'POST' }, { method: 'DELETE' }, { method: 'OPTIONS' }], op: Operation.eq }, { key: 'path', label: 'Path', type: 'input', row: 1, col: 2, op: Operation.like }, - { key: 'api_name', label: 'Nom API', type: 'select', row: 3, col: 2, endpoint: "/stat/incoming/request", query: { 'column.distinct': 'api_name.coalesce(null):api_name', 'api_name.not': 'null', 'order': 'api_name.coalesce(null).asc' }, op: Operation.eq }, - { key: 'user', label: 'Utilisateur', type: 'select', row: 3, col: 3, endpoint: "/stat/incoming/request", query: { 'column.distinct': 'user.coalesce(null)', 'user.not': 'null', 'order': 'user.coalesce(null).asc' }, op: Operation.eq } - // new Filter("err_type", "Exception", 'select', 50, "/stat/incoming/request", null, null, { 'column.distinct': 'err_type:err_type', 'order': 'err_type.asc' }), + { key: 'api_name', label: 'Nom API', type: 'select', row: 3, col: 2, endpoint: "/stat/apisession", query: { 'column.distinct': 'api_name.coalesce(null):api_name', 'api_name.not': 'null', 'order': 'api_name.coalesce(null).asc' }, op: Operation.eq }, + { key: 'user', label: 'Utilisateur', type: 'select', row: 3, col: 3, endpoint: "/stat/apisession", query: { 'column.distinct': 'user.coalesce(null)', 'user.not': 'null', 'order': 'user.coalesce(null).asc' }, op: Operation.eq } + // new Filter("err_type", "Exception", 'select', 50, "/stat/apisession", null, null, { 'column.distinct': 'err_type:err_type', 'order': 'err_type.asc' }), // new Filter("address", "adresse", 'input', 50), - // new Filter("os", "OS", 'select', 50, "/stat/incoming/request", null, null, { 'column.distinct': 'os', 'order': 'os.asc' }), - // new Filter("re", "RE", 'select', 50, "/stat/incoming/request", null, null, { 'column.distinct': 're', 'order': 're.asc' }), - // new Filter("auth", "Authentification scheme", 'select', 50, "/stat/incoming/request", null, null, { 'column.distinct': 'auth', 'order': 'auth.asc' }), - // new Filter("host", "Hôte", 'select', 50, "/stat/incoming/request", null, null, { 'column.distinct': 'host', 'order': 'host.asc' }), + // new Filter("os", "OS", 'select', 50, "/stat/apisession", null, null, { 'column.distinct': 'os', 'order': 'os.asc' }), + // new Filter("re", "RE", 'select', 50, "/stat/apisession", null, null, { 'column.distinct': 're', 'order': 're.asc' }), + // new Filter("auth", "Authentification scheme", 'select', 50, "/stat/apisession", null, null, { 'column.distinct': 'auth', 'order': 'auth.asc' }), + // new Filter("host", "Hôte", 'select', 50, "/stat/apisession", null, null, { 'column.distinct': 'host', 'order': 'host.asc' }), // new Filter("protocol", "Protocole", 'select', 50, null,null, [{ protocol: 'HTTPS' }, { protocol: 'HTTP' }]), ] static readonly SESSION_MAIN: Filter[] = [ - { key: 'name', label: 'Serveur', type: 'select', row: 2, col: 1, endpoint: '/stat/session', query: { 'column.distinct': 'session.name.coalesce(null)', 'session.name.not': 'null', 'order': 'session.name.coalesce(null).asc' }, op: Operation.eq }, + { key: 'name', label: 'Serveur', type: 'select', row: 2, col: 1, endpoint: '/stat/mainsession', query: { 'column.distinct': 'session.name.coalesce(null)', 'session.name.not': 'null', 'order': 'session.name.coalesce(null).asc' }, op: Operation.eq }, { key: 'location', label: 'Chemin', type: 'input', row: 1, col: 1, op: Operation.like }, - { key: 'user', label: 'Utilisateur', type: 'select', row: 2, col: 2, endpoint: '/stat/session', query: { 'column.distinct': 'user.coalesce(null)', 'user.not': 'null', 'order': 'user.coalesce(null).asc' }, op: Operation.eq } + { key: 'user', label: 'Utilisateur', type: 'select', row: 2, col: 2, endpoint: '/stat/mainsession', query: { 'column.distinct': 'user.coalesce(null)', 'user.not': 'null', 'order': 'user.coalesce(null).asc' }, op: Operation.eq } - // new Filter("err_type", "Exception", 'select', 50, "/stat/session", null, null, { 'column.distinct': 'err_type:err_type', 'order': 'err_type.asc' }), - // new Filter("os", "OS", 'select', 50, "/stat/session", null, null, { 'column.distinct': 'os', 'order': 'os.asc' }), - //new Filter("re", "RE", 'select', 50, "/stat/session", null, null, { 'column.distinct': 're', 'order': 're.asc' }), + // new Filter("err_type", "Exception", 'select', 50, "/stat/mainsession", null, null, { 'column.distinct': 'err_type:err_type', 'order': 'err_type.asc' }), + // new Filter("os", "OS", 'select', 50, "/stat/mainsession", null, null, { 'column.distinct': 'os', 'order': 'os.asc' }), + //new Filter("re", "RE", 'select', 50, "/stat/mainsession", null, null, { 'column.distinct': 're', 'order': 're.asc' }), ] static readonly STATS_API: Filter[] = [ { key: 'query', label: 'Query params', type: 'input', row: 1, col: 2, op: Operation.like }, { key: 'method', label: 'Method', type: 'select', width: 20, row: 1, col: 1, options: [{ method: 'GET' }, { method: 'PUT' }, { method: 'POST' }, { method: 'DELETE' }, { method: 'OPTIONS' }], op: Operation.eq }, { key: 'status', label: 'Status', type: 'select', row: 3, col: 1, options: [{ status: '200' }, { status: '201' }, { status: '202' }, { status: '400' }, { status: '401' }, { status: '403' }, { status: '404' }, { status: '405' }, { status: '409' }, { status: '415' }, { status: '500' }, { status: '503' }], op: Operation.eq }, - { key: 'user', label: 'Utilisateur', type: 'select', row: 3, col: 2, endpoint: '/stat/incoming/request', query: { 'column.distinct': 'user.coalesce(null)', 'user.not': 'null', 'order': 'user.coalesce(null).asc' }, op: Operation.eq }, + { key: 'user', label: 'Utilisateur', type: 'select', row: 3, col: 2, endpoint: '/stat/apisession', query: { 'column.distinct': 'user.coalesce(null)', 'user.not': 'null', 'order': 'user.coalesce(null).asc' }, op: Operation.eq }, { key: 'path', label: 'Path', type: 'input', row: 2, col: 1, op: Operation.like } - //new Filter("os", "OS", 'select', 50, "/stat/incoming/request", null, null, { 'column.distinct': 'os', 'order': 'os.asc' }), - //new Filter("re", "RE", 'select', 50, "/stat/incoming/request", null, null, { 'column.distinct': 're', 'order': 're.asc' }), - //new Filter("err_type", "Exception", 'select', 50, "/stat/incoming/request", null, null, { 'column.distinct': 'err_type:err_type', 'order': 'err_type.asc' }), + //new Filter("os", "OS", 'select', 50, "/stat/apisession", null, null, { 'column.distinct': 'os', 'order': 'os.asc' }), + //new Filter("re", "RE", 'select', 50, "/stat/apisession", null, null, { 'column.distinct': 're', 'order': 're.asc' }), + //new Filter("err_type", "Exception", 'select', 50, "/stat/apisession", null, null, { 'column.distinct': 'err_type:err_type', 'order': 'err_type.asc' }), ] @@ -399,12 +399,12 @@ export class FilterConstants { { key: 'query', label: 'Query params', type: 'input', row: 1, col: 2, op: Operation.like }, { key: 'method', label: 'Method', type: 'select', width: 20, row: 1, col: 1, options: [{ method: 'GET' }, { method: 'PUT' }, { method: 'POST' }, { method: 'DELETE' }, { method: 'OPTIONS' }], op: Operation.eq }, { key: 'status', label: 'Status', type: 'select', row: 3, col: 1, options: [{ status: '200' }, { status: '201' }, { status: '202' }, { status: '400' }, { status: '401' }, { status: '403' }, { status: '404' }, { status: '405' }, { status: '409' }, { status: '415' }, { status: '500' }, { status: '503' }], op: Operation.eq }, - { key: 'user', label: 'Utilisateur', type: 'select', row: 3, col: 2, endpoint: '/stat/incoming/request', query: { 'column.distinct': 'user.coalesce(null)', 'user.not': 'null', 'order': 'user.coalesce(null).asc' }, op: Operation.eq }, + { key: 'user', label: 'Utilisateur', type: 'select', row: 3, col: 2, endpoint: '/stat/apisession', query: { 'column.distinct': 'user.coalesce(null)', 'user.not': 'null', 'order': 'user.coalesce(null).asc' }, op: Operation.eq }, { key: 'path', label: 'Path', type: 'input', row: 2, col: 1, op: Operation.like } - //new Filter("os", "OS", 'select', 50, "/stat/incoming/request", null, null, { 'column.distinct': 'os', 'order': 'os.asc' }), - //new Filter("re", "RE", 'select', 50, "/stat/incoming/request", null, null, { 'column.distinct': 're', 'order': 're.asc' }), - //new Filter("err_type", "Exception", 'select', 50, "/stat/incoming/request", null, null, { 'column.distinct': 'err_type:err_type', 'order': 'err_type.asc' }), + //new Filter("os", "OS", 'select', 50, "/stat/apisession", null, null, { 'column.distinct': 'os', 'order': 'os.asc' }), + //new Filter("re", "RE", 'select', 50, "/stat/apisession", null, null, { 'column.distinct': 're', 'order': 're.asc' }), + //new Filter("err_type", "Exception", 'select', 50, "/stat/apisession", null, null, { 'column.distinct': 'err_type:err_type', 'order': 'err_type.asc' }), ] @@ -420,16 +420,16 @@ export class FilterConstants { // new Filter("path", "Path", 'input', 100, null, null, null, null, null, Operation.like), - //new Filter("os", "OS", 'select', 50, "/stat/incoming/request", null, null, { 'column.distinct': 'os', 'order': 'os.asc' }), - //new Filter("re", "RE", 'select', 50, "/stat/incoming/request", null, null, { 'column.distinct': 're', 'order': 're.asc' }), - //new Filter("err_type", "Exception", 'select', 50, "/stat/incoming/request", null, null, { 'column.distinct': 'err_type:err_type', 'order': 'err_type.asc' }), + //new Filter("os", "OS", 'select', 50, "/stat/apisession", null, null, { 'column.distinct': 'os', 'order': 'os.asc' }), + //new Filter("re", "RE", 'select', 50, "/stat/apisession", null, null, { 'column.distinct': 're', 'order': 're.asc' }), + //new Filter("err_type", "Exception", 'select', 50, "/stat/apisession", null, null, { 'column.distinct': 'err_type:err_type', 'order': 'err_type.asc' }), ] static readonly STATS_DB: Filter[] = [ - // new Filter("schema", "Base de donnée", 'select', 50, "/stat/incoming/request", null, null, { 'column.distinct': 'query.schema', 'query.parent': 'request.id', 'order': 'query.schema.asc' }), - // new Filter("user", "Utilisateur", 'select', 50, "/stat/incoming/request",'query.', null, { 'column.distinct': 'query.user', 'query.parent': 'request.id', 'order': 'query.user.asc' }), - // new Filter("err_type", "Exception", 'select', 50, "/stat/incoming/request", null, null, { 'column.distinct': 'dbaction.err_type:err_type','dbaction.parent': 'query.id', 'query.parent': 'request.id', 'order': 'dbaction.err_type.asc' }), - // new Filter("db_name", "SGBD", 'select', 50, "/stat/incoming/request", "query.", null, { 'column.distinct': 'query.db_name:db_name', 'query.parent': 'request.id', 'order': 'query.db_name.asc' }), + // new Filter("schema", "Base de donnée", 'select', 50, "/stat/apisession", null, null, { 'column.distinct': 'dbquery.schema', 'dbquery.parent': 'apisession.id', 'order': 'dbquery.schema.asc' }), + // new Filter("user", "Utilisateur", 'select', 50, "/stat/apisession",'dbquery.', null, { 'column.distinct': 'dbquery.user', 'dbquery.parent': 'apisession.id', 'order': 'dbquery.user.asc' }), + // new Filter("err_type", "Exception", 'select', 50, "/stat/apisession", null, null, { 'column.distinct': 'dbaction.err_type:err_type','dbaction.parent': 'dbquery.id', 'dbquery.parent': 'apisession.id', 'order': 'dbaction.err_type.asc' }), + // new Filter("db_name", "SGBD", 'select', 50, "/stat/apisession", "dbquery.", null, { 'column.distinct': 'dbquery.db_name:db_name', 'dbquery.parent': 'apisession.id', 'order': 'dbquery.db_name.asc' }), ] } diff --git a/src/app/views/session-detail/session-detail.component.html b/src/app/views/session-detail/session-detail.component.html index cdd9a73..6d632a1 100644 --- a/src/app/views/session-detail/session-detail.component.html +++ b/src/app/views/session-detail/session-detail.component.html @@ -1,19 +1,21 @@
settings_suggest {{selectedSession?.type=='api' || selectedSession?.type =='outcoming' ? (selectedSession?.name|| 'N/A') : '[' + selectedSession?.launchMode + '] ' + selectedSession?.name || 'N/A'}}
+ @@ -33,7 +35,7 @@ style="display: flex; gap: 0.5em; color: red; font-weight: 500; margin-top: 0.5em;" *ngIf="selectedSession?.exception?.classname || selectedSession?.exception?.message " [matTooltip]="selectedSession?.exception.classname" TooltipPosition="below"> - warning{{selectedSession?.exception.message || selectedSession?.exception?.classname}} + warning{{selectedSession?.exception.message || selectedSession?.exception?.classname}}
@@ -62,13 +64,14 @@ {{selectedSession?.outDataSize}}o en {{ getElapsedTime(selectedSession?.end, selectedSession?.start) | number :'1.2-3'}}s + {{selectedSession?.status}} storage {{selectedSession?.application?.name}} @@ -155,7 +158,7 @@
- Date de début + Début
{{ (element.start*1000 |date:'dd/MM/yyyy')}} @@ -207,10 +210,9 @@ - - @@ -250,22 +252,6 @@ - - Détails - -
-
- - {{db.type}} -
-
- -
- diff --git a/src/app/views/session-detail/session-detail.component.scss b/src/app/views/session-detail/session-detail.component.scss index be9cebf..f9fa6e9 100644 --- a/src/app/views/session-detail/session-detail.component.scss +++ b/src/app/views/session-detail/session-detail.component.scss @@ -47,19 +47,6 @@ table { background-color: red !important; } -.progress { - height: 20px; - display: flex; -} - -.progress-bar { - justify-content: center; - overflow: hidden; - color: #fff; - text-align: center; - white-space: nowrap; -} - .mat-mdc-row .mat-mdc-cell { cursor: pointer; } @@ -75,4 +62,14 @@ table { .url { color: blue; text-decoration: solid; -} \ No newline at end of file +} + +.badge { + color: white; + padding: 0px 10px; + text-align: center; + border-radius: 12px; + font-size: 0.8em; + gap: 0.5em +} + \ No newline at end of file diff --git a/src/app/views/session-detail/session-detail.component.ts b/src/app/views/session-detail/session-detail.component.ts index 6f82573..473127d 100644 --- a/src/app/views/session-detail/session-detail.component.ts +++ b/src/app/views/session-detail/session-detail.component.ts @@ -2,7 +2,7 @@ import { AfterContentInit, Component, ElementRef, Injectable, NgZone, OnDestroy, import { MatDialog } from '@angular/material/dialog'; import { MatTableDataSource } from '@angular/material/table'; import { ActivatedRoute, NavigationExtras, Router} from '@angular/router'; -import { Observable, combineLatest} from "rxjs"; +import { Observable, Subscription, combineLatest} from "rxjs"; import { Timeline } from 'vis-timeline'; import { ExceptionInfo, OutcomingQuery, OutcomingRequest, RunnableStage } from 'src/app/shared/model/trace.model'; import { Utils } from 'src/app/shared/util'; @@ -12,7 +12,7 @@ import { MatSort } from '@angular/material/sort'; import { TraceService } from 'src/app/shared/services/trace.service'; import { application } from 'src/environments/environment'; - +type sessionType = 'main' | 'api'; export interface UserData { id: string; name: string; @@ -29,11 +29,13 @@ export class SessionDetailComponent implements AfterContentInit, OnDestroy { UtilInstance: Utils = new Utils(); outcomingRequestDisplayedColumns: string[] = ['Status', 'host', 'path', 'start', 'duree']; - outcomingQueryDisplayedColumns: string[] = ['Status', 'host', 'schema', 'start', 'duree', 'db'] + outcomingQueryDisplayedColumns: string[] = ['Status', 'host', 'schema', 'start', 'duree']; outcomingRequestdataSource: MatTableDataSource = new MatTableDataSource(); outcomingQuerydataSource: MatTableDataSource; selectedSession: any // IncomingRequest | Mainrequest | OutcomingRequest; selectedSessionType: string; + sessionDetailSubscription: Observable; + sessionParent: {id : string, type : sessionType}; outcomingRequestList: any; outcomingQueryList: any; isComplete: boolean = true; @@ -69,9 +71,18 @@ export class SessionDetailComponent implements AfterContentInit, OnDestroy { this._activatedRoute.queryParams ]).subscribe({ next: ([params, queryParams]) => { + this.env = queryParams.env || application.default_env; this.selectedSessionType = params.type; + switch(this.selectedSessionType){ + case "main": + this.sessionDetailSubscription = this._traceService.getMainRequestById(params.id); + break; + case "api": + this.sessionDetailSubscription = this._traceService.getIncomingRequestById(params.id); + break; + default : + } this.getSessionById(params.id); - this.env = queryParams.env || application.default_env; this._location.replaceState(`${this._router.url.split('?')[0]}?env=${this.env}`) } }); @@ -92,48 +103,61 @@ export class SessionDetailComponent implements AfterContentInit, OnDestroy { getSessionById(id: string) { this.isLoading = true; - (this.selectedSessionType == 'main' ? this._traceService.getMainRequestById(id) : this._traceService.getIncomingRequestById(id)).subscribe({ - next: (d: any) => { - this.selectedSession = d; - if (this.selectedSession) { - this.selectedSession.type = this.selectedSessionType; - - this.outcomingRequestList = this.selectedSession.requests; - this.outcomingRequestdataSource = new MatTableDataSource(this.outcomingRequestList); - setTimeout(() => { this.outcomingRequestdataSource.paginator = this.outcomingRequestPaginator }); - setTimeout(() => { this.outcomingRequestdataSource.sort = this.outcomingRequestSort }); - this.outcomingRequestdataSource.sortingDataAccessor = (row: any, columnName: string) => { - if (columnName == "host") return row["host"] + ":" + row["port"] as string; - if (columnName == "start") return row['start'] as string; - if (columnName == "duree") return (row["end"] - row["start"]); - var columnValue = row[columnName as keyof any] as string; - return columnValue; - } - this.outcomingQueryList = this.selectedSession.queries - this.outcomingQuerydataSource = new MatTableDataSource(this.outcomingQueryList); - setTimeout(() => { this.outcomingQuerydataSource.paginator = this.outcomingQueryPaginator }); - setTimeout(() => { this.outcomingQuerydataSource.sort = this.outcomingQuerySort }); - this.outcomingQuerydataSource.sortingDataAccessor = (row: any, columnName: string) => { - if (columnName == "duree") return (row["end"] - row["start"]) - var columnValue = row[columnName as keyof any] as string; - return columnValue; - } - - this.groupQueriesBySchema(); - this.configDbactions(this.selectedSession) - - this.visjs(); - this.isLoading = false; - this.isComplete = true; - } else { - this.isLoading = false; - this.isComplete= false; - // navigate to tab incoming + this.sessionDetailSubscription.subscribe({ + next: (d: any) => { + this.selectedSession = d; + if (this.selectedSession) { + this.selectedSession.type = this.selectedSessionType; + + // Api request list + this.outcomingRequestList = this.selectedSession.requests; + this.outcomingRequestdataSource = new MatTableDataSource(this.outcomingRequestList); + setTimeout(() => { this.outcomingRequestdataSource.paginator = this.outcomingRequestPaginator }); + setTimeout(() => { this.outcomingRequestdataSource.sort = this.outcomingRequestSort }); + this.outcomingRequestdataSource.sortingDataAccessor = (row: any, columnName: string) => { + if (columnName == "host") return row["host"] + ":" + row["port"] as string; + if (columnName == "start") return row['start'] as string; + if (columnName == "duree") return (row["end"] - row["start"]); + var columnValue = row[columnName as keyof any] as string; + return columnValue; + } + + // DB request list + this.outcomingQueryList = this.selectedSession.queries + this.outcomingQuerydataSource = new MatTableDataSource(this.outcomingQueryList); + setTimeout(() => { this.outcomingQuerydataSource.paginator = this.outcomingQueryPaginator }); + setTimeout(() => { this.outcomingQuerydataSource.sort = this.outcomingQuerySort }); + this.outcomingQuerydataSource.sortingDataAccessor = (row: any, columnName: string) => { + if (columnName == "duree") return (row["end"] - row["start"]) + var columnValue = row[columnName as keyof any] as string; + return columnValue; } - }, - error: err => { + + this.groupQueriesBySchema(); + + // Timeline + this.visjs(); + + // Check if parent exist + this.sessionParent = null; + this._traceService.getSessionParentByChildId(id).subscribe( { + next : (data: {id : string, type : sessionType}) =>{ + this.sessionParent = data; + console.log(this.sessionParent) + }, + error : err => console.log(err) + }) + this.isLoading = false; + this.isComplete = true; + } else { this.isLoading = false; + this.isComplete= false; + // navigate to tab incoming } + }, + error: err => { + this.isLoading = false; + } }); } @@ -222,12 +246,23 @@ export class SessionDetailComponent implements AfterContentInit, OnDestroy { selectedRequest(event:MouseEvent,row: any) { if(row){ if( event.ctrlKey){ - this._router.open(`#/session/api/${row}`,'_blank') + this._router.open(`#/session/api/${row}`,'_blank',) + }else { + this._router.navigate(['/session', 'api', row],{queryParams:{env:this.env}}); // TODO remove env FIX BUG + } + } + } + + selectedQuery(event: MouseEvent, query:any){ // TODO finish this + if(query){ + if( event.ctrlKey){ + this._router.open(`#/session/api/${this.selectedSession.id}/db/`,'_blank',) }else { - this._router.navigate(['/session', 'api', row]); + this._router.navigate(['/session', 'api', this.selectedSession.id, 'db'],{ + + }); } } - } getElapsedTime(end: number, start: number,) { @@ -306,12 +341,14 @@ export class SessionDetailComponent implements AfterContentInit, OnDestroy { case "tree": params.push('session/api', this.selectedSession.id, 'tree') break; + case "parent": + params.push('session',this.sessionParent.type, this.sessionParent.id) } if(event.ctrlKey){ this._router.open(`#/${params.join('/')}`,'_blank') }else { this._router.navigate(params, { - queryParams: { env: this.selectedSession?.application?.env } + queryParams: { env: this.selectedSession?.application?.env } }); } } diff --git a/src/app/views/stats-api/stats-api.component.ts b/src/app/views/stats-api/stats-api.component.ts index b3bd5f4..22310f2 100644 --- a/src/app/views/stats-api/stats-api.component.ts +++ b/src/app/views/stats-api/stats-api.component.ts @@ -167,8 +167,8 @@ export class StatsApiComponent implements OnInit, OnDestroy { return r; })) }, - dependentsTable: { observable: this._statsService.getSessionApi({ 'column': "count:count,count_succes:countSucces,count_error_client:countErrClient,count_error_server:countErrServer,request2.api_name:name", "request.id": "out.parent", "out.id": "request2.id", 'request.api_name': name, 'request.start.ge': start.toISOString(), 'request.start.lt': end.toISOString(), 'request2.start.ge': start.toISOString(), 'request2.start.lt': end.toISOString(), 'environement': env, 'request2.api_name.not': 'null', 'order': 'count.desc', ...advancedParams }) }, - dependenciesTable: { observable: this._statsService.getSessionApi({ 'column': "count:count,count_succes:countSucces,count_error_client:countErrClient,count_error_server:countErrServer,request.api_name:name", "request.id": "out.parent", "out.id": "request2.id", 'request2.api_name': name, 'request2.start.ge': start.toISOString(), 'request2.start.lt': end.toISOString(), 'request.start.ge': start.toISOString(), 'request.start.lt': end.toISOString(), 'environement': env, 'request.api_name.not': 'null', 'order': 'count.desc', ...advancedParams }) }, + dependentsTable: { observable: this._statsService.getSessionApi({ 'column': "count:count,count_succes:countSucces,count_error_client:countErrClient,count_error_server:countErrServer,apisession2.api_name:name", "apisession.id": "out.parent", "out.id": "apisession2.id", 'apisession.api_name': name, 'apisession.start.ge': start.toISOString(), 'apisession.start.lt': end.toISOString(), 'apisession2.start.ge': start.toISOString(), 'apisession2.start.lt': end.toISOString(), 'environement': env, 'apisession2.api_name.not': 'null', 'order': 'count.desc', ...advancedParams }) }, + dependenciesTable: { observable: this._statsService.getSessionApi({ 'column': "count:count,count_succes:countSucces,count_error_client:countErrClient,count_error_server:countErrServer,apisession.api_name:name", "apisession.id": "out.parent", "out.id": "apisession2.id", 'apisession2.api_name': name, 'apisession2.start.ge': start.toISOString(), 'apisession2.start.lt': end.toISOString(), 'apisession.start.ge': start.toISOString(), 'apisession.start.lt': end.toISOString(), 'environement': env, 'apisession.api_name.not': 'null', 'order': 'count.desc', ...advancedParams }) }, exceptionsTable: { observable: this._statsService.getSessionApi({ 'column': 'count,err_type.coalesce(null),err_msg.coalesce(null)', 'err_type.not': 'null', 'err_msg.not': 'null', "status.ge": 500, "environement": env, "api_name": name, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'order': 'count.desc', ...advancedParams }).pipe(map((d: any) => d.slice(0, 5))) } }; } diff --git a/src/app/views/stats-app/stats-app.component.ts b/src/app/views/stats-app/stats-app.component.ts index 1bcff02..c57177d 100644 --- a/src/app/views/stats-app/stats-app.component.ts +++ b/src/app/views/stats-app/stats-app.component.ts @@ -167,8 +167,8 @@ export class StatsAppComponent implements OnInit, OnDestroy { })) }, repartitionApiBar: { observable: this._statsService.getSessionApi({ 'column': "count_succes:countSucces,count_error_client:countErrorClient,count_error_server:countErrorServer,api_name", 'app_name': name, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'environement': env, 'api_name.not': 'null', 'order': 'count.desc', ...advancedParams }).pipe(map((d: any) => d.slice(0, 5))) }, - dependentsTable: { observable: this._statsService.getSessionApi({ 'column': "count:count,count_succes:countSucces,count_error_client:countErrClient,count_error_server:countErrServer,request2.app_name:name", "request.id": "out.parent", "out.id": "request2.id", 'request.app_name': name, 'request.start.ge': start.toISOString(), 'request.start.lt': end.toISOString(), 'request2.start.ge': start.toISOString(), 'request2.start.lt': end.toISOString(), 'environement': env, 'request2.app_name.not': 'null', 'order': 'count.desc', ...advancedParams }) }, - dependenciesTable: { observable: this._statsService.getSessionApi({ 'column': "count:count,count_succes:countSucces,count_error_client:countErrClient,count_error_server:countErrServer,request.app_name:name", "request.id": "out.parent", "out.id": "request2.id", 'request2.app_name': name, 'request2.start.ge': start.toISOString(), 'request2.start.lt': end.toISOString(), 'request.start.ge': start.toISOString(), 'request.start.lt': end.toISOString(), 'environement': env, 'request.app_name.not': 'null', 'order': 'count.desc', ...advancedParams }) }, + dependentsTable: { observable: this._statsService.getSessionApi({ 'column': "count:count,count_succes:countSucces,count_error_client:countErrClient,count_error_server:countErrServer,apisession2.app_name:name", "apisession.id": "out.parent", "out.id": "apisession2.id", 'apisession.app_name': name, 'apisession.start.ge': start.toISOString(), 'apisession.start.lt': end.toISOString(), 'apisession2.start.ge': start.toISOString(), 'apisession2.start.lt': end.toISOString(), 'environement': env, 'apisession2.app_name.not': 'null', 'order': 'count.desc', ...advancedParams }) }, + dependenciesTable: { observable: this._statsService.getSessionApi({ 'column': "count:count,count_succes:countSucces,count_error_client:countErrClient,count_error_server:countErrServer,apisession.app_name:name", "apisession.id": "out.parent", "out.id": "apisession2.id", 'apisession2.app_name': name, 'apisession2.start.ge': start.toISOString(), 'apisession2.start.lt': end.toISOString(), 'apisession.start.ge': start.toISOString(), 'apisession.start.lt': end.toISOString(), 'environement': env, 'apisession.app_name.not': 'null', 'order': 'count.desc', ...advancedParams }) }, exceptionsTable: { observable: this._statsService.getSessionApi({ 'column': 'count,err_type.coalesce(null),err_msg.coalesce(null)', 'err_type.not': 'null', 'err_msg.not': 'null', "status.ge": 500, "environement": env, "app_name": name, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'order': 'count.desc', ...advancedParams }).pipe(map((d: any) => d.slice(0, 5))) } }; }; diff --git a/src/app/views/stats-database/stats-database.component.html b/src/app/views/stats-database/stats-database.component.html index ee475ed..bf86a88 100644 --- a/src/app/views/stats-database/stats-database.component.html +++ b/src/app/views/stats-database/stats-database.component.html @@ -1,4 +1,4 @@ - +
diff --git a/src/app/views/stats-database/stats-database.component.ts b/src/app/views/stats-database/stats-database.component.ts index fd00845..d412599 100644 --- a/src/app/views/stats-database/stats-database.component.ts +++ b/src/app/views/stats-database/stats-database.component.ts @@ -81,7 +81,7 @@ export class StatsDatabaseComponent implements OnInit { this.dbNameListIsLoading = true; this.serverFilterForm.controls.dbnameControl.reset(); this.serverFilterForm.controls.dbnameControl.disable(); - this._statsService.getSessionApi({ 'column.distinct': 'query.db&query.parent=request.id&order=query.db.asc', 'request.environement': this.env }).pipe(catchError(error => of(error))) + this._statsService.getSessionApi({ 'column.distinct': 'dbquery.db&dbquery.parent=apisession.id&order=dbquery.db.asc', 'apisession.environement': this.env }).pipe(catchError(error => of(error))) .subscribe({ next: (res: { db: string }[]) => { this.dbNameDataList = res.map((s: any) => s.db) @@ -140,22 +140,22 @@ export class StatsDatabaseComponent implements OnInit { let now = new Date(); var groupedBy = periodManagement(start, end); return { - dbInfo: { observable: this._statsService.getSessionApi({ 'column.distinct': 'query.host,query.db,query.driver,query.db_name,query.db_version', 'query.parent': 'request.id', "request.environement": env, "query.db": db, 'query.start.ge': start.toISOString(), 'query.start.lt': end.toISOString(), 'request.start.ge': start.toISOString(), 'request.start.lt': end.toISOString() }) }, - countOkKoSlowest: { observable: this._statsService.getSessionApi({ 'column': 'query.count_db_error:countErrorServer,query.count:count,query.count_slowest:countSlowest,query.start.date:date', 'query.parent': 'request.id', "request.environement": env, "query.db": db, 'request.start.ge': new Date(now.getFullYear(), now.getMonth(), now.getDate() - 6).toISOString(), 'request.start.lt': now.toISOString(), 'query.start.ge': new Date(now.getFullYear(), now.getMonth(), now.getDate() - 7).toISOString(), 'query.start.lt': now.toISOString()}) }, - countMinMaxAvg: { observable: this._statsService.getSessionApi({ 'column': `query.count_db_succes:countDbSucces,query.elapsedtime.max:max,query.elapsedtime.avg:avg,query.start.${groupedBy}:date,query.start.year:year`, 'query.parent': 'request.id', "request.environement": env, "query.db": db, 'request.start.ge': start.toISOString(), 'request.start.lt': end.toISOString(), 'query.start.ge': start.toISOString(), 'query.start.lt': end.toISOString(), 'order': `query.start.year.asc,query.start.${groupedBy}.asc` }).pipe(map(((r: any[]) => { + dbInfo: { observable: this._statsService.getSessionApi({ 'column.distinct': 'dbquery.host,dbquery.db,dbquery.driver,dbquery.db_name,dbquery.db_version', 'dbquery.parent': 'apisession.id', "apisession.environement": env, "dbquery.db": db, 'dbquery.start.ge': start.toISOString(), 'dbquery.start.lt': end.toISOString(), 'apisession.start.ge': start.toISOString(), 'apisession.start.lt': end.toISOString() }) }, + countOkKoSlowest: { observable: this._statsService.getSessionApi({ 'column': 'dbquery.count_db_error:countErrorServer,dbquery.count:count,dbquery.count_slowest:countSlowest,dbquery.start.date:date', 'dbquery.parent': 'apisession.id', "apisession.environement": env, "dbquery.db": db, 'apisession.start.ge': new Date(now.getFullYear(), now.getMonth(), now.getDate() - 6).toISOString(), 'apisession.start.lt': now.toISOString(), 'dbquery.start.ge': new Date(now.getFullYear(), now.getMonth(), now.getDate() - 7).toISOString(), 'dbquery.start.lt': now.toISOString()}) }, + countMinMaxAvg: { observable: this._statsService.getSessionApi({ 'column': `dbquery.count_db_succes:countDbSucces,dbquery.elapsedtime.max:max,dbquery.elapsedtime.avg:avg,dbquery.start.${groupedBy}:date,dbquery.start.year:year`, 'dbquery.parent': 'apisession.id', "apisession.environement": env, "dbquery.db": db, 'apisession.start.ge': start.toISOString(), 'apisession.start.lt': end.toISOString(), 'dbquery.start.ge': start.toISOString(), 'dbquery.start.lt': end.toISOString(), 'order': `dbquery.start.year.asc,dbquery.start.${groupedBy}.asc` }).pipe(map(((r: any[]) => { formatters[groupedBy](r, this._datePipe); return r; }))) }, countRepartitionBySpeedBar: { - observable: this._statsService.getSessionApi({ 'column': `query.count_slowest:elapsedTimeSlowest,query.count_slow:elapsedTimeSlow,query.count_medium:elapsedTimeMedium,query.count_fast:elapsedTimeFast,query.count_fastest:elapsedTimeFastest,query.start.${groupedBy}:date,query.start.year:year`, 'query.parent': 'request.id', "request.environement": env, "query.db": db, 'request.start.ge': start.toISOString(), 'request.start.lt': end.toISOString(), 'query.start.ge': start.toISOString(), 'query.start.lt': end.toISOString(), 'order': `query.start.year.asc,query.start.${groupedBy}.asc` }).pipe(map(((r: any[]) => { + observable: this._statsService.getSessionApi({ 'column': `dbquery.count_slowest:elapsedTimeSlowest,dbquery.count_slow:elapsedTimeSlow,dbquery.count_medium:elapsedTimeMedium,dbquery.count_fast:elapsedTimeFast,dbquery.count_fastest:elapsedTimeFastest,dbquery.start.${groupedBy}:date,dbquery.start.year:year`, 'dbquery.parent': 'apisession.id', "apisession.environement": env, "dbquery.db": db, 'apisession.start.ge': start.toISOString(), 'apisession.start.lt': end.toISOString(), 'dbquery.start.ge': start.toISOString(), 'dbquery.start.lt': end.toISOString(), 'order': `dbquery.start.year.asc,dbquery.start.${groupedBy}.asc` }).pipe(map(((r: any[]) => { formatters[groupedBy](r, this._datePipe); return r; }))) }, - countRepartitionBySpeedPie: { observable: this._statsService.getSessionApi({ 'column': 'query.count_slowest:elapsedTimeSlowest,query.count_slow:elapsedTimeSlow,query.count_medium:elapsedTimeMedium,query.count_fast:elapsedTimeFast,query.count_fastest:elapsedTimeFastest', 'query.parent': 'request.id', "request.environement": env, "query.db": db, 'request.start.ge': start.toISOString(), 'request.start.lt': end.toISOString(), 'query.start.ge': start.toISOString(), 'query.start.lt': end.toISOString()}) }, - exceptions: { observable: this._statsService.getSessionApi({ 'column': 'count,dbaction.err_type.coalesce(null),dbaction.err_msg.coalesce(null)', 'dbaction.err_type.not': 'null', 'dbaction.err_msg.not': 'null', 'dbaction.parent': 'query.id', 'query.parent': 'request.id', 'order': 'count.desc', "request.environement": env, "query.db": db, 'request.start.ge': start.toISOString(), 'request.start.lt': end.toISOString(), 'query.start.ge': start.toISOString(), 'query.start.lt': end.toISOString() }).pipe(map((d: any) => d.slice(0, 5))) }, - usersInfo: { observable: this._statsService.getSessionApi({ 'column': 'count:countRows,query.user', 'query.parent': 'request.id', "request.environement": env, "query.db": db, 'request.start.ge': start.toISOString(), 'request.start.lt': end.toISOString(), 'query.start.ge': start.toISOString(), 'query.start.lt': end.toISOString() }) } + countRepartitionBySpeedPie: { observable: this._statsService.getSessionApi({ 'column': 'dbquery.count_slowest:elapsedTimeSlowest,dbquery.count_slow:elapsedTimeSlow,dbquery.count_medium:elapsedTimeMedium,dbquery.count_fast:elapsedTimeFast,dbquery.count_fastest:elapsedTimeFastest', 'dbquery.parent': 'apisession.id', "apisession.environement": env, "dbquery.db": db, 'apisession.start.ge': start.toISOString(), 'apisession.start.lt': end.toISOString(), 'dbquery.start.ge': start.toISOString(), 'dbquery.start.lt': end.toISOString()}) }, + exceptions: { observable: this._statsService.getSessionApi({ 'column': 'count,dbaction.err_type.coalesce(null),dbaction.err_msg.coalesce(null)', 'dbaction.err_type.not': 'null', 'dbaction.err_msg.not': 'null', 'dbaction.parent': 'dbquery.id', 'dbquery.parent': 'apisession.id', 'order': 'count.desc', "apisession.environement": env, "dbquery.db": db, 'apisession.start.ge': start.toISOString(), 'apisession.start.lt': end.toISOString(), 'dbquery.start.ge': start.toISOString(), 'dbquery.start.lt': end.toISOString() }).pipe(map((d: any) => d.slice(0, 5))) }, + usersInfo: { observable: this._statsService.getSessionApi({ 'column': 'count:countRows,dbquery.user', 'dbquery.parent': 'apisession.id', "apisession.environement": env, "dbquery.db": db, 'apisession.start.ge': start.toISOString(), 'apisession.start.lt': end.toISOString(), 'dbquery.start.ge': start.toISOString(), 'dbquery.start.lt': end.toISOString() }) } } } From 51de8a3ba8ca9cf230b38f3953fcc9b88d87a509 Mon Sep 17 00:00:00 2001 From: YoussefDahi Date: Tue, 28 May 2024 11:28:53 +0200 Subject: [PATCH 004/126] bug fix: - mainsession showing as failed - wrong tree endpoint url - wrong param names in jqeury url in dashboead due to table rename in backend - server info card showing when session is null - removed showing db errors in tree --- src/app/shared/services/trace.service.ts | 2 +- .../session-detail.component.html | 6 ++-- .../session-detail.component.ts | 28 ++++++++++--------- .../session-main/session-main.component.html | 4 +-- .../views/stats-api/stats-api.component.ts | 4 +-- .../views/stats-app/stats-app.component.ts | 4 +-- src/app/views/tree/tree.component.ts | 2 +- src/environments/environment.ts | 2 +- 8 files changed, 27 insertions(+), 25 deletions(-) diff --git a/src/app/shared/services/trace.service.ts b/src/app/shared/services/trace.service.ts index 0e59c99..bd53d77 100644 --- a/src/app/shared/services/trace.service.ts +++ b/src/app/shared/services/trace.service.ts @@ -28,7 +28,7 @@ export class TraceService { } getTreeRequestById(id: string) { - return this.http.get(`${localStorage.getItem('server')}/trace/session/api/${id}/tree`); + return this.http.get(`${localStorage.getItem('server')}/trace/session/${id}/tree`); } getDbRequestById(id: number){ diff --git a/src/app/views/session-detail/session-detail.component.html b/src/app/views/session-detail/session-detail.component.html index 6d632a1..5f1c019 100644 --- a/src/app/views/session-detail/session-detail.component.html +++ b/src/app/views/session-detail/session-detail.component.html @@ -67,7 +67,7 @@ {{selectedSession?.status}} - + - + -
+
diff --git a/src/app/views/session-detail/session-detail.component.ts b/src/app/views/session-detail/session-detail.component.ts index 473127d..a7ccbaa 100644 --- a/src/app/views/session-detail/session-detail.component.ts +++ b/src/app/views/session-detail/session-detail.component.ts @@ -140,13 +140,15 @@ export class SessionDetailComponent implements AfterContentInit, OnDestroy { // Check if parent exist this.sessionParent = null; - this._traceService.getSessionParentByChildId(id).subscribe( { - next : (data: {id : string, type : sessionType}) =>{ - this.sessionParent = data; - console.log(this.sessionParent) - }, - error : err => console.log(err) - }) + if(this.selectedSession.type == "api"){ + this._traceService.getSessionParentByChildId(id).subscribe( { + next : (data: {id : string, type : sessionType}) =>{ + this.sessionParent = data; + }, + error : err => console.log(err) + }) + } + this.isLoading = false; this.isComplete = true; } else { @@ -253,14 +255,14 @@ export class SessionDetailComponent implements AfterContentInit, OnDestroy { } } - selectedQuery(event: MouseEvent, query:any){ // TODO finish this - if(query){ + selectedQuery(event: MouseEvent, queryId:any){ // TODO finish this + if(queryId){ if( event.ctrlKey){ - this._router.open(`#/session/api/${this.selectedSession.id}/db/`,'_blank',) + this._router.open(`#/session/${this.selectedSession.type}/${this.selectedSession.id}/db/${queryId}`,'_blank',) }else { - this._router.navigate(['/session', 'api', this.selectedSession.id, 'db'],{ - - }); + this._router.navigate([ 'db', queryId],{ + queryParams:{env:this.env} + }); } } } diff --git a/src/app/views/session-main/session-main.component.html b/src/app/views/session-main/session-main.component.html index 12b599b..c047e03 100644 --- a/src/app/views/session-main/session-main.component.html +++ b/src/app/views/session-main/session-main.component.html @@ -36,8 +36,8 @@ - + diff --git a/src/app/views/stats-api/stats-api.component.ts b/src/app/views/stats-api/stats-api.component.ts index 22310f2..640bad3 100644 --- a/src/app/views/stats-api/stats-api.component.ts +++ b/src/app/views/stats-api/stats-api.component.ts @@ -167,8 +167,8 @@ export class StatsApiComponent implements OnInit, OnDestroy { return r; })) }, - dependentsTable: { observable: this._statsService.getSessionApi({ 'column': "count:count,count_succes:countSucces,count_error_client:countErrClient,count_error_server:countErrServer,apisession2.api_name:name", "apisession.id": "out.parent", "out.id": "apisession2.id", 'apisession.api_name': name, 'apisession.start.ge': start.toISOString(), 'apisession.start.lt': end.toISOString(), 'apisession2.start.ge': start.toISOString(), 'apisession2.start.lt': end.toISOString(), 'environement': env, 'apisession2.api_name.not': 'null', 'order': 'count.desc', ...advancedParams }) }, - dependenciesTable: { observable: this._statsService.getSessionApi({ 'column': "count:count,count_succes:countSucces,count_error_client:countErrClient,count_error_server:countErrServer,apisession.api_name:name", "apisession.id": "out.parent", "out.id": "apisession2.id", 'apisession2.api_name': name, 'apisession2.start.ge': start.toISOString(), 'apisession2.start.lt': end.toISOString(), 'apisession.start.ge': start.toISOString(), 'apisession.start.lt': end.toISOString(), 'environement': env, 'apisession.api_name.not': 'null', 'order': 'count.desc', ...advancedParams }) }, + dependentsTable: { observable: this._statsService.getSessionApi({ 'column': "count:count,count_succes:countSucces,count_error_client:countErrClient,count_error_server:countErrServer,apisession2.api_name:name", "apisession.id": "apirequest.parent", "apirequest.id": "apisession2.id", 'apisession.api_name': name, 'apisession.start.ge': start.toISOString(), 'apisession.start.lt': end.toISOString(), 'apisession2.start.ge': start.toISOString(), 'apisession2.start.lt': end.toISOString(), 'environement': env, 'apisession2.api_name.not': 'null', 'order': 'count.desc', ...advancedParams }) }, + dependenciesTable: { observable: this._statsService.getSessionApi({ 'column': "count:count,count_succes:countSucces,count_error_client:countErrClient,count_error_server:countErrServer,apisession.api_name:name", "apisession.id": "apirequest.parent", "apirequest.id": "apisession2.id", 'apisession2.api_name': name, 'apisession2.start.ge': start.toISOString(), 'apisession2.start.lt': end.toISOString(), 'apisession.start.ge': start.toISOString(), 'apisession.start.lt': end.toISOString(), 'environement': env, 'apisession.api_name.not': 'null', 'order': 'count.desc', ...advancedParams }) }, exceptionsTable: { observable: this._statsService.getSessionApi({ 'column': 'count,err_type.coalesce(null),err_msg.coalesce(null)', 'err_type.not': 'null', 'err_msg.not': 'null', "status.ge": 500, "environement": env, "api_name": name, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'order': 'count.desc', ...advancedParams }).pipe(map((d: any) => d.slice(0, 5))) } }; } diff --git a/src/app/views/stats-app/stats-app.component.ts b/src/app/views/stats-app/stats-app.component.ts index c57177d..e6bc1d2 100644 --- a/src/app/views/stats-app/stats-app.component.ts +++ b/src/app/views/stats-app/stats-app.component.ts @@ -167,8 +167,8 @@ export class StatsAppComponent implements OnInit, OnDestroy { })) }, repartitionApiBar: { observable: this._statsService.getSessionApi({ 'column': "count_succes:countSucces,count_error_client:countErrorClient,count_error_server:countErrorServer,api_name", 'app_name': name, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'environement': env, 'api_name.not': 'null', 'order': 'count.desc', ...advancedParams }).pipe(map((d: any) => d.slice(0, 5))) }, - dependentsTable: { observable: this._statsService.getSessionApi({ 'column': "count:count,count_succes:countSucces,count_error_client:countErrClient,count_error_server:countErrServer,apisession2.app_name:name", "apisession.id": "out.parent", "out.id": "apisession2.id", 'apisession.app_name': name, 'apisession.start.ge': start.toISOString(), 'apisession.start.lt': end.toISOString(), 'apisession2.start.ge': start.toISOString(), 'apisession2.start.lt': end.toISOString(), 'environement': env, 'apisession2.app_name.not': 'null', 'order': 'count.desc', ...advancedParams }) }, - dependenciesTable: { observable: this._statsService.getSessionApi({ 'column': "count:count,count_succes:countSucces,count_error_client:countErrClient,count_error_server:countErrServer,apisession.app_name:name", "apisession.id": "out.parent", "out.id": "apisession2.id", 'apisession2.app_name': name, 'apisession2.start.ge': start.toISOString(), 'apisession2.start.lt': end.toISOString(), 'apisession.start.ge': start.toISOString(), 'apisession.start.lt': end.toISOString(), 'environement': env, 'apisession.app_name.not': 'null', 'order': 'count.desc', ...advancedParams }) }, + dependentsTable: { observable: this._statsService.getSessionApi({ 'column': "count:count,count_succes:countSucces,count_error_client:countErrClient,count_error_server:countErrServer,apisession2.app_name:name", "apisession.id": "apirequest.parent", "apirequest.id": "apisession2.id", 'apisession.app_name': name, 'apisession.start.ge': start.toISOString(), 'apisession.start.lt': end.toISOString(), 'apisession2.start.ge': start.toISOString(), 'apisession2.start.lt': end.toISOString(), 'environement': env, 'apisession2.app_name.not': 'null', 'order': 'count.desc', ...advancedParams }) }, + dependenciesTable: { observable: this._statsService.getSessionApi({ 'column': "count:count,count_succes:countSucces,count_error_client:countErrClient,count_error_server:countErrServer,apisession.app_name:name", "apisession.id": "apirequest.parent", "apirequest.id": "apisession2.id", 'apisession2.app_name': name, 'apisession2.start.ge': start.toISOString(), 'apisession2.start.lt': end.toISOString(), 'apisession.start.ge': start.toISOString(), 'apisession.start.lt': end.toISOString(), 'environement': env, 'apisession.app_name.not': 'null', 'order': 'count.desc', ...advancedParams }) }, exceptionsTable: { observable: this._statsService.getSessionApi({ 'column': 'count,err_type.coalesce(null),err_msg.coalesce(null)', 'err_type.not': 'null', 'err_msg.not': 'null', "status.ge": 500, "environement": env, "app_name": name, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'order': 'count.desc', ...advancedParams }).pipe(map((d: any) => d.slice(0, 5))) } }; }; diff --git a/src/app/views/tree/tree.component.ts b/src/app/views/tree/tree.component.ts index 0ebd20a..a8e283d 100644 --- a/src/app/views/tree/tree.component.ts +++ b/src/app/views/tree/tree.component.ts @@ -278,7 +278,7 @@ export class TreeComponent implements OnDestroy { break; case 'db': - modal += ` ${value.completed ? "réussi" : "échoué"}
` + modal += ` ${value.completed ? "réussi" : "échoué"}
` modal += `Thread : ${value.threadName || 'N/A'}
` modal += `Schema : ${value.schema || 'N/A'}
` modal += `Hôte : ${value.host || 'N/A'}
` diff --git a/src/environments/environment.ts b/src/environments/environment.ts index 099aae8..2084aa3 100644 --- a/src/environments/environment.ts +++ b/src/environments/environment.ts @@ -10,7 +10,7 @@ export const environment = { }; export const application: Application = { - default_env: 'prd', + default_env: 'dev', session: { api: { default_period: makePeriod(0) From 7a6c88fd9b121d792279acd436df5ee1a3fa5c22 Mon Sep 17 00:00:00 2001 From: YoussefDahi Date: Tue, 28 May 2024 12:05:57 +0200 Subject: [PATCH 005/126] disabled routing to db-request-detail --- src/app/views/session-detail/session-detail.component.html | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/app/views/session-detail/session-detail.component.html b/src/app/views/session-detail/session-detail.component.html index 5f1c019..1d90e42 100644 --- a/src/app/views/session-detail/session-detail.component.html +++ b/src/app/views/session-detail/session-detail.component.html @@ -141,10 +141,7 @@ Hôte - {{element['host']}} - - :{{element['port']}} - + {{element['host']}}:{{element['port']}} @@ -253,7 +250,7 @@ - + Date: Tue, 28 May 2024 14:57:59 +0200 Subject: [PATCH 006/126] period urls --- src/app/app.component.ts | 4 +- src/app/shared/services/filter.service.ts | 9 +- .../session-api/session-api.component.ts | 35 ++++--- .../session-main/session-main.component.ts | 43 +++----- .../views/stats-api/stats-api.component.ts | 27 +++-- .../views/stats-app/stats-app.component.ts | 99 +++++++++---------- .../stats-database.component.ts | 25 ++--- .../views/stats-user/stats-user.component.ts | 99 +++++++++---------- src/environments/environment.ts | 6 +- 9 files changed, 161 insertions(+), 186 deletions(-) diff --git a/src/app/app.component.ts b/src/app/app.component.ts index afabed7..20cb90d 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -17,7 +17,6 @@ import { FilterService } from './shared/services/filter.service'; }) export class AppComponent implements OnInit { - @ViewChild('drawer') drawer: MatDrawer; envs: any[]; env: FormControl = new FormControl(); isLoadingEnv = false; @@ -27,8 +26,7 @@ export class AppComponent implements OnInit { constructor( private _activatedRoute: ActivatedRoute, private _router: EnvRouter, - private _service: StatsService, - private _filter: FilterService ) { + private _service: StatsService) { this.isLoadingEnv = true; this.subscriptions.push(this._service.getSessionApi({'column.distinct': 'environement', 'order': 'environement.asc'}) .pipe(finalize(() => this.isLoadingEnv = false)) diff --git a/src/app/shared/services/filter.service.ts b/src/app/shared/services/filter.service.ts index 1dbdfac..e3f568f 100644 --- a/src/app/shared/services/filter.service.ts +++ b/src/app/shared/services/filter.service.ts @@ -92,12 +92,5 @@ export class FilterService implements OnDestroy{ getPresetsLocalStrorage(pageName:string):FilterPreset[] { return JSON.parse(localStorage.getItem(pageName) || '[]'); - } - - - - - - - + } } \ No newline at end of file diff --git a/src/app/views/session-api/session-api.component.ts b/src/app/views/session-api/session-api.component.ts index 30507df..da3b5da 100644 --- a/src/app/views/session-api/session-api.component.ts +++ b/src/app/views/session-api/session-api.component.ts @@ -43,7 +43,7 @@ export class SessionApiComponent implements OnInit, OnDestroy { filterTable = new Map(); - params: Partial<{ env: string, start: any, end: any, endExclusive: any, serveurs: string[] }> = {}; + params: Partial<{ env: string, start: Date, end: Date, serveurs: string[] }> = {}; advancedParams: Partial<{ [key: string]: any }> ={} advancedParamsChip: Partial<{ [key: string]: any }> ={} focusFieldName: any; @@ -62,17 +62,14 @@ export class SessionApiComponent implements OnInit, OnDestroy { .subscribe({ next: (params: Params) => { this.params.env = params['env'] || application.default_env; - this.params.start = params['start'] || (application.session.api.default_period || makePeriod(0)).start.toISOString(); - this.params.end = params['end'] || (application.session.api.default_period || makePeriod(0)).end.toISOString(); + this.params.start = params['start'] ? new Date(params['start']) : (application.session.api.default_period || makePeriod(0, 1)).start; + this.params.end = params['end'] ? new Date(params['end']) : (application.session.api.default_period || makePeriod(0, 1)).end; this.params.serveurs = Array.isArray(params['appname']) ? params['appname'] : [params['appname'] || '']; if (this.params.serveurs[0] != '') { this.patchServerValue(this.params.serveurs) } - this.params.endExclusive = new Date(this.params.end); - this.params.endExclusive.setDate(this.params.endExclusive.getDate() + 1); - this.params.endExclusive = this.params.endExclusive.toISOString(); - this.patchDateValue(this.params.start, this.params.end); + this.patchDateValue(this.params.start, new Date(this.params.end.getFullYear(), this.params.end.getMonth(), this.params.end.getDate() - 1)); this.subscriptions.push(this._statsService.getSessionApi( { 'column.distinct': 'app_name', 'order': 'app_name.asc' }) .pipe(finalize(()=> this.serverNameIsLoading = false)) .subscribe({ @@ -85,7 +82,7 @@ export class SessionApiComponent implements OnInit, OnDestroy { })); this.getIncomingRequest(); - this._location.replaceState(`${this._router.url.split('?')[0]}?env=${this.params.env}&start=${this.params.start}&end=${this.params.end}${this.params.serveurs[0] !== '' ? '&' + this.params.serveurs.map(name => `appname=${name}`).join('&') : ''}`) + this._location.replaceState(`${this._router.url.split('?')[0]}?env=${this.params.env}&start=${this.params.start.toISOString()}&end=${this.params.end.toISOString()}${this.params.serveurs[0] !== '' ? '&' + this.params.serveurs.map(name => `appname=${name}`).join('&') : ''}`) } }); } @@ -105,16 +102,17 @@ export class SessionApiComponent implements OnInit, OnDestroy { search() { if (this.serverFilterForm.valid) { let appname = this.serverFilterForm.getRawValue().appname; - let start = this.serverFilterForm.getRawValue().dateRangePicker.start.toISOString(); - let end = this.serverFilterForm.getRawValue().dateRangePicker.end.toISOString() - if (this.params.start != start - || this.params.end != end + let start = this.serverFilterForm.getRawValue().dateRangePicker.start; + let end = this.serverFilterForm.getRawValue().dateRangePicker.end + let excludedEnd = new Date(end.getFullYear(), end.getMonth(), end.getDate() + 1) + if (this.params.start.toISOString() != start.toISOString() + || this.params.end.toISOString() != excludedEnd.toISOString() || !this.params?.serveurs?.every((element, index) => element === appname[index]) || appname.length != this.params?.serveurs?.length) { this._router.navigate([], { relativeTo: this._activatedRoute, queryParamsHandling: 'merge', - queryParams: { ...(appname !== undefined && { appname }), start: start, end: end } + queryParams: { ...(appname !== undefined && { appname }), start: start.toISOString(), end: excludedEnd } }) } else { this.getIncomingRequest(); @@ -126,10 +124,11 @@ export class SessionApiComponent implements OnInit, OnDestroy { let params = { 'env': this.params.env, 'appname': this.params.serveurs, - 'start': this.params.start, - 'end': this.params.endExclusive, + 'start': this.params.start.toISOString(), + 'end': this.params.end.toISOString(), 'lazy': false }; + console.log(params) if(this.advancedParams){ Object.assign(params, this.advancedParams); } @@ -186,8 +185,8 @@ export class SessionApiComponent implements OnInit, OnDestroy { patchDateValue(start: Date, end: Date) { this.serverFilterForm.patchValue({ dateRangePicker: { - start: new Date(start), - end: new Date(end) + start: start, + end: end } }, { emitEvent: false }); } @@ -232,7 +231,7 @@ export class SessionApiComponent implements OnInit, OnDestroy { } resetFilters(){ - this.patchDateValue((application.session.api.default_period || makePeriod(0)).start,(application.session.api.default_period || makePeriod(0)).end); + this.patchDateValue((application.session.api.default_period || makePeriod(0)).start,(application.session.api.default_period || makePeriod(0, 1)).end); this.patchServerValue([]); this.advancedParams = {}; this._filter.setFilterMap({}) diff --git a/src/app/views/session-main/session-main.component.ts b/src/app/views/session-main/session-main.component.ts index 65b4945..980774c 100644 --- a/src/app/views/session-main/session-main.component.ts +++ b/src/app/views/session-main/session-main.component.ts @@ -42,7 +42,7 @@ export class SessionMainComponent implements OnInit, OnDestroy { focusFieldName: any filter: string = ''; - params: Partial<{ env: string, start: any, end: any, endExclusive: any, launchMode: string }> = {}; + params: Partial<{ env: string, start: Date, end: Date, launchMode: string }> = {}; @ViewChild(MatPaginator) paginator: MatPaginator; @ViewChild(MatSort) sort: MatSort; @@ -60,14 +60,11 @@ export class SessionMainComponent implements OnInit, OnDestroy { this.params.launchMode = params['name'] || ''; this.patchLaunchValue(this.params.launchMode); - this.params.start = params['start'] || (application.session.main.default_period || makePeriod(0)).start.toISOString(); - this.params.end = params['end'] || (application.session.main.default_period || makePeriod(0)).end.toISOString(); - this.params.endExclusive = new Date(this.params.end); - this.params.endExclusive.setDate(this.params.endExclusive.getDate() + 1); - this.params.endExclusive = this.params.endExclusive.toISOString(); - this.patchDateValue(this.params.start, this.params.end); + this.params.start = params['start'] ? new Date(params['start']) : (application.session.main.default_period || makePeriod(0, 1)).start; + this.params.end = params['end'] ? new Date(params['end']) : (application.session.main.default_period || makePeriod(0, 1)).end; + this.patchDateValue(this.params.start, new Date(this.params.end.getFullYear(), this.params.end.getMonth(), this.params.end.getDate() - 1)); this.getMainRequests(); - this._location.replaceState(`${this._router.url.split('?')[0]}?env=${this.params.env}&start=${this.params.start}&end=${this.params.end}${this.params.launchMode !== '' ? '&name=' + this.params.launchMode : ''}`) + this._location.replaceState(`${this._router.url.split('?')[0]}?env=${this.params.env}&start=${this.params.start.toISOString()}&end=${this.params.end.toISOString()}${this.params.launchMode !== '' ? '&name=' + this.params.launchMode : ''}`) } }); } @@ -81,20 +78,12 @@ export class SessionMainComponent implements OnInit, OnDestroy { this.subscription.unsubscribe(); } - configQueryParamFilter(start: Date, end: Date, name: string) { - this._router.navigate([], { - queryParamsHandling: 'merge', - queryParams: { name: name, start: start.toISOString(), end: end.toISOString() }, - relativeTo: this._activatedRoute - }); - } - getMainRequests() { let params = { 'env': this.params.env, 'launchmode': this.params.launchMode, - 'start': this.params.start, - 'end': this.params.endExclusive, + 'start': this.params.start.toISOString(), + 'end': this.params.end.toISOString(), 'lazy': false }; if(this.advancedParams){ @@ -131,16 +120,16 @@ export class SessionMainComponent implements OnInit, OnDestroy { search() { if (this.serverFilterForm.valid) { let name = this.serverFilterForm.getRawValue().launchmode; - let start = this.serverFilterForm.getRawValue().dateRangePicker.start.toISOString(); - let end = this.serverFilterForm.getRawValue().dateRangePicker.end.toISOString() - - if (this.params.start != start - || this.params.end != end + let start = this.serverFilterForm.getRawValue().dateRangePicker.start; + let end = this.serverFilterForm.getRawValue().dateRangePicker.end + let excludedEnd = new Date(end.getFullYear(), end.getMonth(), end.getDate() + 1) + if (this.params.start.toISOString() != start.toISOString() + || this.params.end.toISOString() != excludedEnd.toISOString() || this.params.launchMode != name) { this._router.navigate([], { relativeTo: this._activatedRoute, queryParamsHandling: 'merge', - queryParams: { ...(name !== undefined && { name }), start: start, end: end } + queryParams: { ...(name !== undefined && { name }), start: start.toISOString(), end: excludedEnd.toISOString() } }) } else { this.getMainRequests(); @@ -151,8 +140,8 @@ export class SessionMainComponent implements OnInit, OnDestroy { patchDateValue(start: Date, end: Date) { this.serverFilterForm.patchValue({ dateRangePicker: { - start: new Date(start), - end: new Date(end) + start: start, + end: end } }, { emitEvent: false }); } @@ -192,7 +181,7 @@ export class SessionMainComponent implements OnInit, OnDestroy { } } resetFilters(){ - this.patchDateValue((application.session.api.default_period || makePeriod(0)).start,(application.session.api.default_period || makePeriod(0)).end); + this.patchDateValue((application.session.api.default_period || makePeriod(0)).start,(application.session.api.default_period || makePeriod(0, 1)).end); this.patchLaunchValue(""); this.advancedParams = {}; this._filter.setFilterMap({}) diff --git a/src/app/views/stats-api/stats-api.component.ts b/src/app/views/stats-api/stats-api.component.ts index 22310f2..0df8763 100644 --- a/src/app/views/stats-api/stats-api.component.ts +++ b/src/app/views/stats-api/stats-api.component.ts @@ -35,10 +35,8 @@ export class StatsApiComponent implements OnInit, OnDestroy { env: any; name: string; - start: any; - end: any; - DEFAULT_START: Date; - DEFAULT_END: Date; + start: Date; + end: Date; advancedParams: Partial<{ [key: string]: any }> = {} focusFieldName: any; @@ -52,11 +50,11 @@ export class StatsApiComponent implements OnInit, OnDestroy { next: (v: { params: Params, queryParams: Params }) => { this.name = v.params.name; this.env = v.queryParams.env || application.default_env; - this.start = v.queryParams.start || (application.dashboard.api.default_period || application.dashboard.default_period || makePeriod(6)).start.toISOString(); - this.end = v.queryParams.end || (application.dashboard.api.default_period || application.dashboard.default_period || makePeriod(6)).end.toISOString(); - this.patchDateValue(this.start, this.end); + this.start = v.queryParams.start ? new Date(v.queryParams.start) : (application.dashboard.api.default_period || application.dashboard.default_period || makePeriod(6)).start; + this.end = v.queryParams.end ? new Date(v.queryParams.end) : (application.dashboard.api.default_period || application.dashboard.default_period || makePeriod(6, 1)).end; + this.patchDateValue(this.start, new Date(this.end.getFullYear(), this.end.getMonth(), this.end.getDate() - 1)); this.init(); - this._location.replaceState(`${this._router.url.split('?')[0]}?env=${this.env}&start=${this.start}&end=${this.end}`); + this._location.replaceState(`${this._router.url.split('?')[0]}?env=${this.env}&start=${this.start.toISOString()}&end=${this.end.toISOString()}`); } }); @@ -100,12 +98,13 @@ export class StatsApiComponent implements OnInit, OnDestroy { search() { if (this.serverFilterForm.valid) { let start = this.serverFilterForm.getRawValue().dateRangePicker.start; - let end = new Date(this.serverFilterForm.getRawValue().dateRangePicker.end); - if (start.toISOString() != this._activatedRoute.snapshot?.queryParams['start'] || end.toISOString() != this._activatedRoute.snapshot?.queryParams['end']) { + let end = this.serverFilterForm.getRawValue().dateRangePicker.end; + let excludedEnd = new Date(end.getFullYear(), end.getMonth(), end.getDate() + 1) + if (start.toISOString() != this.start.toISOString() || excludedEnd.toISOString() != this.end.toISOString()) { this._router.navigate([], { relativeTo: this._activatedRoute, queryParamsHandling: 'merge', - queryParams: { start: start.toISOString(), end: end.toISOString() } + queryParams: { start: start.toISOString(), end: excludedEnd.toISOString() } }) } else { this.init(); @@ -116,8 +115,8 @@ export class StatsApiComponent implements OnInit, OnDestroy { patchDateValue(start: Date, end: Date) { this.serverFilterForm.patchValue({ dateRangePicker: { - start: new Date(start), - end: new Date(end) + start: start, + end: end } }, { emitEvent: false }); } @@ -175,7 +174,7 @@ export class StatsApiComponent implements OnInit, OnDestroy { resetFilters() { this.patchDateValue((application.dashboard.api.default_period || application.dashboard.default_period || makePeriod(6)).start, - (application.dashboard.api.default_period || application.dashboard.default_period || makePeriod(6)).end); + (application.dashboard.api.default_period || application.dashboard.default_period || makePeriod(6, 1)).end); this.advancedParams = {}; this._filter.setFilterMap({}) } diff --git a/src/app/views/stats-app/stats-app.component.ts b/src/app/views/stats-app/stats-app.component.ts index c57177d..2daa308 100644 --- a/src/app/views/stats-app/stats-app.component.ts +++ b/src/app/views/stats-app/stats-app.component.ts @@ -6,7 +6,7 @@ import { ActivatedRoute, Params } from "@angular/router"; import { FormControl, FormGroup, Validators } from "@angular/forms"; import { BehaviorSubject, Observable, Subscription, combineLatest, finalize, map } from "rxjs"; import { Constants, FilterConstants, FilterMap, FilterPreset } from "../constants"; -import { mapParams,formatters, groupingBy, periodManagement } from "src/app/shared/util"; +import { mapParams, formatters, groupingBy, periodManagement } from "src/app/shared/util"; import { application, makePeriod } from "src/environments/environment"; import { FilterService } from "src/app/shared/services/filter.service"; @@ -36,11 +36,9 @@ export class StatsAppComponent implements OnInit, OnDestroy { env: any; name: string; - start: any; - end: any; - DEFAULT_START: Date; - DEFAULT_END: Date; - advancedParams: Partial<{ [key: string]: any }> ={} + start: Date; + end: Date; + advancedParams: Partial<{ [key: string]: any }> = {} focusFieldName: any; requests: { [key: string]: { observable: Observable, data?: any[], isLoading?: boolean } } = {}; @@ -54,11 +52,11 @@ export class StatsAppComponent implements OnInit, OnDestroy { this.name = v.params.name; this.env = v.queryParams.env || application.default_env; - this.start = v.queryParams.start || (application.dashboard.app.default_period || application.dashboard.default_period || makePeriod(6)).start.toISOString(); - this.end = v.queryParams.end || (application.dashboard.app.default_period || application.dashboard.default_period || makePeriod(6)).end.toISOString(); - this.patchDateValue(this.start, this.end); + this.start = v.queryParams.start ? new Date(v.queryParams.start) : (application.dashboard.app.default_period || application.dashboard.default_period || makePeriod(6)).start; + this.end = v.queryParams.end ? new Date(v.queryParams.end) : (application.dashboard.app.default_period || application.dashboard.default_period || makePeriod(6, 1)).end; + this.patchDateValue(this.start, new Date(this.end.getFullYear(), this.end.getMonth(), this.end.getDate() - 1)); this.init(); - this._location.replaceState(`${this._router.url.split('?')[0]}?env=${this.env}&start=${this.start}&end=${this.end}`) + this._location.replaceState(`${this._router.url.split('?')[0]}?env=${this.env}&start=${this.start.toISOString()}&end=${this.end.toISOString()}`) } }); @@ -75,12 +73,12 @@ export class StatsAppComponent implements OnInit, OnDestroy { init(): void { let start = this.serverFilterForm.getRawValue().dateRangePicker.start; - let end = new Date(this.serverFilterForm.getRawValue().dateRangePicker.end); + let end = this.serverFilterForm.getRawValue().dateRangePicker.end; end.setDate(end.getDate() + 1); let advancedParams = this.advancedParams - if(advancedParams){ - advancedParams = mapParams(this.filterConstants.STATS_APP,advancedParams); + if (advancedParams) { + advancedParams = mapParams(this.filterConstants.STATS_APP, advancedParams); } this.requests = this.APP_REQUEST(this.name, this.env, start, end, advancedParams); @@ -101,11 +99,12 @@ export class StatsAppComponent implements OnInit, OnDestroy { if (this.serverFilterForm.valid) { let start = this.serverFilterForm.getRawValue().dateRangePicker.start; let end = new Date(this.serverFilterForm.getRawValue().dateRangePicker.end); - if (start.toISOString() != this._activatedRoute.snapshot?.queryParams['start'] || end.toISOString() != this._activatedRoute.snapshot?.queryParams['end']) { + let excludedEnd = new Date(end.getFullYear(), end.getMonth(), end.getDate() + 1) + if (start.toISOString() != this.start.toISOString() || excludedEnd.toISOString() != this.end.toISOString()) { this._router.navigate([], { relativeTo: this._activatedRoute, queryParamsHandling: 'merge', - queryParams: { start: start.toISOString(), end: end.toISOString() } + queryParams: { start: start.toISOString(), end: excludedEnd.toISOString() } }) } else { this.init(); @@ -116,8 +115,8 @@ export class StatsAppComponent implements OnInit, OnDestroy { patchDateValue(start: Date, end: Date) { this.serverFilterForm.patchValue({ dateRangePicker: { - start: new Date(start), - end: new Date(end) + start: start, + end: end } }, { emitEvent: false }); } @@ -132,7 +131,7 @@ export class StatsAppComponent implements OnInit, OnDestroy { } } - APP_REQUEST = (name: string, env: string, start: Date, end: Date, advancedParams:FilterMap) => { + APP_REQUEST = (name: string, env: string, start: Date, end: Date, advancedParams: FilterMap) => { let now = new Date(); var groupedBy = periodManagement(start, end); return { @@ -161,10 +160,10 @@ export class StatsAppComponent implements OnInit, OnDestroy { }).slice(0, 5).flatMap(r => r.data); return results; }), - map((r: any[]) => { - formatters[groupedBy](r, this._datePipe); - return r; - })) + map((r: any[]) => { + formatters[groupedBy](r, this._datePipe); + return r; + })) }, repartitionApiBar: { observable: this._statsService.getSessionApi({ 'column': "count_succes:countSucces,count_error_client:countErrorClient,count_error_server:countErrorServer,api_name", 'app_name': name, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'environement': env, 'api_name.not': 'null', 'order': 'count.desc', ...advancedParams }).pipe(map((d: any) => d.slice(0, 5))) }, dependentsTable: { observable: this._statsService.getSessionApi({ 'column': "count:count,count_succes:countSucces,count_error_client:countErrClient,count_error_server:countErrServer,apisession2.app_name:name", "apisession.id": "out.parent", "out.id": "apisession2.id", 'apisession.app_name': name, 'apisession.start.ge': start.toISOString(), 'apisession.start.lt': end.toISOString(), 'apisession2.start.ge': start.toISOString(), 'apisession2.start.lt': end.toISOString(), 'environement': env, 'apisession2.app_name.not': 'null', 'order': 'count.desc', ...advancedParams }) }, @@ -173,58 +172,58 @@ export class StatsAppComponent implements OnInit, OnDestroy { }; }; - resetFilters(){ + resetFilters() { this.patchDateValue((application.dashboard.api.default_period || application.dashboard.default_period || makePeriod(6)).start, - (application.dashboard.api.default_period || application.dashboard.default_period || makePeriod(6)).end); + (application.dashboard.api.default_period || application.dashboard.default_period || makePeriod(6, 1)).end); this.advancedParams = {}; this._filter.setFilterMap({}) - } + } filtersSupplier(): BehaviorSubject { //change - return new BehaviorSubject({}); + return new BehaviorSubject({}); } handlePresetSelection(filterPreset: FilterPreset) { - const formControlNamelist = Object.keys(this.serverFilterForm.controls); - Object.entries(filterPreset.values).reduce((accumulator: any, [key, value]) => { + const formControlNamelist = Object.keys(this.serverFilterForm.controls); + Object.entries(filterPreset.values).reduce((accumulator: any, [key, value]) => { - if (formControlNamelist.includes(key)) { - this.serverFilterForm.patchValue({ - [key]: value - }) - delete filterPreset.values[key]; - } - },{}) - this.advancedParams = filterPreset.values - this._filter.setFilterMap(this.advancedParams); - this.search() + if (formControlNamelist.includes(key)) { + this.serverFilterForm.patchValue({ + [key]: value + }) + delete filterPreset.values[key]; + } + }, {}) + this.advancedParams = filterPreset.values + this._filter.setFilterMap(this.advancedParams); + this.search() } handlePresetSelectionReset() { - this.resetFilters(); - this.search(); + this.resetFilters(); + this.search(); } - handleFilterReset(){ - this.resetFilters(); + handleFilterReset() { + this.resetFilters(); } focusField(fieldName: string) { - this.focusFieldName = [fieldName]; + this.focusFieldName = [fieldName]; } handledialogclose(filterMap: FilterMap) { - this.advancedParams = filterMap; - this._filter.setFilterMap(this.advancedParams); - this.search() + this.advancedParams = filterMap; + this._filter.setFilterMap(this.advancedParams); + this.search() } handleRemovedFilter(filterName: string) { - if(this.advancedParams[filterName]){ - delete this.advancedParams[filterName]; - this._filter.setFilterMap(this.advancedParams); - } + if (this.advancedParams[filterName]) { + delete this.advancedParams[filterName]; + this._filter.setFilterMap(this.advancedParams); + } } } \ No newline at end of file diff --git a/src/app/views/stats-database/stats-database.component.ts b/src/app/views/stats-database/stats-database.component.ts index d412599..f2f0e14 100644 --- a/src/app/views/stats-database/stats-database.component.ts +++ b/src/app/views/stats-database/stats-database.component.ts @@ -42,9 +42,9 @@ export class StatsDatabaseComponent implements OnInit { exceptions: any[]; dbInfo: any[] = []; userInfo: any[]; + start: Date; + end: Date; doresetServerFormValue: boolean = false; - DEFAULT_START: Date; - DEFAULT_END: Date; displayedColumns: string[] = ['name']; dataSource: MatTableDataSource<{ name: string }> = new MatTableDataSource([]); @@ -60,12 +60,12 @@ export class StatsDatabaseComponent implements OnInit { this.db = v.params.name; this.env = v.queryParams.env || application.default_env; - let start = v.queryParams.start || (application.dashboard.database.default_period || application.dashboard.default_period || makePeriod(6)).start.toISOString(); - let end = v.queryParams.end || (application.dashboard.database.default_period || application.dashboard.default_period || makePeriod(6)).end.toISOString(); + this.start = v.queryParams.start ? new Date(v.queryParams.start) : (application.dashboard.database.default_period || application.dashboard.default_period || makePeriod(6)).start; + this.end = v.queryParams.end ? new Date(v.queryParams.end) : (application.dashboard.database.default_period || application.dashboard.default_period || makePeriod(6, 1)).end; - this.patchDateValue(start, end); + this.patchDateValue(this.start, new Date(this.end.getFullYear(), this.end.getMonth(), this.end.getDate() - 1)); this.init(); - this._location.replaceState(`${this._router.url.split('?')[0]}?env=${this.env}&start=${start}&end=${end}`) + this._location.replaceState(`${this._router.url.split('?')[0]}?env=${this.env}&start=${this.start.toISOString()}&end=${this.end.toISOString()}`) }, error: (err) => { console.log(err) @@ -100,12 +100,13 @@ export class StatsDatabaseComponent implements OnInit { search() { if (this.serverFilterForm.valid) { let start = this.serverFilterForm.getRawValue().dateRangePicker.start; - let end = new Date(this.serverFilterForm.getRawValue().dateRangePicker.end); - if (start.toISOString() != this._activatedRoute.snapshot?.queryParams['start'] || end.toISOString() != this._activatedRoute.snapshot?.queryParams['end']) { + let end = this.serverFilterForm.getRawValue().dateRangePicker.end; + let excludedEnd = new Date(end.getFullYear(), end.getMonth(), end.getDate() + 1) + if (start.toISOString() != this.start.toISOString() || excludedEnd.toISOString() != this.end.toISOString()) { this._router.navigate([], { relativeTo: this._activatedRoute, queryParamsHandling: 'merge', - queryParams: { start: start.toISOString(), end: end.toISOString() } + queryParams: { start: start.toISOString(), end: excludedEnd.toISOString() } }) } else { this.init(); @@ -120,7 +121,7 @@ export class StatsDatabaseComponent implements OnInit { init() { this.dataIsLoading = true; let start = this.serverFilterForm.getRawValue().dateRangePicker.start; - let end = new Date(this.serverFilterForm.getRawValue().dateRangePicker.end); + let end = this.serverFilterForm.getRawValue().dateRangePicker.end; end.setDate(end.getDate() + 1); this.requests = this.DB_REQUEST(this.db, this.env, start, end) Object.keys(this.requests).forEach(k => { @@ -162,8 +163,8 @@ export class StatsDatabaseComponent implements OnInit { patchDateValue(start: Date, end: Date) { this.serverFilterForm.patchValue({ dateRangePicker: { - start: new Date(start), - end: new Date(end) + start: start, + end: end } }, { emitEvent: false }); } diff --git a/src/app/views/stats-user/stats-user.component.ts b/src/app/views/stats-user/stats-user.component.ts index ad7bcbf..f79340e 100644 --- a/src/app/views/stats-user/stats-user.component.ts +++ b/src/app/views/stats-user/stats-user.component.ts @@ -8,7 +8,7 @@ import { BehaviorSubject, Observable, Subscription, combineLatest, finalize, map import { Constants, FilterConstants, FilterMap, FilterPreset } from "../constants"; import { application, makePeriod } from "src/environments/environment"; import { FilterService } from "src/app/shared/services/filter.service"; -import { mapParams, formatters, periodManagement } from "src/app/shared/util"; +import { mapParams, formatters, periodManagement } from "src/app/shared/util"; @Component({ templateUrl: './stats-user.component.html', @@ -36,18 +36,14 @@ export class StatsUserComponent implements OnInit, OnDestroy { env: any; name: string; - DEFAULT_START: Date; - DEFAULT_END: Date; - advancedParams: Partial<{ [key: string]: any }> ={} + start: Date; + end: Date; + advancedParams: Partial<{ [key: string]: any }> = {} focusFieldName: any; requests: { [key: string]: { observable: Observable, data?: any[], isLoading?: boolean } } = {}; constructor() { - let now = new Date(); - this.DEFAULT_START = new Date(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate() - 6); - this.DEFAULT_END = new Date(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate()); - combineLatest({ params: this._activatedRoute.params, queryParams: this._activatedRoute.queryParams @@ -55,11 +51,11 @@ export class StatsUserComponent implements OnInit, OnDestroy { next: (v: { params: Params, queryParams: Params }) => { this.name = v.params.name; this.env = v.queryParams.env || application.default_env; - let start = v.queryParams.start || (application.dashboard.database.default_period || application.dashboard.default_period || makePeriod(6)).start.toISOString(); - let end = v.queryParams.end || (application.dashboard.database.default_period || application.dashboard.default_period || makePeriod(6)).end.toISOString(); - this.patchDateValue(start, end); + this.start = v.queryParams.start ? new Date(v.queryParams.start) : (application.dashboard.database.default_period || application.dashboard.default_period || makePeriod(6)).start; + this.end = v.queryParams.end ? new Date(v.queryParams.end) : (application.dashboard.database.default_period || application.dashboard.default_period || makePeriod(6, 1)).end; + this.patchDateValue(this.start, this.end); this.init(); - this._location.replaceState(`${this._router.url.split('?')[0]}?env=${this.env}&start=${start}&end=${end}`) + this._location.replaceState(`${this._router.url.split('?')[0]}?env=${this.env}&start=${this.start.toISOString()}&end=${this.end.toISOString()}`) } }); @@ -75,11 +71,11 @@ export class StatsUserComponent implements OnInit, OnDestroy { init(): void { let start = this.serverFilterForm.getRawValue().dateRangePicker.start; - let end = new Date(this.serverFilterForm.getRawValue().dateRangePicker.end); + let end = this.serverFilterForm.getRawValue().dateRangePicker.end; end.setDate(end.getDate() + 1); let advancedParams = this.advancedParams; - if(advancedParams){ - advancedParams = mapParams(this.filterConstants.STATS_APP,advancedParams); + if (advancedParams) { + advancedParams = mapParams(this.filterConstants.STATS_APP, advancedParams); } this.requests = this.USER_REQUEST(this.name, this.env, start, end, advancedParams); @@ -99,12 +95,13 @@ export class StatsUserComponent implements OnInit, OnDestroy { search() { if (this.serverFilterForm.valid) { let start = this.serverFilterForm.getRawValue().dateRangePicker.start; - let end = new Date(this.serverFilterForm.getRawValue().dateRangePicker.end); - if (start.toISOString() != this._activatedRoute.snapshot?.queryParams['start'] || end.toISOString() != this._activatedRoute.snapshot?.queryParams['end']) { + let end = this.serverFilterForm.getRawValue().dateRangePicker.end; + let excludedEnd = new Date(end.getFullYear(), end.getMonth(), end.getDate() + 1) + if (start.toISOString() != this.start.toISOString() || excludedEnd.toISOString() != this.end.toISOString()) { this._router.navigate([], { relativeTo: this._activatedRoute, queryParamsHandling: 'merge', - queryParams: { start: start.toISOString(), end: end.toISOString() } + queryParams: { start: start.toISOString(), end: excludedEnd.toISOString() } }) } else { this.init(); @@ -116,14 +113,14 @@ export class StatsUserComponent implements OnInit, OnDestroy { patchDateValue(start: Date, end: Date) { this.serverFilterForm.patchValue({ dateRangePicker: { - start: new Date(start), - end: new Date(end) + start: start, + end: end } }, { emitEvent: false }); } // Stats en fonction du navigateur et du systeme - USER_REQUEST = (name: string, env: string, start: Date, end: Date, advancedParams:FilterMap) => { + USER_REQUEST = (name: string, env: string, start: Date, end: Date, advancedParams: FilterMap) => { let now = new Date(); var groupedBy = periodManagement(start, end); return { @@ -141,59 +138,59 @@ export class StatsUserComponent implements OnInit, OnDestroy { }; } - resetFilters(){ + resetFilters() { this.patchDateValue((application.dashboard.api.default_period || application.dashboard.default_period || makePeriod(6)).start, - (application.dashboard.api.default_period || application.dashboard.default_period || makePeriod(6)).end); - this.advancedParams = {}; - this._filter.setFilterMap({}) - } + (application.dashboard.api.default_period || application.dashboard.default_period || makePeriod(6, 1)).end); + this.advancedParams = {}; + this._filter.setFilterMap({}) + } - filtersSupplier(): BehaviorSubject { //change - return new BehaviorSubject({}); - } + filtersSupplier(): BehaviorSubject { //change + return new BehaviorSubject({}); + } - handlePresetSelection(filterPreset: FilterPreset) { + handlePresetSelection(filterPreset: FilterPreset) { console.log(filterPreset); const formControlNamelist = Object.keys(this.serverFilterForm.controls); Object.entries(filterPreset.values).reduce((accumulator: any, [key, value]) => { - if (formControlNamelist.includes(key)) { - this.serverFilterForm.patchValue({ - [key]: value - }) - delete filterPreset.values[key]; - } - },{}) + if (formControlNamelist.includes(key)) { + this.serverFilterForm.patchValue({ + [key]: value + }) + delete filterPreset.values[key]; + } + }, {}) this.advancedParams = filterPreset.values this._filter.setFilterMap(this.advancedParams); this.search() - } + } - handlePresetSelectionReset() { + handlePresetSelectionReset() { this.resetFilters(); this.search(); - } + } - handleFilterReset(){ + handleFilterReset() { this.resetFilters(); - } + } - focusField(fieldName: string) { + focusField(fieldName: string) { this.focusFieldName = [fieldName]; - } + } - handledialogclose(filterMap: FilterMap) { + handledialogclose(filterMap: FilterMap) { this.advancedParams = filterMap; this._filter.setFilterMap(this.advancedParams); this.search() - } + } - handleRemovedFilter(filterName: string) { - if(this.advancedParams[filterName]){ - delete this.advancedParams[filterName]; - this._filter.setFilterMap(this.advancedParams); + handleRemovedFilter(filterName: string) { + if (this.advancedParams[filterName]) { + delete this.advancedParams[filterName]; + this._filter.setFilterMap(this.advancedParams); } - } + } } \ No newline at end of file diff --git a/src/environments/environment.ts b/src/environments/environment.ts index 099aae8..cfd4153 100644 --- a/src/environments/environment.ts +++ b/src/environments/environment.ts @@ -13,14 +13,14 @@ export const application: Application = { default_env: 'prd', session: { api: { - default_period: makePeriod(0) + default_period: makePeriod(0, 1) }, main: { - default_period: makePeriod(0) + default_period: makePeriod(0, 1) } }, dashboard: { - default_period: makePeriod(6), + default_period: makePeriod(6, 1), api : { default_period: undefined }, From 1ade10ab5b89d4acdd9261815b7dfa549f7ddaa9 Mon Sep 17 00:00:00 2001 From: fufuu Date: Tue, 28 May 2024 16:15:00 +0200 Subject: [PATCH 007/126] period url --- src/app/views/session-api/session-api.component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/views/session-api/session-api.component.ts b/src/app/views/session-api/session-api.component.ts index da3b5da..6536ec0 100644 --- a/src/app/views/session-api/session-api.component.ts +++ b/src/app/views/session-api/session-api.component.ts @@ -62,7 +62,7 @@ export class SessionApiComponent implements OnInit, OnDestroy { .subscribe({ next: (params: Params) => { this.params.env = params['env'] || application.default_env; - this.params.start = params['start'] ? new Date(params['start']) : (application.session.api.default_period || makePeriod(0, 1)).start; + this.params.start = params['start'] ? new Date(params['start']) : (application.session.api.default_period || makePeriod(0)).start; this.params.end = params['end'] ? new Date(params['end']) : (application.session.api.default_period || makePeriod(0, 1)).end; this.params.serveurs = Array.isArray(params['appname']) ? params['appname'] : [params['appname'] || '']; if (this.params.serveurs[0] != '') { From 9a5360c267aa4548e4fe03713ee68a189d80b31c Mon Sep 17 00:00:00 2001 From: YoussefDahi Date: Tue, 28 May 2024 16:19:33 +0200 Subject: [PATCH 008/126] Exception? --- .../session-detail/session-detail.component.html | 6 +++--- .../views/session-detail/session-detail.component.ts | 9 +++++---- .../views/session-main/session-main.component.html | 4 ++-- src/app/views/tree/tree.component.ts | 12 ++++++------ 4 files changed, 16 insertions(+), 15 deletions(-) diff --git a/src/app/views/session-detail/session-detail.component.html b/src/app/views/session-detail/session-detail.component.html index 1d90e42..8b6cb7e 100644 --- a/src/app/views/session-detail/session-detail.component.html +++ b/src/app/views/session-detail/session-detail.component.html @@ -34,8 +34,8 @@
- warning{{selectedSession?.exception.message || selectedSession?.exception?.classname}} + [matTooltip]="selectedSession?.exception?.classname" TooltipPosition="below"> + warning{{selectedSession?.exception?.message || selectedSession?.exception?.classname}}
@@ -250,7 +250,7 @@ - + !a.exception.classname && !a.exception.message); + return query.actions.every((a:any) => !a?.exception?.classname && !a?.exception?.message); } getCommand(commands:string[]):string{ diff --git a/src/app/views/session-main/session-main.component.html b/src/app/views/session-main/session-main.component.html index c047e03..cdf7a7e 100644 --- a/src/app/views/session-main/session-main.component.html +++ b/src/app/views/session-main/session-main.component.html @@ -36,8 +36,8 @@ - + diff --git a/src/app/views/tree/tree.component.ts b/src/app/views/tree/tree.component.ts index a8e283d..bc283b8 100644 --- a/src/app/views/tree/tree.component.ts +++ b/src/app/views/tree/tree.component.ts @@ -282,24 +282,24 @@ export class TreeComponent implements OnDestroy { modal += `Thread : ${value.threadName || 'N/A'}
` modal += `Schema : ${value.schema || 'N/A'}
` modal += `Hôte : ${value.host || 'N/A'}
` - value.actions.forEach((action: any) => { + /*value.actions.forEach((action: any) => { if (action.exception) { modal += `${action.exception.classname || ''} ${action.exception.message || ''}` } - }); + });*/ // removed this since we dont get the actions from the back break; case 'api': modal += ` ${value.remoteTrace.status}     ${value.remoteTrace.path}
` modal += `Thread : ${value.threadName || 'N/A'}
` modal += `Latence: ${self.UtilInstance.getElapsedTime(value.remoteTrace?.start, value.start)}s
`; - modal += `${value.remoteTrace.exception.classname || ''} ${value.remoteTrace.exception.message || ''}
` + modal += `${value.remoteTrace?.exception?.classname || ''} ${value.remoteTrace?.exception?.message || ''}
` // modal += ` ${self.UtilInstance.getElapsedTime(value.remoteTrace.end, value.remoteTrace.start)}s`; break; case 'unknown': modal += `Thread : ${value.threadName || 'N/A'}
` - modal += `${cell.source.value.data[0].exception?.classname || ''} ${cell.source.value.data[0].exception?.message || ''}` + modal += `${cell.source.value.data[0]?.exception?.classname || ''} ${cell.source.value.data[0]?.exception?.message || ''}` break; default: @@ -666,12 +666,12 @@ export class TreeComponent implements OnDestroy { getActionsCount(actionsList: any) { let e = actionsList.reduce((acc: any, item: any) => { let key = item.type + "_succes" - if (item.exception.classname || item.exception.message) + if (item?.exception?.classname || item?.exception?.message) key = item.type + "_failure"; if (!acc[key]) { acc[key] = {} - acc[key].failed = !!(item.exception.classname || item.exception.message) + acc[key].failed = !!(item?.exception?.classname || item?.exception?.message) acc[key].name = item.type; acc[key].count = 0 } From 615b62c77e609aaa10d40bdd01a725384b02c931 Mon Sep 17 00:00:00 2001 From: YoussefDahi Date: Tue, 28 May 2024 17:15:38 +0200 Subject: [PATCH 009/126] disabeled link to dbrequestcomponenet --- src/app/views/session-detail/session-detail.component.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/views/session-detail/session-detail.component.html b/src/app/views/session-detail/session-detail.component.html index 8b6cb7e..4bee123 100644 --- a/src/app/views/session-detail/session-detail.component.html +++ b/src/app/views/session-detail/session-detail.component.html @@ -250,7 +250,7 @@ - + Date: Wed, 29 May 2024 10:42:04 +0200 Subject: [PATCH 010/126] periods dashboard --- src/app/views/stats-api/stats-api.component.ts | 3 +-- src/app/views/stats-app/stats-app.component.ts | 5 +---- src/app/views/stats-database/stats-database.component.ts | 2 -- src/app/views/stats-user/stats-user.component.ts | 4 ---- 4 files changed, 2 insertions(+), 12 deletions(-) diff --git a/src/app/views/stats-api/stats-api.component.ts b/src/app/views/stats-api/stats-api.component.ts index 16df59f..9bad160 100644 --- a/src/app/views/stats-api/stats-api.component.ts +++ b/src/app/views/stats-api/stats-api.component.ts @@ -71,8 +71,7 @@ export class StatsApiComponent implements OnInit, OnDestroy { init(): void { let start = this.serverFilterForm.getRawValue().dateRangePicker.start; - let end = new Date(this.serverFilterForm.getRawValue().dateRangePicker.end); - end.setDate(end.getDate() + 1); + let end = this.serverFilterForm.getRawValue().dateRangePicker.end; let advancedParams = this.advancedParams; if (advancedParams) { advancedParams = mapParams(this.filterConstants.STATS_API, advancedParams); diff --git a/src/app/views/stats-app/stats-app.component.ts b/src/app/views/stats-app/stats-app.component.ts index c7bc382..f53a823 100644 --- a/src/app/views/stats-app/stats-app.component.ts +++ b/src/app/views/stats-app/stats-app.component.ts @@ -74,13 +74,10 @@ export class StatsAppComponent implements OnInit, OnDestroy { init(): void { let start = this.serverFilterForm.getRawValue().dateRangePicker.start; let end = this.serverFilterForm.getRawValue().dateRangePicker.end; - end.setDate(end.getDate() + 1); - let advancedParams = this.advancedParams if (advancedParams) { advancedParams = mapParams(this.filterConstants.STATS_APP, advancedParams); } - this.requests = this.APP_REQUEST(this.name, this.env, start, end, advancedParams); Object.keys(this.requests).forEach(k => { this.requests[k].data = []; @@ -98,7 +95,7 @@ export class StatsAppComponent implements OnInit, OnDestroy { search() { if (this.serverFilterForm.valid) { let start = this.serverFilterForm.getRawValue().dateRangePicker.start; - let end = new Date(this.serverFilterForm.getRawValue().dateRangePicker.end); + let end = this.serverFilterForm.getRawValue().dateRangePicker.end; let excludedEnd = new Date(end.getFullYear(), end.getMonth(), end.getDate() + 1) if (start.toISOString() != this.start.toISOString() || excludedEnd.toISOString() != this.end.toISOString()) { this._router.navigate([], { diff --git a/src/app/views/stats-database/stats-database.component.ts b/src/app/views/stats-database/stats-database.component.ts index f2f0e14..3629805 100644 --- a/src/app/views/stats-database/stats-database.component.ts +++ b/src/app/views/stats-database/stats-database.component.ts @@ -62,7 +62,6 @@ export class StatsDatabaseComponent implements OnInit { this.env = v.queryParams.env || application.default_env; this.start = v.queryParams.start ? new Date(v.queryParams.start) : (application.dashboard.database.default_period || application.dashboard.default_period || makePeriod(6)).start; this.end = v.queryParams.end ? new Date(v.queryParams.end) : (application.dashboard.database.default_period || application.dashboard.default_period || makePeriod(6, 1)).end; - this.patchDateValue(this.start, new Date(this.end.getFullYear(), this.end.getMonth(), this.end.getDate() - 1)); this.init(); this._location.replaceState(`${this._router.url.split('?')[0]}?env=${this.env}&start=${this.start.toISOString()}&end=${this.end.toISOString()}`) @@ -122,7 +121,6 @@ export class StatsDatabaseComponent implements OnInit { this.dataIsLoading = true; let start = this.serverFilterForm.getRawValue().dateRangePicker.start; let end = this.serverFilterForm.getRawValue().dateRangePicker.end; - end.setDate(end.getDate() + 1); this.requests = this.DB_REQUEST(this.db, this.env, start, end) Object.keys(this.requests).forEach(k => { this.requests[k].data = []; diff --git a/src/app/views/stats-user/stats-user.component.ts b/src/app/views/stats-user/stats-user.component.ts index f79340e..57a44bd 100644 --- a/src/app/views/stats-user/stats-user.component.ts +++ b/src/app/views/stats-user/stats-user.component.ts @@ -72,12 +72,10 @@ export class StatsUserComponent implements OnInit, OnDestroy { init(): void { let start = this.serverFilterForm.getRawValue().dateRangePicker.start; let end = this.serverFilterForm.getRawValue().dateRangePicker.end; - end.setDate(end.getDate() + 1); let advancedParams = this.advancedParams; if (advancedParams) { advancedParams = mapParams(this.filterConstants.STATS_APP, advancedParams); } - this.requests = this.USER_REQUEST(this.name, this.env, start, end, advancedParams); Object.keys(this.requests).forEach(k => { this.requests[k].data = []; @@ -151,8 +149,6 @@ export class StatsUserComponent implements OnInit, OnDestroy { } handlePresetSelection(filterPreset: FilterPreset) { - console.log(filterPreset); - const formControlNamelist = Object.keys(this.serverFilterForm.controls); Object.entries(filterPreset.values).reduce((accumulator: any, [key, value]) => { From f1789b20942c6b7d9e16eed39978419fd5c6575e Mon Sep 17 00:00:00 2001 From: fufuu Date: Wed, 29 May 2024 10:43:57 +0200 Subject: [PATCH 011/126] periods dashboard --- src/app/views/session-api/session-api.component.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/app/views/session-api/session-api.component.ts b/src/app/views/session-api/session-api.component.ts index 6536ec0..e0db93d 100644 --- a/src/app/views/session-api/session-api.component.ts +++ b/src/app/views/session-api/session-api.component.ts @@ -128,7 +128,6 @@ export class SessionApiComponent implements OnInit, OnDestroy { 'end': this.params.end.toISOString(), 'lazy': false }; - console.log(params) if(this.advancedParams){ Object.assign(params, this.advancedParams); } From 9d1c16adcbc67301641dd752cd84fd22776de132 Mon Sep 17 00:00:00 2001 From: fufuu Date: Wed, 29 May 2024 11:08:30 +0200 Subject: [PATCH 012/126] clean --- src/app/views/session-api/session-api.component.ts | 3 --- src/app/views/session-main/session-main.component.ts | 4 ---- 2 files changed, 7 deletions(-) diff --git a/src/app/views/session-api/session-api.component.ts b/src/app/views/session-api/session-api.component.ts index e0db93d..2d7bad8 100644 --- a/src/app/views/session-api/session-api.component.ts +++ b/src/app/views/session-api/session-api.component.ts @@ -29,7 +29,6 @@ export class SessionApiComponent implements OnInit, OnDestroy { dataSource: MatTableDataSource = new MatTableDataSource(); isLoading = true; serverNameIsLoading = true; - statusFilter: string[] = []; subscriptions: Subscription[] = []; serverFilterForm = new FormGroup({ appname: new FormControl([""]), @@ -38,8 +37,6 @@ export class SessionApiComponent implements OnInit, OnDestroy { end: new FormControl(null, [Validators.required]), }), }); - DEFAULT_START: Date; - DEFAULT_END: Date; filterTable = new Map(); diff --git a/src/app/views/session-main/session-main.component.ts b/src/app/views/session-main/session-main.component.ts index 980774c..e4f498a 100644 --- a/src/app/views/session-main/session-main.component.ts +++ b/src/app/views/session-main/session-main.component.ts @@ -21,7 +21,6 @@ import { FilterService } from 'src/app/shared/services/filter.service'; }) export class SessionMainComponent implements OnInit, OnDestroy { filterConstants = FilterConstants; - currentEnv: string; utilInstance: Utils = new Utils(); displayedColumns: string[] = ['status', 'app_name', 'session', 'location', 'start', 'Durée', 'user']; dataSource: MatTableDataSource = new MatTableDataSource(); @@ -35,9 +34,6 @@ export class SessionMainComponent implements OnInit, OnDestroy { }); subscription: Subscription; isLoading = false; - - DEFAULT_START: Date; - DEFAULT_END: Date; advancedParams: Partial<{[key:string]:any}> focusFieldName: any From 0e21224406f4b4f38c9d38fc932bc6f74992fd7c Mon Sep 17 00:00:00 2001 From: fufuu Date: Wed, 29 May 2024 11:21:33 +0200 Subject: [PATCH 013/126] clean --- src/app/shared/model/conf.model.ts | 1 - src/app/shared/model/trace.model.ts | 2 -- src/app/shared/services/filter.service.ts | 3 +-- src/app/shared/services/trace.service.ts | 1 - 4 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/app/shared/model/conf.model.ts b/src/app/shared/model/conf.model.ts index 372be97..33a5ef6 100644 --- a/src/app/shared/model/conf.model.ts +++ b/src/app/shared/model/conf.model.ts @@ -2,7 +2,6 @@ export interface Application { default_env: string; session: Partial; dashboard: Partial; - } interface Session { diff --git a/src/app/shared/model/trace.model.ts b/src/app/shared/model/trace.model.ts index ad60ff1..b13559d 100644 --- a/src/app/shared/model/trace.model.ts +++ b/src/app/shared/model/trace.model.ts @@ -1,5 +1,3 @@ - - export interface IncomingRequest { id: string; method: string; diff --git a/src/app/shared/services/filter.service.ts b/src/app/shared/services/filter.service.ts index e3f568f..a93aafd 100644 --- a/src/app/shared/services/filter.service.ts +++ b/src/app/shared/services/filter.service.ts @@ -1,8 +1,7 @@ import { Injectable, OnDestroy, inject } from "@angular/core"; import { NavigationStart, Router } from "@angular/router"; import { BehaviorSubject, Observable, Subscription, catchError, combineLatest, first, map, of, throwError } from "rxjs"; -import { Filter, FilterPreset, FilterMap } from "src/app/views/constants"; - +import { FilterPreset, FilterMap } from "src/app/views/constants"; @Injectable({ providedIn: 'root' }) export class FilterService implements OnDestroy{ diff --git a/src/app/shared/services/trace.service.ts b/src/app/shared/services/trace.service.ts index bd53d77..ce362aa 100644 --- a/src/app/shared/services/trace.service.ts +++ b/src/app/shared/services/trace.service.ts @@ -1,7 +1,6 @@ import { HttpClient, HttpErrorResponse } from "@angular/common/http"; import { Injectable } from "@angular/core"; import { catchError, throwError } from "rxjs"; -import { environment } from "src/environments/environment"; @Injectable({ providedIn: 'root' }) export class TraceService { From 1b582c07e20d1701d16f750cf96765c248b51cca Mon Sep 17 00:00:00 2001 From: YoussefDahi Date: Wed, 29 May 2024 17:22:39 +0200 Subject: [PATCH 014/126] edit : -updated exception-table to show the number of exception not showing on table -updated dashboard to use newly added DBCOLUMN ERR to to get all the exceptions --- .../exception-table.component.html | 9 ++++---- .../exception-table.component.ts | 23 ++++++++++++------- .../session-detail.component.html | 2 +- .../session-detail.component.ts | 1 - .../views/stats-api/stats-api.component.ts | 2 +- .../views/stats-app/stats-app.component.ts | 2 +- .../stats-database.component.ts | 2 +- .../views/stats-user/stats-user.component.ts | 2 +- 8 files changed, 25 insertions(+), 18 deletions(-) diff --git a/src/app/shared/components/stats/exception-table/exception-table.component.html b/src/app/shared/components/stats/exception-table/exception-table.component.html index b20c2f7..4453d1b 100644 --- a/src/app/shared/components/stats/exception-table/exception-table.component.html +++ b/src/app/shared/components/stats/exception-table/exception-table.component.html @@ -11,14 +11,15 @@
- - + + - +
{{element.count}} {{element.message}} {{element.count}} {{element?.class || '[Class indisponible]'}}: {{element?.message || '[Message indisponible]'}} + +{{addExceptionCount}} Autres... +
-
diff --git a/src/app/shared/components/stats/exception-table/exception-table.component.ts b/src/app/shared/components/stats/exception-table/exception-table.component.ts index 7dbc640..50cb284 100644 --- a/src/app/shared/components/stats/exception-table/exception-table.component.ts +++ b/src/app/shared/components/stats/exception-table/exception-table.component.ts @@ -1,6 +1,7 @@ import { Component, Input, ViewChild } from "@angular/core"; import { MatPaginator } from "@angular/material/paginator"; import { MatTableDataSource } from "@angular/material/table"; +import { pipe } from "rxjs"; @Component({ selector: 'exception-table', @@ -9,16 +10,22 @@ import { MatTableDataSource } from "@angular/material/table"; }) export class ExceptionTableComponent { displayedColumns: string[] = ['message']; - dataSource: MatTableDataSource<{count:number, message: string }> = new MatTableDataSource([]); + dataSource: MatTableDataSource<{ count: number, message: string, class: string }> = new MatTableDataSource([]); + addExceptionCount: number = 0; - @ViewChild(MatPaginator) paginator: MatPaginator; - - @Input() set data(objects: any[]) { - if (objects?.length) { - this.dataSource = new MatTableDataSource(objects.map(r => { - return {count: r['COUNT'], message: r.errorMessage }; + @Input() set data(objects: any) { + if (objects?.length) { //.pipe(map((d: any) => d.slice(0, 5))) + this.dataSource = new MatTableDataSource(objects.slice(0, 5).map((r: any) => { + return { count: r['COUNT'], message: r?.errorMessage, class: r?.errorType }; })); - this.dataSource.paginator = this.paginator; + if (objects.length > 5) { + this.addExceptionCount = objects.reduce((acc: number, curr: any, i: number) => { + if (i >= 5 ) { + acc += curr['COUNT']; + } + return acc; + } , 0); + } } else { this.dataSource = new MatTableDataSource([]); } diff --git a/src/app/views/session-detail/session-detail.component.html b/src/app/views/session-detail/session-detail.component.html index 4bee123..23ec281 100644 --- a/src/app/views/session-detail/session-detail.component.html +++ b/src/app/views/session-detail/session-detail.component.html @@ -14,7 +14,7 @@
@@ -51,10 +54,10 @@ person
- - {{selectedSession?.user || "N/A"}} + + {{selectedSession?.user || "N/A"}} le {{( selectedSession?.start*1000 ) | date: 'dd/MM/yyyy à HH:mm:ss.SSS': 'fr' }}
@@ -64,7 +67,8 @@ {{selectedSession?.outDataSize}}o en {{ getElapsedTime(selectedSession?.end, selectedSession?.start) | number :'1.2-3'}}s
- {{selectedSession?.status}} + {{selectedSession?.status}} @@ -126,66 +130,104 @@ - +
+ + + search + + + + + done + + + + + error + + + + + warning + + + +
+
+
- - - - - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - -
- - Hôte - {{element['host']}}:{{element['port']}} - + + API - [{{element.method}}] -
- {{element['path']}} -
Hôte + {{element['host']}}:{{element['port']}} + Début -
- {{ (element.start*1000 |date:'dd/MM/yyyy')}} -
-
-
- {{ (element.start*1000 |date:'HH:mm:ss.SSS')}} -
-
API + [{{element.method}}] +
+ {{element['path']}} +
Durée - - {{getElapsedTime(element.end,element.start)| number :'1.2-3' }}s - - Début +
+ {{ (element.start*1000 |date:'dd/MM/yyyy')}} +
+
+
+ {{ (element.start*1000 |date:'HH:mm:ss.SSS')}} +
+
- + + Durée + + + {{getElapsedTime(element.end,element.start)| number :'1.2-3' }}s + + + + + + + + + +
+ + info + + Aucun résultat +
+ + + + + @@ -202,64 +244,69 @@ - +
+
- - - - - - - - + + + + + + + + - - - - + + + + - - - - + + + + + + + + + + + + +
- Hôte - {{element["host"] || 'N/A'}} + Hôte + {{element["host"] || 'N/A'}} BDD - {{getCommand(element.commands)}} -
- {{element["schema"] || 'N/A'}} -
BDD + {{getCommand(element.commands)}} +
+ {{element["schema"] || 'N/A'}} +
Début -
- {{ (element.start*1000 |date:'dd/MM/yyyy')}} -
-
-
- {{ (element.start*1000 |date:'HH:mm:ss.SSS')}} -
-
Début +
+ {{ (element.start*1000 |date:'dd/MM/yyyy')}} +
+
+
+ {{ (element.start*1000 |date:'HH:mm:ss.SSS')}} +
+
Durée + + {{getElapsedTime(element.end,element.start)| number :'1.2-3' || 'N/A'}}s + +
+ + - - Durée - - - {{getElapsedTime(element.end,element.start)| number :'1.2-3' || 'N/A'}}s - - - - - - - -
-
+
@@ -268,7 +315,7 @@
- +
@@ -280,6 +327,7 @@

selectedSession?.host}}

-
+
Chargement en cours...
\ No newline at end of file diff --git a/src/app/views/session-detail/session-detail.component.scss b/src/app/views/session-detail/session-detail.component.scss index 1c6733e..b10a13f 100644 --- a/src/app/views/session-detail/session-detail.component.scss +++ b/src/app/views/session-detail/session-detail.component.scss @@ -71,4 +71,7 @@ table { border-radius: 12px; font-size: 0.8em; } - \ No newline at end of file + +.searchwidth { + flex-grow: 1; +} \ No newline at end of file diff --git a/src/app/views/session-detail/session-detail.component.ts b/src/app/views/session-detail/session-detail.component.ts index 5f48f17..de418b2 100644 --- a/src/app/views/session-detail/session-detail.component.ts +++ b/src/app/views/session-detail/session-detail.component.ts @@ -1,12 +1,12 @@ -import { AfterContentInit, Component, ElementRef, Injectable, NgZone, OnDestroy, ViewChild} from '@angular/core'; +import { AfterContentInit, Component, ElementRef, Injectable, NgZone, OnDestroy, ViewChild } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; import { MatTableDataSource } from '@angular/material/table'; -import { ActivatedRoute, NavigationExtras, Router} from '@angular/router'; -import { Observable, Subscription, combineLatest} from "rxjs"; +import { ActivatedRoute, NavigationExtras, Router } from '@angular/router'; +import { Observable, Subscription, combineLatest } from "rxjs"; import { Timeline } from 'vis-timeline'; -import { ExceptionInfo, OutcomingQuery, OutcomingRequest, RunnableStage } from 'src/app/shared/model/trace.model'; +import { ExceptionInfo, OutcomingQuery, OutcomingRequest, RunnableStage } from 'src/app/shared/model/trace.model'; import { Utils } from 'src/app/shared/util'; -import { DatePipe, Location} from '@angular/common'; +import { DatePipe, Location } from '@angular/common'; import { MatPaginator } from '@angular/material/paginator'; import { MatSort } from '@angular/material/sort'; import { TraceService } from 'src/app/shared/services/trace.service'; @@ -35,7 +35,7 @@ export class SessionDetailComponent implements AfterContentInit, OnDestroy { selectedSession: any // IncomingRequest | Mainrequest | OutcomingRequest; selectedSessionType: string; sessionDetailSubscription: Observable; - sessionParent: {id : string, type : sessionType}; + sessionParent: { id: string, type: sessionType }; outcomingRequestList: any; outcomingQueryList: any; isComplete: boolean = true; @@ -49,9 +49,10 @@ export class SessionDetailComponent implements AfterContentInit, OnDestroy { container: any; dataTable: any; timeLine: any; - queryBySchema :any[]; - env:any; - pipe = new DatePipe('fr-FR') + queryBySchema: any[]; + env: any; + pipe = new DatePipe('fr-FR'); + filterTable = new Map(); @ViewChild('timeline') timelineContainer: ElementRef; @ViewChild('OutcomingRequestPaginator') outcomingRequestPaginator: MatPaginator; @ViewChild('OutcomingRequestSort') outcomingRequestSort: MatSort; @@ -73,14 +74,14 @@ export class SessionDetailComponent implements AfterContentInit, OnDestroy { next: ([params, queryParams]) => { this.env = queryParams.env || application.default_env; this.selectedSessionType = params.type; - switch(this.selectedSessionType){ - case "main": + switch (this.selectedSessionType) { + case "main": this.sessionDetailSubscription = this._traceService.getMainRequestById(params.id); - break; + break; case "api": this.sessionDetailSubscription = this._traceService.getIncomingRequestById(params.id); - break; - default : + break; + default: } this.getSessionById(params.id); this._location.replaceState(`${this._router.url.split('?')[0]}?env=${this.env}`) @@ -95,82 +96,97 @@ export class SessionDetailComponent implements AfterContentInit, OnDestroy { })*/ } + getSessionById(id: string) { + this.isLoading = true; + this.sessionDetailSubscription.subscribe({ + next: (d: any) => { + this.selectedSession = d; + if (this.selectedSession) { + this.selectedSession.type = this.selectedSessionType; + + // Api request list + this.outcomingRequestList = this.selectedSession.requests; + this.outcomingRequestdataSource = new MatTableDataSource(this.outcomingRequestList); + setTimeout(() => { this.outcomingRequestdataSource.paginator = this.outcomingRequestPaginator }); + setTimeout(() => { this.outcomingRequestdataSource.sort = this.outcomingRequestSort }); + this.outcomingRequestdataSource.sortingDataAccessor = (row: any, columnName: string) => { + if (columnName == "host") return row["host"] + ":" + row["port"] as string; + if (columnName == "start") return row['start'] as string; + if (columnName == "duree") return (row["end"] - row["start"]); + var columnValue = row[columnName as keyof any] as string; + return columnValue; + } + this.outcomingRequestdataSource.filterPredicate = (data: OutcomingRequest, filter: string) => { + var map: Map = new Map(JSON.parse(filter)); + let isMatch = true; + for (let [key, value] of map.entries()) { + if (key == 'filter') { + isMatch = isMatch && (value == '' || + (data.host?.toLowerCase().includes(value) || data.method?.toLowerCase().includes(value) || data.query?.toLowerCase().includes(value) || + data.path?.toLowerCase().includes(value))); + } else if (key == 'status') { + const s = data.status.toString(); + isMatch = isMatch && (!value.length || (value.some((status: any) => { + return s.startsWith(status[0]); + }))); + } + } + return isMatch; + } + this.outcomingRequestdataSource.filter = JSON.stringify(Array.from(this.filterTable.entries())); + setTimeout(() => { this.outcomingRequestdataSource.paginator.pageIndex = 0 }); + + // DB request list + this.outcomingQueryList = this.selectedSession.queries + this.outcomingQuerydataSource = new MatTableDataSource(this.outcomingQueryList); + setTimeout(() => { this.outcomingQuerydataSource.paginator = this.outcomingQueryPaginator }); + setTimeout(() => { this.outcomingQuerydataSource.sort = this.outcomingQuerySort }); + this.outcomingQuerydataSource.sortingDataAccessor = (row: any, columnName: string) => { + if (columnName == "duree") return (row["end"] - row["start"]) + var columnValue = row[columnName as keyof any] as string; + return columnValue; + } + this.groupQueriesBySchema(); + // Timeline + this.visjs(); - getSessionById(id: string) { - - this.isLoading = true; - this.sessionDetailSubscription.subscribe({ - next: (d: any) => { - this.selectedSession = d; - if (this.selectedSession) { - this.selectedSession.type = this.selectedSessionType; - - // Api request list - this.outcomingRequestList = this.selectedSession.requests; - this.outcomingRequestdataSource = new MatTableDataSource(this.outcomingRequestList); - setTimeout(() => { this.outcomingRequestdataSource.paginator = this.outcomingRequestPaginator }); - setTimeout(() => { this.outcomingRequestdataSource.sort = this.outcomingRequestSort }); - this.outcomingRequestdataSource.sortingDataAccessor = (row: any, columnName: string) => { - if (columnName == "host") return row["host"] + ":" + row["port"] as string; - if (columnName == "start") return row['start'] as string; - if (columnName == "duree") return (row["end"] - row["start"]); - var columnValue = row[columnName as keyof any] as string; - return columnValue; - } + // Check if parent exist + this.sessionParent = null; + if (this.selectedSession.type == "api") { + this._traceService.getSessionParentByChildId(id).subscribe({ + next: (data: { id: string, type: sessionType }) => { + this.sessionParent = data; + }, + error: err => console.log(err) + }) + } - // DB request list - this.outcomingQueryList = this.selectedSession.queries - this.outcomingQuerydataSource = new MatTableDataSource(this.outcomingQueryList); - setTimeout(() => { this.outcomingQuerydataSource.paginator = this.outcomingQueryPaginator }); - setTimeout(() => { this.outcomingQuerydataSource.sort = this.outcomingQuerySort }); - this.outcomingQuerydataSource.sortingDataAccessor = (row: any, columnName: string) => { - if (columnName == "duree") return (row["end"] - row["start"]) - var columnValue = row[columnName as keyof any] as string; - return columnValue; + this.isLoading = false; + this.isComplete = true; + } else { + this.isLoading = false; + this.isComplete = false; + // navigate to tab incoming } - - this.groupQueriesBySchema(); - - // Timeline - this.visjs(); - - // Check if parent exist - this.sessionParent = null; - if(this.selectedSession.type == "api"){ - this._traceService.getSessionParentByChildId(id).subscribe( { - next : (data: {id : string, type : sessionType}) =>{ - this.sessionParent = data; - }, - error : err => console.log(err) - }) - } - - this.isLoading = false; - this.isComplete = true; - } else { + }, + error: err => { this.isLoading = false; - this.isComplete= false; - // navigate to tab incoming } - }, - error: err => { - this.isLoading = false; - } }); } visjs() { - + let timeline_end = +this.selectedSession.end * 1000 let timeline_start = +this.selectedSession.start * 1000 let dataArray: any = [...this.selectedSession.requests, ...this.selectedSession.queries, ...this.selectedSession.stages.map((s: any) => ({ ...s, isStage: true }))]; - dataArray.splice(0, 0, {...this.selectedSession,isStage: true}) + dataArray.splice(0, 0, { ...this.selectedSession, isStage: true }) this.sortInnerArrayByDate(dataArray); @@ -193,17 +209,17 @@ export class SessionDetailComponent implements AfterContentInit, OnDestroy { let o = { id: c.hasOwnProperty('schema') ? -i : c.id, group: isWebapp ? 0 : c.threadName, - content:c.hasOwnProperty('isStage') ? '' : (c.schema || c.host || 'N/A'), + content: c.hasOwnProperty('isStage') ? '' : (c.schema || c.host || 'N/A'), start: c.start * 1000, end: c.end * 1000, title: `${this.pipe.transform(new Date(c.start * 1000), 'HH:mm:ss.SSS')} - ${this.pipe.transform(new Date(c.end * 1000), 'HH:mm:ss.SSS')}

${c[title]}: ${this.getElapsedTime(c.end, c.start).toFixed(3)}s

`, - className: c.hasOwnProperty('schema') ? "bdd" : !c.hasOwnProperty('isStage') ? "rest" : "", - type: c.hasOwnProperty('isStage') ? 'background' : 'range' + className: c.hasOwnProperty('schema') ? "bdd" : !c.hasOwnProperty('isStage') ? "rest" : "", + type: c.hasOwnProperty('isStage') ? 'background' : 'range' } - if (o.end > timeline_end){ + if (o.end > timeline_end) { timeline_end = o.end - } + } return o; }) @@ -245,25 +261,25 @@ export class SessionDetailComponent implements AfterContentInit, OnDestroy { } - selectedRequest(event:MouseEvent,row: any) { - if(row){ - if( event.ctrlKey){ - this._router.open(`#/session/api/${row}`,'_blank',) - }else { - this._router.navigate(['/session', 'api', row],{queryParams:{env:this.env}}); // TODO remove env FIX BUG - } + selectedRequest(event: MouseEvent, row: any) { + if (row) { + if (event.ctrlKey) { + this._router.open(`#/session/api/${row}`, '_blank',) + } else { + this._router.navigate(['/session', 'api', row], { queryParams: { env: this.env } }); // TODO remove env FIX BUG + } } } - selectedQuery(event: MouseEvent, queryId:any){ // TODO finish this - if(queryId){ - if( event.ctrlKey){ - this._router.open(`#/session/${this.selectedSession.type}/${this.selectedSession.id}/db/${queryId}`,'_blank',) - }else { - this._router.navigate(['/session', this.selectedSession.type, this.selectedSession.id, 'db', queryId],{ - queryParams:{env:this.env} + selectedQuery(event: MouseEvent, queryId: any) { // TODO finish this + if (queryId) { + if (event.ctrlKey) { + this._router.open(`#/session/${this.selectedSession.type}/${this.selectedSession.id}/db/${queryId}`, '_blank',) + } else { + this._router.navigate(['/session', this.selectedSession.type, this.selectedSession.id, 'db', queryId], { + queryParams: { env: this.env } }); - } + } } } @@ -314,16 +330,16 @@ export class SessionDetailComponent implements AfterContentInit, OnDestroy { }); } - groupQueriesBySchema(){ - if(this.selectedSession.queries){ - this.queryBySchema = this.selectedSession.queries.reduce((acc: any, item: any) => { - if(!acc[item['schema']]){ + groupQueriesBySchema() { + if (this.selectedSession.queries) { + this.queryBySchema = this.selectedSession.queries.reduce((acc: any, item: any) => { + if (!acc[item['schema']]) { acc[item['schema']] = [] } acc[item['schema']].push(item); return acc; - },[]); + }, []); } } @@ -331,7 +347,7 @@ export class SessionDetailComponent implements AfterContentInit, OnDestroy { return this.UtilInstance.getSessionUrl(selectedSession); } - navigate(event:MouseEvent,targetType: string,extraParam?:string) { + navigate(event: MouseEvent, targetType: string, extraParam?: string) { let params: any[] = []; switch (targetType) { case "api": @@ -344,13 +360,13 @@ export class SessionDetailComponent implements AfterContentInit, OnDestroy { params.push('session/api', this.selectedSession.id, 'tree') break; case "parent": - params.push('session',this.sessionParent.type, this.sessionParent.id) + params.push('session', this.sessionParent.type, this.sessionParent.id) } - if(event.ctrlKey){ - this._router.open(`#/${params.join('/')}`,'_blank') - }else { + if (event.ctrlKey) { + this._router.open(`#/${params.join('/')}`, '_blank') + } else { this._router.navigate(params, { - queryParams: { env: this.selectedSession?.application?.env } + queryParams: { env: this.selectedSession?.application?.env } }); } } @@ -369,15 +385,15 @@ export class SessionDetailComponent implements AfterContentInit, OnDestroy { }); } - isQueryCompleted(query:any):boolean { - return query.actions.every((a:any) => !a?.exception?.classname && !a?.exception?.message); + isQueryCompleted(query: any): boolean { + return query.actions.every((a: any) => !a?.exception?.classname && !a?.exception?.message); } - getCommand(commands:string[]):string{ + getCommand(commands: string[]): string { let command = "" - if(commands?.length == 1){ + if (commands?.length == 1) { command = `[${commands[0]}]` - }else if(commands?.length > 1) { + } else if (commands?.length > 1) { command = "[SQL]" } return command; @@ -391,11 +407,25 @@ export class SessionDetailComponent implements AfterContentInit, OnDestroy { this.paramsSubscription.unsubscribe(); } } + + applyFilter(event: Event) { + const filterValue = (event.target as HTMLInputElement).value; + this.filterTable.set('filter', filterValue.trim().toLowerCase()); + this.outcomingRequestdataSource.filter = JSON.stringify(Array.from(this.filterTable.entries())); + if (this.outcomingRequestdataSource.paginator) { + this.outcomingRequestdataSource.paginator.firstPage(); + } + } + + toggleFilter(filter: string[]) { + this.filterTable.set('status', filter); + this.outcomingRequestdataSource.filter = JSON.stringify(Array.from(this.filterTable.entries())); + } } @Injectable() export class EnvRouter { - + private _env: string; constructor(private router: Router) { } @@ -404,14 +434,14 @@ export class EnvRouter { this._env = env } - get events(): Observable{ + get events(): Observable { return this.router.events; }; get url(): string { return this.router.url; } - + navigate(commands: any[], extras?: NavigationExtras): Promise { if (!extras?.queryParams?.env) { @@ -432,8 +462,8 @@ export class EnvRouter { // return Promise.resolve(true); } - open(url?: string | URL, target?: string, features?: string): WindowProxy | null{ - return window.open(url,target,features); + open(url?: string | URL, target?: string, features?: string): WindowProxy | null { + return window.open(url, target, features); } - + } \ No newline at end of file diff --git a/src/styles.scss b/src/styles.scss index 644b7d7..6d9fd0d 100644 --- a/src/styles.scss +++ b/src/styles.scss @@ -145,11 +145,12 @@ mat-form-field.loading { .empty-row { display: flex; gap: .5em; - margin: 2.5rem auto; + height: 52px; color: #707070; font-weight: 500; - width: fit-content; + width: 100%; font-size: 12px; + justify-content: center; } .mdc-data-table__cell:has(chart) { From e0023d217916e357ed0a4af37c28f2d9e373138e Mon Sep 17 00:00:00 2001 From: fufuu Date: Wed, 5 Jun 2024 10:31:02 +0200 Subject: [PATCH 018/126] timeline affichage --- src/app/views/session-detail/session-detail.component.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/views/session-detail/session-detail.component.html b/src/app/views/session-detail/session-detail.component.html index 0b13c9e..d5efb33 100644 --- a/src/app/views/session-detail/session-detail.component.html +++ b/src/app/views/session-detail/session-detail.component.html @@ -317,7 +317,7 @@ -
+
From 30531cbbbb355f2e78ca938ab22f8dac579f0841 Mon Sep 17 00:00:00 2001 From: YoussefDahi Date: Wed, 5 Jun 2024 10:40:44 +0200 Subject: [PATCH 019/126] added db-request-detail --- src/app/app.module.ts | 18 +- src/app/shared/model/trace.model.ts | 1 + src/app/shared/services/trace.service.ts | 2 +- .../db-request-detail.component.html | 85 +++--- .../db-request-detail.component.scss | 5 +- .../db-request-detail.component.ts | 260 +++++------------- .../session-detail.component.html | 17 +- .../session-detail.component.ts | 25 +- src/styles.scss | 20 ++ 9 files changed, 164 insertions(+), 269 deletions(-) diff --git a/src/app/app.module.ts b/src/app/app.module.ts index a8dea1c..a33cc96 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -44,20 +44,20 @@ const routes: Route[] = [ component: SessionMainComponent, title: 'Liste des Sessions' }, + { + path: ':type/:id/db/:dbid', + component: DbRequestDetailComponent, + title: 'Detail de la requête SQL' + }, { path: ':type/:id', component: SessionDetailComponent, title: (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => { - if(route.paramMap.get('type') == 'main') { + if (route.paramMap.get('type') == 'main') { return 'Detail de la Session'; - } + } return 'Detail de l\'API'; - } - }, - { - path: 'api/:id/db/:dbid', - component: DbRequestDetailComponent, - title: 'Detail de la requête SQL' + }, }, { path: '**', pathMatch: 'full', redirectTo: `/session/api` } ] @@ -78,7 +78,7 @@ const routes: Route[] = [ path: 'user/:name', component: StatsUserComponent, title: 'Statistiques Utilisateur' - }, + }, { path: 'database/:name', component: StatsDatabaseComponent, diff --git a/src/app/shared/model/trace.model.ts b/src/app/shared/model/trace.model.ts index b13559d..d4c5eaa 100644 --- a/src/app/shared/model/trace.model.ts +++ b/src/app/shared/model/trace.model.ts @@ -79,6 +79,7 @@ export interface DatabaseAction{ start:Date; end:Date; exception:ExceptionInfo; + count:number; } export interface ExceptionInfo{ diff --git a/src/app/shared/services/trace.service.ts b/src/app/shared/services/trace.service.ts index ce362aa..c236f2b 100644 --- a/src/app/shared/services/trace.service.ts +++ b/src/app/shared/services/trace.service.ts @@ -31,7 +31,7 @@ export class TraceService { } getDbRequestById(id: number){ - return this.http.get(`${localStorage.getItem('server')}/trace/db/${id}`); + return this.http.get(`${localStorage.getItem('server')}/trace/session/db/${id}`); } getSessionParentByChildId(id: string){ diff --git a/src/app/views/db-request-detail/db-request-detail.component.html b/src/app/views/db-request-detail/db-request-detail.component.html index 06cff64..8fe3504 100644 --- a/src/app/views/db-request-detail/db-request-detail.component.html +++ b/src/app/views/db-request-detail/db-request-detail.component.html @@ -1,77 +1,60 @@
- - + - +

settings_suggest - {{selectedSession?.type=='api' || selectedSession?.type =='outcoming' ? (selectedSession?.name|| 'N/A') : '[' - + selectedSession?.launchMode + '] ' + selectedSession?.name || 'N/A'}} - + {{ selectedQuery?.name || 'N/A' }} +

+
-
-
+ -
+
+ +
- warning{{selectedSession?.exception.message || selectedSession?.exception?.classname}} + *ngIf="!selectedQuery?.completed" + [matTooltip]="selectedQuery?.exception?.classname" TooltipPosition="below"> + warning{{getException(selectedQuery?.actions)?.exception?.message}}
- - person
- - {{selectedSession?.user || "N/A"}} - - le {{( selectedSession?.start*1000 ) | date: 'dd/MM/yyyy à HH:mm:ss.SSS': 'fr' }} + {{selectedQuery?.user || "N/A"}} le {{( selectedQuery?.start*1000 ) | date: 'dd/MM/yyyy à HH:mm:ss.SSS': 'fr' }}
- {{selectedSession?.inDataSize || 0}}o - swap_vert - {{selectedSession?.outDataSize}}o en {{ getElapsedTime(selectedSession?.end, selectedSession?.start) | - number :'1.2-3'}}s + en {{ getElapsedTime(selectedQuery?.end, selectedQuery?.start) | number :'1.2-3'}}s
+ {{getSessionStatusTooltip(selectedQuery)}}
- + - - storage - {{selectedSession?.application?.name}} + + Database + {{selectedQuery?.database}}
@@ -98,13 +81,13 @@
- {{selectedSession?.application?.address}} en {{selectedSession?.application?.env}} + {{selectedQuery?.host}} {{ ':'+ selectedQuery?.port || '' }}
- {{selectedSession?.application?.os}} + {{selectedQuery?.databaseName}} - {{selectedSession?.application?.re}} + {{selectedQuery?.databaseVersion}}
diff --git a/src/app/views/db-request-detail/db-request-detail.component.scss b/src/app/views/db-request-detail/db-request-detail.component.scss index be9cebf..ffc8b36 100644 --- a/src/app/views/db-request-detail/db-request-detail.component.scss +++ b/src/app/views/db-request-detail/db-request-detail.component.scss @@ -75,4 +75,7 @@ table { .url { color: blue; text-decoration: solid; -} \ No newline at end of file +} + + + \ No newline at end of file diff --git a/src/app/views/db-request-detail/db-request-detail.component.ts b/src/app/views/db-request-detail/db-request-detail.component.ts index a246cf7..d7a0b7e 100644 --- a/src/app/views/db-request-detail/db-request-detail.component.ts +++ b/src/app/views/db-request-detail/db-request-detail.component.ts @@ -1,16 +1,14 @@ -import { AfterContentInit, Component, ElementRef, Injectable, NgZone, OnDestroy, ViewChild} from '@angular/core'; -import { MatDialog } from '@angular/material/dialog'; -import { MatTableDataSource } from '@angular/material/table'; -import { ActivatedRoute, NavigationExtras, Router} from '@angular/router'; -import { Observable, combineLatest} from "rxjs"; +import { Component, ElementRef,NgZone, OnDestroy, ViewChild } from '@angular/core'; + +import { ActivatedRoute } from '@angular/router'; +import { combineLatest } from "rxjs"; import { Timeline } from 'vis-timeline'; -import { ExceptionInfo, OutcomingQuery, OutcomingRequest, RunnableStage } from 'src/app/shared/model/trace.model'; +import { DatabaseAction } from 'src/app/shared/model/trace.model'; import { Utils } from 'src/app/shared/util'; -import { DatePipe, Location} from '@angular/common'; -import { MatPaginator } from '@angular/material/paginator'; -import { MatSort } from '@angular/material/sort'; +import { DatePipe, Location } from '@angular/common'; import { TraceService } from 'src/app/shared/services/trace.service'; import { application } from 'src/environments/environment'; +import { EnvRouter } from '../session-detail/session-detail.component'; export interface UserData { @@ -25,72 +23,62 @@ export interface UserData { styleUrls: ['./db-request-detail.component.scss'], }) -export class DbRequestDetailComponent implements AfterContentInit, OnDestroy { +export class DbRequestDetailComponent implements OnDestroy { UtilInstance: Utils = new Utils(); selectedQuery: any; + dbQueryId: number; + dbQueryParentId: string; + dbQueryParentType: string; isComplete: boolean = true; isLoading: boolean = false; - data: any[]; - chartOp: any; - resizeSubscription: any; - paramsSubscription: any; - chart: any; - options: any; - container: any; - dataTable: any; + paramsSubscription: any; timeLine: any; - queryBySchema :any[]; - env:any; + env: any; pipe = new DatePipe('fr-FR') @ViewChild('timeline') timelineContainer: ElementRef; - @ViewChild('OutcomingRequestPaginator') outcomingRequestPaginator: MatPaginator; - @ViewChild('OutcomingRequestSort') outcomingRequestSort: MatSort; - @ViewChild('OutcomingQueryPaginator') outcomingQueryPaginator: MatPaginator; - @ViewChild('OutcomingQuerySort') outcomingQuerySort: MatSort; constructor(private _activatedRoute: ActivatedRoute, private _traceService: TraceService, - public dialog: MatDialog, private zone: NgZone, private _router: EnvRouter, private _location: Location) { - - this.paramsSubscription = combineLatest([ + this.paramsSubscription = combineLatest([ this._activatedRoute.params, this._activatedRoute.queryParams ]).subscribe({ next: ([params, queryParams]) => { - this.getSessionById(params.id); + this.dbQueryId = params.dbid; + this.dbQueryParentId = params.id; + this.dbQueryParentType = params.type; this.env = queryParams.env || application.default_env; this._location.replaceState(`${this._router.url.split('?')[0]}?env=${this.env}`) + this.getDbRequestById(this.dbQueryId); } - }); - } + }); + } - ngAfterContentInit(): void { - } - getSessionById(id: number) { + getDbRequestById(id: number) { this.isLoading = true; this._traceService.getDbRequestById(id).subscribe({ next: (d: any) => { - if(d) - { + if (d) { this.selectedQuery = d; - //this.groupQueriesBySchema(); - this.configDbactions(this.selectedQuery) + // this.configDbactions(this.selectedQuery) + + this.visjs(); this.isLoading = false; this.isComplete = true; } else { this.isLoading = false; - this.isComplete= false; + this.isComplete = false; // navigate to tab incoming } }, @@ -101,103 +89,60 @@ export class DbRequestDetailComponent implements AfterContentInit, OnDestroy { } visjs() { - - let timeline_end = +this.selectedQuery.end * 1000 + let timeline_end = +(this.selectedQuery.end * 1000) let timeline_start = +this.selectedQuery.start * 1000 - let dataArray: any = [...this.selectedQuery.requests, - ...this.selectedQuery.queries, - ...this.selectedQuery.stages.map((s: any) => ({ ...s, isStage: true }))]; - dataArray.splice(0, 0, {...this.selectedQuery,isStage: true}) + let dataArray = this.selectedQuery.actions; this.sortInnerArrayByDate(dataArray); - - let data: any; - let groups: any; - let isWebapp = false, title = ''; - if (this.selectedQuery === "main" && this.selectedQuery.launchMode === "WEBAPP") { - groups = [{ id: 0, content: this.selectedQuery?.application?.re }]; - title = 'path'; - isWebapp = true; - } else { - groups = new Set(); - dataArray.forEach((c: any, i: number) => { - groups.add(c['threadName']) - }); - title = 'threadName'; - groups = Array.from(groups).map((g: string) => ({ id: g, content: g })) - } - data = dataArray.map((c: any, i: number) => { - let o = { - id: c.hasOwnProperty('schema') ? -i : c.id, - group: isWebapp ? 0 : c.threadName, - content:c.hasOwnProperty('isStage') ? '' : (c.schema || c.host || 'N/A'), - start: c.start * 1000, - end: c.end * 1000, + let g = new Set() + dataArray.forEach((c: any) =>{ + g.add(c.type); + }); + let groups = Array.from(g).map((g: string) => ({ id: g, content: g })) + + dataArray = dataArray.map((c: any, i: number) => { + let e:any = { + group: c.type, + // content: "c.type", + start: Math.trunc(c.start * 1000), + end: Math.trunc(c.end * 1000), title: `${this.pipe.transform(new Date(c.start * 1000), 'HH:mm:ss.SSS')} - ${this.pipe.transform(new Date(c.end * 1000), 'HH:mm:ss.SSS')}
-

${c[title]}: ${this.getElapsedTime(c.end, c.start).toFixed(3)}s

`, - className: c.hasOwnProperty('schema') ? "bdd" : !c.hasOwnProperty('isStage') ? "rest" : "", - type: c.hasOwnProperty('isStage') ? 'background' : 'range' +

${c.type}${c?.count? '('+c?.count+')': ''}: ${this.getElapsedTime(c.end, c.start).toFixed(3)}s

`, + //className : 'vis-dot', } - if (o.end > timeline_end){ - timeline_end = o.end - } - return o; - }) + e.type = e.start == e.end ? 'point' : 'range' + if(c?.exception?.message || c?.exception?.classname){ + e.className ='bdd-failed'; + e.title += `
${c?.exception?.message}
`; // TODO : fix css on tooltip + } + + return e; + }) if (this.timeLine) { // destroy if exists this.timeLine.destroy(); } - // Create a Timeline - this.timeLine = new Timeline(this.timelineContainer.nativeElement, data, groups - , { - min: timeline_start, - max: timeline_end, + this.timeLine = new Timeline(this.timelineContainer.nativeElement, dataArray, groups, + { + //stack:false, + // min: timeline_start, + // max: timeline_end, + selectable : false, clickToUse: true, tooltip: { followMouse: true }, - margin: { - item: { - horizontal: -1 - } - }, - order: (a, b) => { - return b.start - a.start // inverser l'ordre - } + //order: (a, b) => { + // return b.start - a.start // inverser l'ordre + // } }); - - let that = this; - this.timeLine.on('select', function (props: any) { - let id = props.items[0]; - if (isNaN(+id)) { - that._router.navigate(['/session', 'api', id]); - } - }); - - if (timeline_end != +this.selectedQuery.end * 1000) { - this.timeLine.addCustomTime(+this.selectedQuery.end * 1000, "async"); - this.timeLine.setCustomTimeMarker("async", "async"); - } - - } - - selectedRequest(event:MouseEvent,row: any) { - if(row){ - if( event.ctrlKey){ - this._router.open(`#/session/api/${row}`,'_blank') - }else { - this._router.navigate(['/session', 'api', row]); - } - } - } getElapsedTime(end: number, start: number,) { // return (new Date(end * 1000).getTime() - new Date(start * 1000).getTime()) / 1000 return end - start; - } getRe(re: string) { @@ -214,15 +159,12 @@ export class DbRequestDetailComponent implements AfterContentInit, OnDestroy { if (session?.type == "api" || session?.type == "outcoming") return this.UtilInstance.statusBorderCard(session.status) if (session?.type == "main") - return this.UtilInstance.statusBorderCard(!!session.exception.message) + return this.UtilInstance.statusBorderCard(!!session?.exception?.message) } getSessionStatusTooltip(session: any) { - if (session?.type == "api" || session?.type == "outcoming") - return session?.status; - if (session?.type == "main") - return !session.exception.message ? "réussi" : "échoué"; + return session?.completed ? "réussi" : "échoué"; } @@ -242,28 +184,23 @@ export class DbRequestDetailComponent implements AfterContentInit, OnDestroy { return this.UtilInstance.getSessionUrl(selectedSession); } + navigate(event:MouseEvent,targetType: string,extraParam?:string) { let params: any[] = []; switch (targetType) { - case "api": - params.push('dashboard', 'api', this.selectedQuery.name); - break; - case "app": - params.push('dashboard', 'app', this.selectedQuery.application.name) - break; - case "tree": - params.push('session/api', this.selectedQuery.id, 'tree') - break; + case "parent": + params.push('session', this.dbQueryParentType, this.dbQueryParentId) } if(event.ctrlKey){ this._router.open(`#/${params.join('/')}`,'_blank') }else { this._router.navigate(params, { - queryParams: { env: this.selectedQuery?.application?.env } + queryParams: { env: this.env } }); } } + sortInnerArrayByDate(innerArray: any[]): any[] { return innerArray.sort((a, b) => { if (a.start > b.start) @@ -271,80 +208,33 @@ export class DbRequestDetailComponent implements AfterContentInit, OnDestroy { if (a.start < b.start) return -1; - - if (a.threadName && b.threadName) - return a.threadName.localeCompare(b.threadName) - }); } - isQueryCompleted(query:any):boolean { - return query.actions.every((a:any) => !a.exception.classname && !a.exception.message); + isQueryCompleted(query: any): boolean { + return query.actions.every((a: any) => !a?.exception?.classname && !a?.exception?.message); } - getCommand(commands:string[]):string{ + getCommand(commands: string[]): string { let command = "" - if(commands?.length == 1){ + if (commands?.length == 1) { command = `[${commands[0]}]` - }else if(commands?.length > 1) { + } else if (commands?.length > 1) { command = "[SQL]" } return command; } + getException(actions: DatabaseAction[]): DatabaseAction{ + return actions.filter(a => a?.exception?.message || a?.exception?.classname)[0] + } + ngOnDestroy() { - if (this.resizeSubscription) { - this.resizeSubscription.unsubscribe(); - } if (this.paramsSubscription) { this.paramsSubscription.unsubscribe(); } } - -} - -@Injectable() -export class EnvRouter { - - private _env: string; - - constructor(private router: Router) { } - - set env(env: string) { - this._env = env - } - - get events(): Observable{ - return this.router.events; - }; - - get url(): string { - return this.router.url; - } - - navigate(commands: any[], extras?: NavigationExtras): Promise { - if (!extras?.queryParams?.env) { - if (this._env) { - if (!extras) { - extras = {} - } - if (!extras.queryParams) { - extras.queryParams = {} - } - extras.queryParams.env = this._env; - } - } - else { - this.env = extras.queryParams.env; - } - return this.router.navigate(commands, extras); - // return Promise.resolve(true); - } - open(url?: string | URL, target?: string, features?: string): WindowProxy | null{ - return window.open(url,target,features); - } - } \ No newline at end of file diff --git a/src/app/views/session-detail/session-detail.component.html b/src/app/views/session-detail/session-detail.component.html index d5efb33..05d3c1f 100644 --- a/src/app/views/session-detail/session-detail.component.html +++ b/src/app/views/session-detail/session-detail.component.html @@ -67,8 +67,7 @@ {{selectedSession?.outDataSize}}o en {{ getElapsedTime(selectedSession?.end, selectedSession?.start) | number :'1.2-3'}}s
- {{selectedSession?.status}} + {{selectedSession?.status}}
@@ -294,14 +293,12 @@ - - - - -
- + + + +
diff --git a/src/app/views/session-detail/session-detail.component.ts b/src/app/views/session-detail/session-detail.component.ts index de418b2..c2b8029 100644 --- a/src/app/views/session-detail/session-detail.component.ts +++ b/src/app/views/session-detail/session-detail.component.ts @@ -105,7 +105,7 @@ export class SessionDetailComponent implements AfterContentInit, OnDestroy { if (this.selectedSession) { this.selectedSession.type = this.selectedSessionType; - // Api request list + // Api request list this.outcomingRequestList = this.selectedSession.requests; this.outcomingRequestdataSource = new MatTableDataSource(this.outcomingRequestList); setTimeout(() => { this.outcomingRequestdataSource.paginator = this.outcomingRequestPaginator }); @@ -123,7 +123,7 @@ export class SessionDetailComponent implements AfterContentInit, OnDestroy { let isMatch = true; for (let [key, value] of map.entries()) { if (key == 'filter') { - isMatch = isMatch && (value == '' || + isMatch = isMatch && (value == '' || (data.host?.toLowerCase().includes(value) || data.method?.toLowerCase().includes(value) || data.query?.toLowerCase().includes(value) || data.path?.toLowerCase().includes(value))); } else if (key == 'status') { @@ -138,7 +138,7 @@ export class SessionDetailComponent implements AfterContentInit, OnDestroy { this.outcomingRequestdataSource.filter = JSON.stringify(Array.from(this.filterTable.entries())); setTimeout(() => { this.outcomingRequestdataSource.paginator.pageIndex = 0 }); - // DB request list + // DB request list this.outcomingQueryList = this.selectedSession.queries this.outcomingQuerydataSource = new MatTableDataSource(this.outcomingQueryList); setTimeout(() => { this.outcomingQuerydataSource.paginator = this.outcomingQueryPaginator }); @@ -151,7 +151,7 @@ export class SessionDetailComponent implements AfterContentInit, OnDestroy { this.groupQueriesBySchema(); - // Timeline + // Timeline this.visjs(); // Check if parent exist @@ -266,18 +266,19 @@ export class SessionDetailComponent implements AfterContentInit, OnDestroy { if (event.ctrlKey) { this._router.open(`#/session/api/${row}`, '_blank',) } else { - this._router.navigate(['/session', 'api', row], { queryParams: { env: this.env } }); // TODO remove env FIX BUG + this._router.navigate(['/session', 'api', row], { queryParams: { env: this.env } }); // TODO remove env FIX BUG } } } - selectedQuery(event: MouseEvent, queryId: any) { // TODO finish this - if (queryId) { - if (event.ctrlKey) { - this._router.open(`#/session/${this.selectedSession.type}/${this.selectedSession.id}/db/${queryId}`, '_blank',) - } else { - this._router.navigate(['/session', this.selectedSession.type, this.selectedSession.id, 'db', queryId], { - queryParams: { env: this.env } + selectedQuery(event: MouseEvent, queryId:any){ // TODO finish this + if(queryId){ + if( event.ctrlKey){ + this._router.open(`#/session/${this.selectedSession.type}/${this.selectedSession.id}/db/${queryId}`,'_blank',) + }else { + console.log('/session', this.selectedSession.type, this.selectedSession.id, 'db', queryId) + this._router.navigate(['/session', this.selectedSession.type, this.selectedSession.id, 'db', queryId],{ + queryParams:{env:this.env} }); } } diff --git a/src/styles.scss b/src/styles.scss index 6d9fd0d..da2a0d4 100644 --- a/src/styles.scss +++ b/src/styles.scss @@ -104,16 +104,36 @@ mat-form-field.no-subscript { color:white; cursor: pointer; } + .vis-item.bdd{ background-color: #008080; //rgb(150, 205, 50); border-color: #002e2e;//rgb(150, 205, 50); color:white; } +.vis-item.bdd-failed{ + background-color: red; //rgb(150, 205, 50); + border-color: rgb(185, 40, 40);//rgb(150, 205, 50); + color:white; +} + .vis-custom-time { // makes markers not draggable pointer-events: none; } +.error{ + color:red; +} + +.badge { + color: white; + padding: 0px 10px; + text-align: center; + border-radius: 12px; + font-size: 0.8em; + gap: 0.5em +} + /*.vis-item.vis-selected{ background-color: orange; From 3d6aea782e8f553b8dc4b8a189d9cc174dbeb285 Mon Sep 17 00:00:00 2001 From: fufuu Date: Wed, 5 Jun 2024 17:30:49 +0200 Subject: [PATCH 020/126] refactor --- src/app/shared/model/client-app.model.ts | 2 - src/app/shared/model/trace.model.ts | 141 +++--- src/app/shared/services/filter.service.ts | 62 +-- src/app/shared/util.ts | 62 +-- .../db-request-detail.component.html | 4 +- .../db-request-detail.component.ts | 21 +- .../session-api/session-api.component.html | 4 +- .../session-api/session-api.component.ts | 3 +- .../request-database-table.component.html | 57 +++ .../request-database-table.component.scss | 0 .../request-database-table.component.ts | 60 +++ .../request-rest-table.component.html | 98 ++++ .../request-rest-table.component.scss | 3 + .../request-rest-table.component.ts | 86 ++++ .../request-timeline.component.html | 1 + .../request-timeline.component.scss | 0 .../request-timeline.component.ts | 118 +++++ .../session-detail.component.html | 438 ++++++------------ .../session-detail.component.ts | 359 ++------------ .../session-main/session-main.component.html | 4 +- .../session-main/session-main.component.ts | 12 +- src/app/views/tree/tree.component.ts | 11 +- src/app/views/views.module.ts | 6 + src/styles.scss | 12 + 24 files changed, 771 insertions(+), 793 deletions(-) delete mode 100644 src/app/shared/model/client-app.model.ts create mode 100644 src/app/views/session-detail/components/request-database-table/request-database-table.component.html create mode 100644 src/app/views/session-detail/components/request-database-table/request-database-table.component.scss create mode 100644 src/app/views/session-detail/components/request-database-table/request-database-table.component.ts create mode 100644 src/app/views/session-detail/components/request-rest-table/request-rest-table.component.html create mode 100644 src/app/views/session-detail/components/request-rest-table/request-rest-table.component.scss create mode 100644 src/app/views/session-detail/components/request-rest-table/request-rest-table.component.ts create mode 100644 src/app/views/session-detail/components/request-timeline/request-timeline.component.html create mode 100644 src/app/views/session-detail/components/request-timeline/request-timeline.component.scss create mode 100644 src/app/views/session-detail/components/request-timeline/request-timeline.component.ts diff --git a/src/app/shared/model/client-app.model.ts b/src/app/shared/model/client-app.model.ts deleted file mode 100644 index 139597f..0000000 --- a/src/app/shared/model/client-app.model.ts +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/src/app/shared/model/trace.model.ts b/src/app/shared/model/trace.model.ts index d4c5eaa..a17ac8b 100644 --- a/src/app/shared/model/trace.model.ts +++ b/src/app/shared/model/trace.model.ts @@ -1,31 +1,45 @@ -export interface IncomingRequest { +export interface Request { id: string; + user: string; + start: number; + end: number; + threadName: string; + application: ApplicationInfo; + exception: ExceptionInfo; + requests: OutcomingRequest[]; + queries: OutcomingQuery[]; + stages: RunnableStage[]; +} + +export interface RestRequest extends Request { method: string; protocol: string; host: string; port: number; path: string; query: string; - contentType: string; + contentType: string; authScheme: string; status: number; inDataSize: number; - outDataSize:number; - start:number; - end:number; - threadName:string; - exception:ExceptionInfo + outDataSize: number; +} + +export interface MainRequest extends Request { name: string; - user: string; - application: applicationInfo; - requests: OutcomingRequest[]; - queries: OutcomingQuery[]; - stages: RunnableStage[]; - type?:string; + launchMode: string; + location: string; +} +export interface IncomingRequest extends RestRequest { + name: string; } -export interface applicationInfo { +export interface OutcomingRequest extends RestRequest { + +} + +export interface ApplicationInfo { name: string; version: string; address: string; @@ -34,85 +48,42 @@ export interface applicationInfo { re: string; } -export interface OutcomingRequest { - id: string; - method: string; - name?:string; - protocol: string; +export interface OutcomingQuery { host: string; port: number; - path: string; - query: string; - contentType: string; - authScheme: string; - status: number; - inDataSize: number; - outDataSize:number; - start:Date; - end:Date; - threadName:string; - exception:ExceptionInfo; - requests?:OutcomingRequest[]; - queries?: OutcomingQuery[]; - stages?: RunnableStage[]; - type?:string; - application?:applicationInfo -} - -export interface OutcomingQuery{ - host:string; - port:number; - scheme:string; - start:Date; - end:Date; - user:string; - threadName:string; - driverVersion:string; - databaseName:string; - databaseVersion:string; - completed:boolean; - actions:DatabaseAction[] -} - -export interface DatabaseAction{ - type:string; - start:Date; - end:Date; - exception:ExceptionInfo; - count:number; + scheme: string; + start: Date; + end: Date; + user: string; + threadName: string; + driverVersion: string; + databaseName: string; + databaseVersion: string; + completed: boolean; + actions: DatabaseAction[] } -export interface ExceptionInfo{ - classname:string; - message:string; +export interface DatabaseAction { + type: string; + start: Date; + end: Date; + exception: ExceptionInfo; + count: number; } -export interface Mainrequest{ - id:string; - name:string; - user:string; - start:Date; - end:Date; - launchMode:string; - location:string; - threadName:string; - application:applicationInfo; - exception:ExceptionInfo; - requests:OutcomingRequest[]; - queries: OutcomingQuery[]; - stages: RunnableStage[]; - type?:string; - +export interface ExceptionInfo { + classname: string; + message: string; } -export interface RunnableStage { - name:string; - location:string; - start:number; - end:number; - user:string; - threadName:string; - exception:ExceptionInfo; +export interface RunnableStage { + name: string; + location: string; + start: number; + end: number; + user: string; + threadName: string; + exception: ExceptionInfo; } diff --git a/src/app/shared/services/filter.service.ts b/src/app/shared/services/filter.service.ts index a93aafd..c96c48d 100644 --- a/src/app/shared/services/filter.service.ts +++ b/src/app/shared/services/filter.service.ts @@ -4,16 +4,16 @@ import { BehaviorSubject, Observable, Subscription, catchError, combineLatest, f import { FilterPreset, FilterMap } from "src/app/views/constants"; @Injectable({ providedIn: 'root' }) -export class FilterService implements OnDestroy{ +export class FilterService implements OnDestroy { private _router = inject(Router) - routeSubscription:Subscription + routeSubscription: Subscription - filters = new BehaviorSubject({}); - otherfilters : Observable ; + filters = new BehaviorSubject({}); + otherfilters: Observable; - getOtherFilters : ()=> Observable; + getOtherFilters: () => Observable; constructor() { @@ -21,27 +21,27 @@ export class FilterService implements OnDestroy{ this.filters.next({}); }); } - - registerGetallFilters( fns : ()=> Observable){ + + registerGetallFilters(fns: () => Observable) { this.getOtherFilters = fns; } - - savePreset(name: string, pn: string) : Observable { - - if(!name) - return throwError(()=> new Error("preset name is missing! ")); - + + savePreset(name: string, pn: string): Observable { + + if (!name) + return throwError(() => new Error("preset name is missing! ")); + return combineLatest({ filters: this.filters, otherfilters: this.getOtherFilters() || of({}) - }).pipe(map((f)=>{ - const map = {...f.filters, ...f.otherfilters}; + }).pipe(map((f) => { + const map = { ...f.filters, ...f.otherfilters }; const presets: FilterPreset[] = this.getPresetsLocalStrorage(pn); const existingPresetNameIndex = presets.findIndex(p => p.name === name); - let newPreset: FilterPreset = { name: name, pageName: pn, values: map }; - if(existingPresetNameIndex != -1){ + let newPreset: FilterPreset = { name: name, pageName: pn, values: map }; + if (existingPresetNameIndex != -1) { console.log("existing preset name, editing value") - presets[existingPresetNameIndex].values = map; + presets[existingPresetNameIndex].values = map; newPreset = presets[existingPresetNameIndex]; } else { const existingPresetValuesIndex = presets.findIndex(p => JSON.stringify(p.values) === JSON.stringify(map)) @@ -56,24 +56,24 @@ export class FilterService implements OnDestroy{ console.log('new preset, adding ') presets.push(newPreset); } - } + } localStorage.setItem(pn, JSON.stringify(presets)) return newPreset; })) - .pipe( - catchError(error => { - console.error('error',error) - return of(null) - }) - ).pipe(first()); + .pipe( + catchError(error => { + console.error('error', error) + return of(null) + }) + ).pipe(first()); } - removePreset(name: string, pn: string) : FilterPreset { - + removePreset(name: string, pn: string): FilterPreset { + const presets = this.getPresetsLocalStrorage(pn); const removedPresetIndex = presets.findIndex((p: FilterPreset) => p.name == name); let removedPreset: FilterPreset; - if( removedPresetIndex != -1){ + if (removedPresetIndex != -1) { removedPreset = presets[removedPresetIndex]; presets.splice(removedPresetIndex, 1); localStorage.setItem(pn, JSON.stringify(presets)) @@ -81,7 +81,7 @@ export class FilterService implements OnDestroy{ } } - setFilterMap(filterMap:FilterMap){ + setFilterMap(filterMap: FilterMap) { this.filters.next(filterMap); } @@ -89,7 +89,7 @@ export class FilterService implements OnDestroy{ this.routeSubscription.unsubscribe(); } - getPresetsLocalStrorage(pageName:string):FilterPreset[] { + getPresetsLocalStrorage(pageName: string): FilterPreset[] { return JSON.parse(localStorage.getItem(pageName) || '[]'); - } + } } \ No newline at end of file diff --git a/src/app/shared/util.ts b/src/app/shared/util.ts index 6e86375..b67c2c9 100644 --- a/src/app/shared/util.ts +++ b/src/app/shared/util.ts @@ -10,17 +10,17 @@ export class Utils { dbactionIcon: any = { 'CONNECTION': '#1423DC', - 'METADATA' : '#2134CB', - 'STATEMENT' : '#2E45BA', - 'EXECUTE' : '#3B56A9', - 'RESULTSET' : "#486798", - 'SELECT' : '#557887', - 'UPDATE' : '#628976', - 'BATCH' : '#6F9A65', - 'COMMIT' : '#7CAB54', - 'ROLLBACK' : '#89BC43', - 'FETCH' : '#96CD32', - ' ' : '#e9ecef' + 'METADATA': '#2134CB', + 'STATEMENT': '#2E45BA', + 'EXECUTE': '#3B56A9', + 'RESULTSET': "#486798", + 'SELECT': '#557887', + 'UPDATE': '#628976', + 'BATCH': '#6F9A65', + 'COMMIT': '#7CAB54', + 'ROLLBACK': '#89BC43', + 'FETCH': '#96CD32', + ' ': '#e9ecef' }; protocol: any = { 'http': 'fa-solid fa-lock-open', @@ -37,7 +37,7 @@ export class Utils { 'java': 'fa-brands fa-java fa-xl', } - getStateColor(status: number) { // put it in util class + static getStateColor(status: number) { // put it in util class if (status >= 200 && status < 300) return "green" @@ -50,20 +50,20 @@ export class Utils { return "gray" } - getStateColorBool(completed: boolean) { + static getStateColorBool(completed: boolean) { if (completed) return 'green' return 'red'; } - statusBorder(completed: any): { [key: string]: string } { + static statusBorder(completed: any): { [key: string]: string } { if (typeof completed == "boolean") { return { 'box-shadow': '4px 0px 0px 0px ' + this.getStateColorBool(completed) + ' inset' }; } return { 'box-shadow': '4px 0px 0px 0px ' + this.getStateColor(completed) + ' inset' }; } - statusBorderCard(failed: any): { [key: string]: string } { + static statusBorderCard(failed: any): { [key: string]: string } { if (typeof failed == "boolean") { return { 'border-left': '4px solid ' + this.getStateColorBool(!failed) }; } @@ -88,7 +88,7 @@ export class Utils { return secondString } - public getRe(re: string) { + getRe(re: string) { let result = re if (re) { @@ -104,11 +104,11 @@ export class Utils { return result; } - public getSessionUrl(selectedSession: any) { + static getSessionUrl(selectedSession: any) { return `${selectedSession?.protocol ? selectedSession?.protocol + '://' : ''}${selectedSession?.host ? selectedSession?.host : ''}${selectedSession?.port > 0 ? ':' + selectedSession?.port : ''}${selectedSession?.path ? selectedSession?.path : ''}${selectedSession?.query ? '?' + selectedSession?.query : ''}` } - public getElapsedTime(end: number, start: number,) { + static getElapsedTime(end: number, start: number,) { return (new Date(end * 1000).getTime() - new Date(start * 1000).getTime()) / 1000 } @@ -128,13 +128,13 @@ export function groupingBy(arr: any[], field: string): any { export function periodManagement(start: Date, end: Date): string { var dayDiff = (end.getTime() - start.getTime()) / (24 * 60 * 60 * 1000); - if(dayDiff <= 1) { // 24 heures + if (dayDiff <= 1) { // 24 heures return ChartGroup.byHour; } if (dayDiff <= 24) { return ChartGroup.byDay; } - if(Math.round(dayDiff / 7) <= 24) { + if (Math.round(dayDiff / 7) <= 24) { return ChartGroup.byWeek; } if (Math.round(dayDiff / 30) <= 24) { @@ -143,7 +143,7 @@ export function periodManagement(start: Date, end: Date): string { return ChartGroup.byYear; } -export const formatters : any = { +export const formatters: any = { year: function byYear(r: any[], _datePipe: DatePipe) { r.forEach(e => { @@ -181,29 +181,29 @@ export const formatters : any = { } -export function mapParams(filters:Filter[],filter:FilterMap) { - return Object.entries(filter).reduce((accumulator: any, [key, value]: any) => { +export function mapParams(filters: Filter[], filter: FilterMap) { + return Object.entries(filter).reduce((accumulator: any, [key, value]: any) => { const f = filters.find(f => f.key.toLowerCase() == key) - const val = Array.isArray(value)? value.join(','): value - if(f && f.op.value != Operation.eq.value) { + const val = Array.isArray(value) ? value.join(',') : value + if (f && f.op.value != Operation.eq.value) { accumulator[`${key}.${f.op.value}`] = val; - }else { + } else { accumulator[`${key}`] = val; } return accumulator; }, {}); - } +} - export function extractInfo(filterKey: string){ +export function extractInfo(filterKey: string) { const r = /^(.*?)__(.*)$/; const match = filterKey.match(r); - if(match){ + if (match) { return { - controlName : match[1], + controlName: match[1], key: match[2] } } return null; - } \ No newline at end of file +} \ No newline at end of file diff --git a/src/app/views/db-request-detail/db-request-detail.component.html b/src/app/views/db-request-detail/db-request-detail.component.html index 8fe3504..b2980b0 100644 --- a/src/app/views/db-request-detail/db-request-detail.component.html +++ b/src/app/views/db-request-detail/db-request-detail.component.html @@ -1,6 +1,6 @@
+ [ngStyle]="getSessionDetailBorder()">

settings_suggest @@ -47,7 +47,7 @@

en {{ getElapsedTime(selectedQuery?.end, selectedQuery?.start) | number :'1.2-3'}}s
- {{getSessionStatusTooltip(selectedQuery)}} + {{getSessionStatusTooltip(selectedQuery)}}
diff --git a/src/app/views/db-request-detail/db-request-detail.component.ts b/src/app/views/db-request-detail/db-request-detail.component.ts index d7a0b7e..cd8c56b 100644 --- a/src/app/views/db-request-detail/db-request-detail.component.ts +++ b/src/app/views/db-request-detail/db-request-detail.component.ts @@ -24,8 +24,7 @@ export interface UserData { }) export class DbRequestDetailComponent implements OnDestroy { - - UtilInstance: Utils = new Utils(); + utils: Utils = new Utils; selectedQuery: any; dbQueryId: number; dbQueryParentId: string; @@ -146,20 +145,20 @@ export class DbRequestDetailComponent implements OnDestroy { } getRe(re: string) { - return this.UtilInstance.getRe(re); + return this.utils.getRe(re); } statusBorder(status: any) { - return this.UtilInstance.statusBorder(status); + return Utils.statusBorder(status); + } + + getStateColorBool() { + return Utils.getStateColorBool(this.selectedQuery?.completed) } + getSessionDetailBorder() { - getSessionDetailBorder(session: any) { - - if (session?.type == "api" || session?.type == "outcoming") - return this.UtilInstance.statusBorderCard(session.status) - if (session?.type == "main") - return this.UtilInstance.statusBorderCard(!!session?.exception?.message) + return Utils.statusBorderCard(!this.selectedQuery?.completed) } @@ -181,7 +180,7 @@ export class DbRequestDetailComponent implements OnDestroy { } getSessionUrl(selectedSession: any) { - return this.UtilInstance.getSessionUrl(selectedSession); + return Utils.getSessionUrl(selectedSession); } diff --git a/src/app/views/session-api/session-api.component.html b/src/app/views/session-api/session-api.component.html index 154b66a..7fb53dd 100644 --- a/src/app/views/session-api/session-api.component.html +++ b/src/app/views/session-api/session-api.component.html @@ -118,13 +118,13 @@ -
+
info Aucun résultat
-
+
Chargement en cours... diff --git a/src/app/views/session-api/session-api.component.ts b/src/app/views/session-api/session-api.component.ts index 2d7bad8..66d1ccc 100644 --- a/src/app/views/session-api/session-api.component.ts +++ b/src/app/views/session-api/session-api.component.ts @@ -23,7 +23,6 @@ import { T } from '@angular/cdk/keycodes'; }) export class SessionApiComponent implements OnInit, OnDestroy { filterConstants = FilterConstants; - utilInstance: Utils = new Utils(); nameDataList: any[]; displayedColumns: string[] = ['status', 'app_name', 'method/path', 'query', 'start', 'Durée', 'user']; dataSource: MatTableDataSource = new MatTableDataSource(); @@ -209,7 +208,7 @@ export class SessionApiComponent implements OnInit, OnDestroy { statusBorder(status: number) { - return this.utilInstance.statusBorder(status) + return Utils.statusBorder(status) } applyFilter(event: Event) { diff --git a/src/app/views/session-detail/components/request-database-table/request-database-table.component.html b/src/app/views/session-detail/components/request-database-table/request-database-table.component.html new file mode 100644 index 0000000..337ffe1 --- /dev/null +++ b/src/app/views/session-detail/components/request-database-table/request-database-table.component.html @@ -0,0 +1,57 @@ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Hôte + {{element["host"] || 'N/A'}} BDD + {{getCommand(element.commands)}} +
+ {{element["schema"] || 'N/A'}} +
Début +
+ {{ (element.start*1000 |date:'dd/MM/yyyy')}} +
+
+
+ {{ (element.start*1000 |date:'HH:mm:ss.SSS')}} +
+
Durée + + {{getElapsedTime(element.end,element.start)| number :'1.2-3' || 'N/A'}}s + +
+ +
\ No newline at end of file diff --git a/src/app/views/session-detail/components/request-database-table/request-database-table.component.scss b/src/app/views/session-detail/components/request-database-table/request-database-table.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/app/views/session-detail/components/request-database-table/request-database-table.component.ts b/src/app/views/session-detail/components/request-database-table/request-database-table.component.ts new file mode 100644 index 0000000..e2c98c0 --- /dev/null +++ b/src/app/views/session-detail/components/request-database-table/request-database-table.component.ts @@ -0,0 +1,60 @@ +import { Component, EventEmitter, Input, OnInit, Output, ViewChild } from "@angular/core"; +import { MatPaginator } from "@angular/material/paginator"; +import { MatSort } from "@angular/material/sort"; +import { MatTableDataSource } from "@angular/material/table"; +import { OutcomingQuery } from "src/app/shared/model/trace.model"; +import { Utils } from "src/app/shared/util"; + +@Component({ + selector: 'request-database-table', + templateUrl: './request-database-table.component.html', + styleUrls: ['./request-database-table.component.scss'] +}) +export class RequestDatabaseTableComponent implements OnInit { + displayedColumns: string[] = ['Status', 'host', 'schema', 'start', 'duree']; + dataSource: MatTableDataSource = new MatTableDataSource(); + + @ViewChild('paginator', {static: true}) paginator: MatPaginator; + @ViewChild('sort', {static: true}) sort: MatSort; + + @Input() set requests(requests: OutcomingQuery[]) { + if(requests) { + this.dataSource = new MatTableDataSource(requests); + this.dataSource.paginator = this.paginator; + this.dataSource.sort = this.sort; + } + } + @Output() onClickRow: EventEmitter<{event: MouseEvent, row: any}> = new EventEmitter(); + + ngOnInit() { + this.dataSource.sortingDataAccessor = sortingDataAccessor; + } + + getElapsedTime(end: number, start: number,) { + return end - start; + } + + getCommand(commands: string[]): string { + let command = "" + if (commands?.length == 1) { + command = `[${commands[0]}]` + } else if (commands?.length > 1) { + command = "[SQL]" + } + return command; + } + + selectedQuery(event: MouseEvent, row: any) { + this.onClickRow.emit({event: event, row: row}); + } + + statusBorder(status: any) { + return Utils.statusBorder(status); + } +} + +const sortingDataAccessor = (row: any, columnName: string) => { + if (columnName == "duree") return (row["end"] - row["start"]) + var columnValue = row[columnName as keyof any] as string; + return columnValue; +} \ No newline at end of file diff --git a/src/app/views/session-detail/components/request-rest-table/request-rest-table.component.html b/src/app/views/session-detail/components/request-rest-table/request-rest-table.component.html new file mode 100644 index 0000000..0028bf5 --- /dev/null +++ b/src/app/views/session-detail/components/request-rest-table/request-rest-table.component.html @@ -0,0 +1,98 @@ +
+ + + search + + + + + + done + + + + + error + + + + + warning + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + Hôte + {{element['host']}}:{{element['port']}} + API + [{{element.method}}] +
+ {{element['path']}} +
Début +
+ {{ (element.start*1000 |date:'dd/MM/yyyy')}} +
+
+
+ {{ (element.start*1000 |date:'HH:mm:ss.SSS')}} +
+
Durée + + {{getElapsedTime(element.end,element.start)| number :'1.2-3' }}s + +
+
+ + info + + Aucun résultat +
+
+ +
\ No newline at end of file diff --git a/src/app/views/session-detail/components/request-rest-table/request-rest-table.component.scss b/src/app/views/session-detail/components/request-rest-table/request-rest-table.component.scss new file mode 100644 index 0000000..a755ca7 --- /dev/null +++ b/src/app/views/session-detail/components/request-rest-table/request-rest-table.component.scss @@ -0,0 +1,3 @@ +.searchwidth { + flex-grow: 1; +} \ No newline at end of file diff --git a/src/app/views/session-detail/components/request-rest-table/request-rest-table.component.ts b/src/app/views/session-detail/components/request-rest-table/request-rest-table.component.ts new file mode 100644 index 0000000..4a41559 --- /dev/null +++ b/src/app/views/session-detail/components/request-rest-table/request-rest-table.component.ts @@ -0,0 +1,86 @@ +import { Component, EventEmitter, Input, OnInit, Output, ViewChild, inject } from "@angular/core"; +import { MatPaginator } from "@angular/material/paginator"; +import { MatSort } from "@angular/material/sort"; +import { MatTableDataSource } from "@angular/material/table"; +import { OutcomingRequest } from "src/app/shared/model/trace.model"; +import { Utils } from "src/app/shared/util"; + +@Component({ + selector: 'request-rest-table', + templateUrl: './request-rest-table.component.html', + styleUrls: ['./request-rest-table.component.scss'] +}) +export class RequestRestTableComponent implements OnInit { + displayedColumns: string[] = ['Status', 'host', 'path', 'start', 'duree']; + dataSource: MatTableDataSource = new MatTableDataSource(); + filterTable = new Map(); + + @ViewChild('paginator', {static: true}) paginator: MatPaginator; + @ViewChild('sort', {static: true}) sort: MatSort; + + @Input() set requests(requests: OutcomingRequest[]) { + if(requests) { + this.dataSource = new MatTableDataSource(requests); + this.dataSource.paginator = this.paginator; + this.dataSource.sort = this.sort; + } + } + @Output() onClickRow: EventEmitter<{event: MouseEvent, row: any}> = new EventEmitter(); + + ngOnInit() { + this.dataSource.sortingDataAccessor = sortingDataAccessor; + this.dataSource.filterPredicate = filterPredicate; + } + + applyFilter(event: Event) { + const filterValue = (event.target as HTMLInputElement).value; + this.filterTable.set('filter', filterValue.trim().toLowerCase()); + this.dataSource.filter = JSON.stringify(Array.from(this.filterTable.entries())); + if (this.dataSource.paginator) { + this.dataSource.paginator.firstPage(); + } + } + + toggleFilter(filter: string[]) { + this.filterTable.set('status', filter); + this.dataSource.filter = JSON.stringify(Array.from(this.filterTable.entries())); + } + + selectedRequest(event: MouseEvent, row: any) { + this.onClickRow.emit({event: event, row: row}); + } + + getElapsedTime(end: number, start: number,) { + return end - start; + } + + statusBorder(status: any) { + return Utils.statusBorder(status); + } +} + +const sortingDataAccessor = (row: any, columnName: string) => { + if (columnName == "host") return row["host"] + ":" + row["port"] as string; + if (columnName == "start") return row['start'] as string; + if (columnName == "duree") return (row["end"] - row["start"]); + var columnValue = row[columnName as keyof any] as string; + return columnValue; +} + +const filterPredicate = (data: OutcomingRequest, filter: string) => { + var map: Map = new Map(JSON.parse(filter)); + let isMatch = true; + for (let [key, value] of map.entries()) { + if (key == 'filter') { + isMatch = isMatch && (value == '' || + (data.host?.toLowerCase().includes(value) || data.method?.toLowerCase().includes(value) || data.query?.toLowerCase().includes(value) || + data.path?.toLowerCase().includes(value))); + } else if (key == 'status') { + const s = data.status.toString(); + isMatch = isMatch && (!value.length || (value.some((status: any) => { + return s.startsWith(status[0]); + }))); + } + } + return isMatch; +} diff --git a/src/app/views/session-detail/components/request-timeline/request-timeline.component.html b/src/app/views/session-detail/components/request-timeline/request-timeline.component.html new file mode 100644 index 0000000..e6c749d --- /dev/null +++ b/src/app/views/session-detail/components/request-timeline/request-timeline.component.html @@ -0,0 +1 @@ +
diff --git a/src/app/views/session-detail/components/request-timeline/request-timeline.component.scss b/src/app/views/session-detail/components/request-timeline/request-timeline.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/app/views/session-detail/components/request-timeline/request-timeline.component.ts b/src/app/views/session-detail/components/request-timeline/request-timeline.component.ts new file mode 100644 index 0000000..bef08d0 --- /dev/null +++ b/src/app/views/session-detail/components/request-timeline/request-timeline.component.ts @@ -0,0 +1,118 @@ +import { DatePipe } from "@angular/common"; +import { Component, ElementRef, Input, OnInit, ViewChild, inject } from "@angular/core"; +import { OutcomingQuery, OutcomingRequest, Request, RunnableStage } from "src/app/shared/model/trace.model"; +import { Timeline } from "vis-timeline"; +import { EnvRouter } from "../../session-detail.component"; + +@Component({ + selector: 'request-timeline-table', + templateUrl: './request-timeline.component.html', + styleUrls: ['./request-timeline.component.scss'] +}) +export class RequestTimelineComponent { + private _router: EnvRouter = inject(EnvRouter); + + timeline: any; + pipe = new DatePipe('fr-FR'); + + @ViewChild('timeline', {static: true}) timelineElement: ElementRef; + + @Input() set request(request: any) { + if (request) { + let timeline_end = +request.end * 1000 + let timeline_start = +request.start * 1000 + let dataArray: any = [...request.requests, + ...request.queries, + ...request.stages.map((s: any) => ({ ...s, isStage: true }))]; + dataArray.splice(0, 0, { ...request, isStage: true }) + this.sortInnerArrayByDate(dataArray); + + + let data: any; + let groups: any; + let isWebapp = false, title = ''; + if (request.launchMode != null && request.launchMode === "WEBAPP") { + groups = [{ id: 0, content: request?.application?.re }]; + title = 'path'; + isWebapp = true; + } else { + groups = new Set(); + dataArray.forEach((c: any, i: number) => { + groups.add(c['threadName']) + }); + title = 'threadName'; + groups = Array.from(groups).map((g: string) => ({ id: g, content: g })) + } + data = dataArray.map((c: any, i: number) => { + let o = { + id: c.hasOwnProperty('schema') ? -i : c.id, + group: isWebapp ? 0 : c.threadName, + content: c.hasOwnProperty('isStage') ? '' : (c.schema || c.host || 'N/A'), + start: c.start * 1000, + end: c.end * 1000, + title: `${this.pipe.transform(new Date(c.start * 1000), 'HH:mm:ss.SSS')} - ${this.pipe.transform(new Date(c.end * 1000), 'HH:mm:ss.SSS')}
+

${c[title]}: ${this.getElapsedTime(c.end, c.start).toFixed(3)}s

`, + className: c.hasOwnProperty('schema') ? "bdd" : !c.hasOwnProperty('isStage') ? "rest" : "", + type: c.hasOwnProperty('isStage') ? 'background' : 'range' + } + if (o.end > timeline_end) { + timeline_end = o.end + } + return o; + }) + + + if (this.timeline) { // destroy if exists + this.timeline.destroy(); + } + // Create a Timeline + this.timeline = new Timeline(this.timelineElement.nativeElement, data, groups, { + min: timeline_start, + max: timeline_end, + clickToUse: true, + tooltip: { + followMouse: true + }, + margin: { + item: { + horizontal: -1 + } + }, + order: (a, b) => { + return b.start - a.start // inverser l'ordre + } + }); + + let that = this; + this.timeline.on('select', function (props: any) { + let id = props.items[0]; + if (isNaN(+id)) { + that._router.navigate(['/session', 'api', id]); + } + }); + + if (timeline_end != +request.end * 1000) { + this.timeline.addCustomTime(+request.end * 1000, "async"); + this.timeline.setCustomTimeMarker("async", "async"); + } + } + } + + sortInnerArrayByDate(innerArray: any[]): any[] { + return innerArray.sort((a, b) => { + if (a.start > b.start) + return 1; + + if (a.start < b.start) + return -1; + + if (a.threadName && b.threadName) + return a.threadName.localeCompare(b.threadName) + + }); + } + + getElapsedTime(end: number, start: number,) { + return end - start; + } +} \ No newline at end of file diff --git a/src/app/views/session-detail/session-detail.component.html b/src/app/views/session-detail/session-detail.component.html index 05d3c1f..bab65d7 100644 --- a/src/app/views/session-detail/session-detail.component.html +++ b/src/app/views/session-detail/session-detail.component.html @@ -1,323 +1,167 @@ -
- +
+
+ + + + + settings_suggest + {{selectedSessionType =='api' ? (selectedSession?.name|| 'N/A') + : '[' + + selectedSession?.launchMode + '] ' + selectedSession?.name || 'N/A'}} + +
+ + +
- - - settings_suggest - {{selectedSession?.type=='api' || selectedSession?.type =='outcoming' ? (selectedSession?.name|| 'N/A') - : '[' - + selectedSession?.launchMode + '] ' + selectedSession?.name || 'N/A'}} - -
- - -
+
+ +
+ - - -
-
- - [{{selectedSession?.method}}] - {{getSessionUrl(selectedSession)}} - +
+ warning{{selectedSession?.exception?.message + || selectedSession?.exception?.classname}} +
-
- warning{{selectedSession?.exception?.message - || selectedSession?.exception?.classname}} + -
-
- - - {{selectedSession?.location}} + + + person + - - - - person -
- - {{selectedSession?.user || "N/A"}} - - le {{( selectedSession?.start*1000 ) | date: 'dd/MM/yyyy à HH:mm:ss.SSS': 'fr' }} -
-
- {{selectedSession?.inDataSize || 0}}o - swap_vert - {{selectedSession?.outDataSize}}o en {{ getElapsedTime(selectedSession?.end, selectedSession?.start) | - number :'1.2-3'}}s -
- {{selectedSession?.status}} -
- - - - - storage - {{selectedSession?.application?.name}} - -
- -
-
- - -
-
- Database + le {{( selectedSession?.start*1000 ) | date: 'dd/MM/yyyy à HH:mm:ss.SSS': 'fr' }}
-
- - {{ item.key }} - -
{{ item.value[0].databaseName }} v.{{ - item.value[0].databaseVersion}}
+
+ {{selectedSession?.inDataSize || 0}}o + swap_vert + {{selectedSession?.outDataSize}}o en {{ getElapsedTime(selectedSession?.end, selectedSession?.start) + | + number :'1.2-3'}}s
-
+ {{selectedSession?.status}} + + + + + + storage + {{selectedSession?.application?.name}} + +
+
+
+ - - -
- {{selectedSession?.application?.address}} en {{selectedSession?.application?.env}} -
- - {{selectedSession?.application?.os}} - - - {{selectedSession?.application?.re}} - -
-
-
-
+
+
+ Database +
+
+ + {{ item.key }} + +
{{ item.value[0].databaseName }} v.{{ + item.value[0].databaseVersion}}
+
+
-
- -
- west -
- Appels - sortants
-
- -
-
- - - search - - - - - done - - - - - error + + +
+ {{selectedSession?.application?.address}} en {{selectedSession?.application?.env}} +
+ + {{selectedSession?.application?.os}} -
- - - warning + + {{selectedSession?.application?.re}} - -
+ +
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Hôte - {{element['host']}}:{{element['port']}} - API - [{{element.method}}] -
- {{element['path']}} -
Début -
- {{ (element.start*1000 |date:'dd/MM/yyyy')}} -
-
-
- {{ (element.start*1000 |date:'HH:mm:ss.SSS')}} -
-
Durée - - {{getElapsedTime(element.end,element.start)| number :'1.2-3' }}s - -
-
- - info - - Aucun résultat -
-
- +
+
+ +
+ west +
+ Appels + sortants
+
+ +
+
-
- - - -
-
- -
- Database -
Base de - donnée
+
+
+ +
+ Database +
Base de + donnée
+
+
- +
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Hôte - {{element["host"] || 'N/A'}} BDD - {{getCommand(element.commands)}} -
- {{element["schema"] || 'N/A'}} -
Début -
- {{ (element.start*1000 |date:'dd/MM/yyyy')}} -
-
-
- {{ (element.start*1000 |date:'HH:mm:ss.SSS')}} -
-
Durée - - {{getElapsedTime(element.end,element.start)| number :'1.2-3' || 'N/A'}}s - -
-
-
- -
-
- +
- view_timeline - Chronologie + style="display: flex; flex-direction: row; justify-content: center; align-items: center; align-content: center;"> + +
+ view_timeline + Chronologie +
+
- +
-
-
- - -
+

Aucun détail disponible ..
Vérifiez que TraceAPI est bien configuré sur {{ diff --git a/src/app/views/session-detail/session-detail.component.ts b/src/app/views/session-detail/session-detail.component.ts index c2b8029..5b44724 100644 --- a/src/app/views/session-detail/session-detail.component.ts +++ b/src/app/views/session-detail/session-detail.component.ts @@ -1,69 +1,29 @@ -import { AfterContentInit, Component, ElementRef, Injectable, NgZone, OnDestroy, ViewChild } from '@angular/core'; -import { MatDialog } from '@angular/material/dialog'; -import { MatTableDataSource } from '@angular/material/table'; +import { Component, Injectable, OnDestroy } from '@angular/core'; import { ActivatedRoute, NavigationExtras, Router } from '@angular/router'; -import { Observable, Subscription, combineLatest } from "rxjs"; -import { Timeline } from 'vis-timeline'; -import { ExceptionInfo, OutcomingQuery, OutcomingRequest, RunnableStage } from 'src/app/shared/model/trace.model'; +import { Observable, combineLatest, finalize } from "rxjs"; import { Utils } from 'src/app/shared/util'; -import { DatePipe, Location } from '@angular/common'; -import { MatPaginator } from '@angular/material/paginator'; -import { MatSort } from '@angular/material/sort'; +import { Location } from '@angular/common'; import { TraceService } from 'src/app/shared/services/trace.service'; import { application } from 'src/environments/environment'; type sessionType = 'main' | 'api'; -export interface UserData { - id: string; - name: string; - progress: string; - fruit: string; -} @Component({ templateUrl: './session-detail.component.html', styleUrls: ['./session-detail.component.scss'], }) -export class SessionDetailComponent implements AfterContentInit, OnDestroy { - - UtilInstance: Utils = new Utils(); - outcomingRequestDisplayedColumns: string[] = ['Status', 'host', 'path', 'start', 'duree']; - outcomingQueryDisplayedColumns: string[] = ['Status', 'host', 'schema', 'start', 'duree']; - outcomingRequestdataSource: MatTableDataSource = new MatTableDataSource(); - outcomingQuerydataSource: MatTableDataSource; +export class SessionDetailComponent implements OnDestroy { selectedSession: any // IncomingRequest | Mainrequest | OutcomingRequest; selectedSessionType: string; - sessionDetailSubscription: Observable; sessionParent: { id: string, type: sessionType }; - outcomingRequestList: any; - outcomingQueryList: any; - isComplete: boolean = true; isLoading: boolean = false; - data: any[]; - chartOp: any; - resizeSubscription: any; paramsSubscription: any; - chart: any; - options: any; - container: any; - dataTable: any; - timeLine: any; queryBySchema: any[]; env: any; - pipe = new DatePipe('fr-FR'); - filterTable = new Map(); - @ViewChild('timeline') timelineContainer: ElementRef; - @ViewChild('OutcomingRequestPaginator') outcomingRequestPaginator: MatPaginator; - @ViewChild('OutcomingRequestSort') outcomingRequestSort: MatSort; - @ViewChild('OutcomingQueryPaginator') outcomingQueryPaginator: MatPaginator; - @ViewChild('OutcomingQuerySort') outcomingQuerySort: MatSort; - constructor(private _activatedRoute: ActivatedRoute, private _traceService: TraceService, - public dialog: MatDialog, - private zone: NgZone, private _router: EnvRouter, private _location: Location) { @@ -74,261 +34,73 @@ export class SessionDetailComponent implements AfterContentInit, OnDestroy { next: ([params, queryParams]) => { this.env = queryParams.env || application.default_env; this.selectedSessionType = params.type; - switch (this.selectedSessionType) { - case "main": - this.sessionDetailSubscription = this._traceService.getMainRequestById(params.id); - break; - case "api": - this.sessionDetailSubscription = this._traceService.getIncomingRequestById(params.id); - break; - default: - } this.getSessionById(params.id); this._location.replaceState(`${this._router.url.split('?')[0]}?env=${this.env}`) } }); } - ngAfterContentInit(): void { - /*this._activatedRoute.paramMap.subscribe((paramsList: any) => { - this.selectedSessionType = paramsList.params['type']; - this.getSessionById(paramsList.params['id']); - })*/ - } - getSessionById(id: string) { - this.isLoading = true; - this.sessionDetailSubscription.subscribe({ - next: (d: any) => { - this.selectedSession = d; - if (this.selectedSession) { - this.selectedSession.type = this.selectedSessionType; - - // Api request list - this.outcomingRequestList = this.selectedSession.requests; - this.outcomingRequestdataSource = new MatTableDataSource(this.outcomingRequestList); - setTimeout(() => { this.outcomingRequestdataSource.paginator = this.outcomingRequestPaginator }); - setTimeout(() => { this.outcomingRequestdataSource.sort = this.outcomingRequestSort }); - this.outcomingRequestdataSource.sortingDataAccessor = (row: any, columnName: string) => { - if (columnName == "host") return row["host"] + ":" + row["port"] as string; - if (columnName == "start") return row['start'] as string; - if (columnName == "duree") return (row["end"] - row["start"]); - var columnValue = row[columnName as keyof any] as string; - return columnValue; - } - - this.outcomingRequestdataSource.filterPredicate = (data: OutcomingRequest, filter: string) => { - var map: Map = new Map(JSON.parse(filter)); - let isMatch = true; - for (let [key, value] of map.entries()) { - if (key == 'filter') { - isMatch = isMatch && (value == '' || - (data.host?.toLowerCase().includes(value) || data.method?.toLowerCase().includes(value) || data.query?.toLowerCase().includes(value) || - data.path?.toLowerCase().includes(value))); - } else if (key == 'status') { - const s = data.status.toString(); - isMatch = isMatch && (!value.length || (value.some((status: any) => { - return s.startsWith(status[0]); - }))); - } + (this.selectedSessionType == "main" ? this._traceService.getMainRequestById(id) : this._traceService.getIncomingRequestById(id)) + .pipe(finalize(() => this.isLoading = false)).subscribe({ + next: (d: any) => { + this.selectedSession = d; + if (this.selectedSession) { + this.groupQueriesBySchema(); + + // Check if parent exist + this.sessionParent = null; + if (this.selectedSessionType == "api") { + this._traceService.getSessionParentByChildId(id).subscribe({ + next: (data: { id: string, type: sessionType }) => { + this.sessionParent = data; + }, + error: err => console.log(err) + }) } - return isMatch; - } - this.outcomingRequestdataSource.filter = JSON.stringify(Array.from(this.filterTable.entries())); - setTimeout(() => { this.outcomingRequestdataSource.paginator.pageIndex = 0 }); - - // DB request list - this.outcomingQueryList = this.selectedSession.queries - this.outcomingQuerydataSource = new MatTableDataSource(this.outcomingQueryList); - setTimeout(() => { this.outcomingQuerydataSource.paginator = this.outcomingQueryPaginator }); - setTimeout(() => { this.outcomingQuerydataSource.sort = this.outcomingQuerySort }); - this.outcomingQuerydataSource.sortingDataAccessor = (row: any, columnName: string) => { - if (columnName == "duree") return (row["end"] - row["start"]) - var columnValue = row[columnName as keyof any] as string; - return columnValue; - } - - this.groupQueriesBySchema(); - - // Timeline - this.visjs(); - - // Check if parent exist - this.sessionParent = null; - if (this.selectedSession.type == "api") { - this._traceService.getSessionParentByChildId(id).subscribe({ - next: (data: { id: string, type: sessionType }) => { - this.sessionParent = data; - }, - error: err => console.log(err) - }) - } - - this.isLoading = false; - this.isComplete = true; - } else { - this.isLoading = false; - this.isComplete = false; - // navigate to tab incoming - } - }, - error: err => { - this.isLoading = false; - } - }); - } - - visjs() { - - let timeline_end = +this.selectedSession.end * 1000 - let timeline_start = +this.selectedSession.start * 1000 - let dataArray: any = [...this.selectedSession.requests, - ...this.selectedSession.queries, - ...this.selectedSession.stages.map((s: any) => ({ ...s, isStage: true }))]; - dataArray.splice(0, 0, { ...this.selectedSession, isStage: true }) - this.sortInnerArrayByDate(dataArray); - - - let data: any; - let groups: any; - let isWebapp = false, title = ''; - if (this.selectedSessionType === "main" && this.selectedSession.launchMode === "WEBAPP") { - groups = [{ id: 0, content: this.selectedSession?.application?.re }]; - title = 'path'; - isWebapp = true; - } else { - groups = new Set(); - dataArray.forEach((c: any, i: number) => { - groups.add(c['threadName']) - }); - title = 'threadName'; - groups = Array.from(groups).map((g: string) => ({ id: g, content: g })) - } - data = dataArray.map((c: any, i: number) => { - let o = { - id: c.hasOwnProperty('schema') ? -i : c.id, - group: isWebapp ? 0 : c.threadName, - content: c.hasOwnProperty('isStage') ? '' : (c.schema || c.host || 'N/A'), - start: c.start * 1000, - end: c.end * 1000, - title: `${this.pipe.transform(new Date(c.start * 1000), 'HH:mm:ss.SSS')} - ${this.pipe.transform(new Date(c.end * 1000), 'HH:mm:ss.SSS')}
-

${c[title]}: ${this.getElapsedTime(c.end, c.start).toFixed(3)}s

`, - className: c.hasOwnProperty('schema') ? "bdd" : !c.hasOwnProperty('isStage') ? "rest" : "", - type: c.hasOwnProperty('isStage') ? 'background' : 'range' - } - if (o.end > timeline_end) { - timeline_end = o.end - } - return o; - }) - - - if (this.timeLine) { // destroy if exists - this.timeLine.destroy(); - } - // Create a Timeline - this.timeLine = new Timeline(this.timelineContainer.nativeElement, data, groups - , { - min: timeline_start, - max: timeline_end, - clickToUse: true, - tooltip: { - followMouse: true - }, - margin: { - item: { - horizontal: -1 } - }, - order: (a, b) => { - return b.start - a.start // inverser l'ordre } }); - - let that = this; - this.timeLine.on('select', function (props: any) { - let id = props.items[0]; - if (isNaN(+id)) { - that._router.navigate(['/session', 'api', id]); - } - }); - - if (timeline_end != +this.selectedSession.end * 1000) { - this.timeLine.addCustomTime(+this.selectedSession.end * 1000, "async"); - this.timeLine.setCustomTimeMarker("async", "async"); - } - } - selectedRequest(event: MouseEvent, row: any) { - if (row) { - if (event.ctrlKey) { - this._router.open(`#/session/api/${row}`, '_blank',) + selectedRequest(event: { event: MouseEvent, row: any }) { + if (event.row) { + if (event.event.ctrlKey) { + this._router.open(`#/session/api/${event.row}`, '_blank',) } else { - this._router.navigate(['/session', 'api', row], { queryParams: { env: this.env } }); // TODO remove env FIX BUG + this._router.navigate(['/session', 'api', event.row], { queryParams: { env: this.env } }); // TODO remove env FIX BUG } } } - selectedQuery(event: MouseEvent, queryId:any){ // TODO finish this - if(queryId){ - if( event.ctrlKey){ - this._router.open(`#/session/${this.selectedSession.type}/${this.selectedSession.id}/db/${queryId}`,'_blank',) - }else { - console.log('/session', this.selectedSession.type, this.selectedSession.id, 'db', queryId) - this._router.navigate(['/session', this.selectedSession.type, this.selectedSession.id, 'db', queryId],{ - queryParams:{env:this.env} + selectedQuery(event: { event: MouseEvent, row: any }) { // TODO finish this + if (event.row) { + if (event.event.ctrlKey) { + this._router.open(`#/session/${this.selectedSessionType}/${this.selectedSession.id}/db/${event.row}`, '_blank',) + } else { + this._router.navigate(['/session', this.selectedSessionType, this.selectedSession.id, 'db', event.row], { + queryParams: { env: this.env } }); } } } + getStateColor() { + return Utils.getStateColor(this.selectedSession?.status) + } + getElapsedTime(end: number, start: number,) { - // return (new Date(end * 1000).getTime() - new Date(start * 1000).getTime()) / 1000 return end - start; - } - getRe(re: string) { - return this.UtilInstance.getRe(re); - } - - statusBorder(status: any) { - return this.UtilInstance.statusBorder(status); - } - - - getSessionDetailBorder(session: any) { + getSessionDetailBorder() { - if (session?.type == "api" || session?.type == "outcoming") - return this.UtilInstance.statusBorderCard(session.status) - if (session?.type == "main") - return this.UtilInstance.statusBorderCard(!!session?.exception?.message) - - } - - getSessionStatusTooltip(session: any) { - if (session?.type == "api" || session?.type == "outcoming") - return session?.status; - if (session?.type == "main") - return !session?.exception?.message ? "réussi" : "échoué"; - } - - - configDbactions(session: any) { - session.queries.forEach((query: any) => { - query.actions.forEach((db: any, i: number) => { - if (query.actions[i + 1]) { - let diffElapsed = new Date(db.end * 1000).getTime() - new Date(query.actions[i + 1].start * 1000).getTime(); - - if (diffElapsed != 0) { - query.actions.splice(i + 1, 0, { 'type': ' ', 'exception': { 'classname': null, 'message': null }, 'start': db.end, 'end': query.actions[i + 1].start }) - } - } - }); + if (this.selectedSessionType == "api") + return Utils.statusBorderCard(this.selectedSession.status) + if (this.selectedSessionType == "main") + return Utils.statusBorderCard(!!this.selectedSession?.exception?.message) - }); } groupQueriesBySchema() { @@ -344,8 +116,8 @@ export class SessionDetailComponent implements AfterContentInit, OnDestroy { } } - getSessionUrl(selectedSession: any) { - return this.UtilInstance.getSessionUrl(selectedSession); + getSessionUrl() { + return Utils.getSessionUrl(this.selectedSession); } navigate(event: MouseEvent, targetType: string, extraParam?: string) { @@ -372,56 +144,11 @@ export class SessionDetailComponent implements AfterContentInit, OnDestroy { } } - sortInnerArrayByDate(innerArray: any[]): any[] { - return innerArray.sort((a, b) => { - if (a.start > b.start) - return 1; - - if (a.start < b.start) - return -1; - - if (a.threadName && b.threadName) - return a.threadName.localeCompare(b.threadName) - - }); - } - - isQueryCompleted(query: any): boolean { - return query.actions.every((a: any) => !a?.exception?.classname && !a?.exception?.message); - } - - getCommand(commands: string[]): string { - let command = "" - if (commands?.length == 1) { - command = `[${commands[0]}]` - } else if (commands?.length > 1) { - command = "[SQL]" - } - return command; - } - ngOnDestroy() { - if (this.resizeSubscription) { - this.resizeSubscription.unsubscribe(); - } if (this.paramsSubscription) { this.paramsSubscription.unsubscribe(); } } - - applyFilter(event: Event) { - const filterValue = (event.target as HTMLInputElement).value; - this.filterTable.set('filter', filterValue.trim().toLowerCase()); - this.outcomingRequestdataSource.filter = JSON.stringify(Array.from(this.filterTable.entries())); - if (this.outcomingRequestdataSource.paginator) { - this.outcomingRequestdataSource.paginator.firstPage(); - } - } - - toggleFilter(filter: string[]) { - this.filterTable.set('status', filter); - this.outcomingRequestdataSource.filter = JSON.stringify(Array.from(this.filterTable.entries())); - } } @Injectable() diff --git a/src/app/views/session-main/session-main.component.html b/src/app/views/session-main/session-main.component.html index cdf7a7e..d9f402e 100644 --- a/src/app/views/session-main/session-main.component.html +++ b/src/app/views/session-main/session-main.component.html @@ -89,7 +89,7 @@
{{ utilInstance.convertSeconds(getElapsedTime(row.end,row.start)) }} + matTooltipClass="mat-tooltip">{{ utils.convertSeconds(getElapsedTime(row.end,row.start)) }}
@@ -110,7 +110,7 @@ Aucun résultat -
+
Chargement en cours... diff --git a/src/app/views/session-main/session-main.component.ts b/src/app/views/session-main/session-main.component.ts index e4f498a..b7cadd6 100644 --- a/src/app/views/session-main/session-main.component.ts +++ b/src/app/views/session-main/session-main.component.ts @@ -6,7 +6,7 @@ import { MatTableDataSource } from '@angular/material/table'; import { ActivatedRoute, Params, Router } from '@angular/router'; import { BehaviorSubject, Subscription } from 'rxjs'; import { Location } from '@angular/common'; -import { Mainrequest } from 'src/app/shared/model/trace.model'; +import { MainRequest } from 'src/app/shared/model/trace.model'; import { Utils } from 'src/app/shared/util'; import { TraceService } from 'src/app/shared/services/trace.service'; import { EnvRouter } from '../session-detail/session-detail.component'; @@ -21,10 +21,10 @@ import { FilterService } from 'src/app/shared/services/filter.service'; }) export class SessionMainComponent implements OnInit, OnDestroy { filterConstants = FilterConstants; - utilInstance: Utils = new Utils(); + utils: Utils = new Utils(); displayedColumns: string[] = ['status', 'app_name', 'session', 'location', 'start', 'Durée', 'user']; - dataSource: MatTableDataSource = new MatTableDataSource(); - mainRequestList: Mainrequest[]; + dataSource: MatTableDataSource = new MatTableDataSource(); + mainRequestList: MainRequest[]; serverFilterForm = new FormGroup({ launchmode: new FormControl(""), dateRangePicker: new FormGroup({ @@ -88,7 +88,7 @@ export class SessionMainComponent implements OnInit, OnDestroy { this.isLoading = true; this.dataSource.data = []; - this.subscription = this._traceService.getMainRequestByCriteria(params).subscribe((d: Mainrequest[]) => { + this.subscription = this._traceService.getMainRequestByCriteria(params).subscribe((d: MainRequest[]) => { if (d) { this.dataSource = new MatTableDataSource(d); this.dataSource.paginator = this.paginator; @@ -164,7 +164,7 @@ export class SessionMainComponent implements OnInit, OnDestroy { } statusBorder(status: number) { - return this.utilInstance.statusBorder(status) + return Utils.statusBorder(status) } diff --git a/src/app/views/tree/tree.component.ts b/src/app/views/tree/tree.component.ts index bc283b8..cb13ab7 100644 --- a/src/app/views/tree/tree.component.ts +++ b/src/app/views/tree/tree.component.ts @@ -22,7 +22,6 @@ export class TreeComponent implements OnDestroy { private _zone = inject(NgZone); private _location = inject(Location); - UtilInstance: Utils = new Utils(); id: string; groupedExchange: any; exchange: any; @@ -278,7 +277,7 @@ export class TreeComponent implements OnDestroy { break; case 'db': - modal += ` ${value.completed ? "réussi" : "échoué"}
` + modal += ` ${value.completed ? "réussi" : "échoué"}
` modal += `Thread : ${value.threadName || 'N/A'}
` modal += `Schema : ${value.schema || 'N/A'}
` modal += `Hôte : ${value.host || 'N/A'}
` @@ -290,9 +289,9 @@ export class TreeComponent implements OnDestroy { break; case 'api': - modal += ` ${value.remoteTrace.status}     ${value.remoteTrace.path}
` + modal += ` ${value.remoteTrace.status}     ${value.remoteTrace.path}
` modal += `Thread : ${value.threadName || 'N/A'}
` - modal += `Latence: ${self.UtilInstance.getElapsedTime(value.remoteTrace?.start, value.start)}s
`; + modal += `Latence: ${Utils.getElapsedTime(value.remoteTrace?.start, value.start)}s
`; modal += `${value.remoteTrace?.exception?.classname || ''} ${value.remoteTrace?.exception?.message || ''}
` // modal += ` ${self.UtilInstance.getElapsedTime(value.remoteTrace.end, value.remoteTrace.start)}s`; break; @@ -385,7 +384,7 @@ export class TreeComponent implements OnDestroy { vertexIcon = this.getVertexIconType(r) r.remoteTrace.application.name = r.remoteTrace.name; req = this.graph.insertVertex(this.parent, null, { data: [r] }, 0, 0, 80, 30, 'shape=image;image=assets/mxgraph/api.drawio.svg;fillColor=#81D060;') - edgeStyle += `strokeColor=${this.UtilInstance.getStateColor(r.status)};`; + edgeStyle += `strokeColor=${Utils.getStateColor(r.status)};`; edgeLabel = this.getElapsedTime(r.end, r.start) + "s" this.graph.insertEdge(this.parent, null, edgeLabel, exParent, req, edgeStyle) }) @@ -414,7 +413,7 @@ export class TreeComponent implements OnDestroy { else edgeLabel = `${ex?.remoteTrace.parentCallCount - ex?.remoteTrace.succesCalls} / ${ex?.remoteTrace.parentCallCount}`; } else { - edgeStyle += "strokeColor=" + this.UtilInstance.getStateColor(exchange.data[0].status) + edgeStyle += "strokeColor=" + Utils.getStateColor(exchange.data[0].status) edgeLabel = `${this.getElapsedTime(exchange.data[0].end, exchange.data[0].start)}s` } diff --git a/src/app/views/views.module.ts b/src/app/views/views.module.ts index ac9e15a..6c8f60a 100644 --- a/src/app/views/views.module.ts +++ b/src/app/views/views.module.ts @@ -20,6 +20,9 @@ import { StatsUserComponent } from './stats-user/stats-user.component'; import { ExceptionTableComponent } from '../shared/components/stats/exception-table/exception-table.component'; import { ChartComponent } from '@oneteme/jquery-apexcharts'; import { DbRequestDetailComponent } from './db-request-detail/db-request-detail.component'; +import { RequestRestTableComponent } from './session-detail/components/request-rest-table/request-rest-table.component'; +import { RequestDatabaseTableComponent } from './session-detail/components/request-database-table/request-database-table.component'; +import { RequestTimelineComponent } from './session-detail/components/request-timeline/request-timeline.component'; @NgModule({ imports: [ @@ -36,6 +39,9 @@ import { DbRequestDetailComponent } from './db-request-detail/db-request-detail. declarations: [ SessionApiComponent, SessionDetailComponent, + RequestRestTableComponent, + RequestDatabaseTableComponent, + RequestTimelineComponent, SessionMainComponent, StatsAppComponent, StatsApiComponent, diff --git a/src/styles.scss b/src/styles.scss index da2a0d4..e685f1d 100644 --- a/src/styles.scss +++ b/src/styles.scss @@ -173,6 +173,18 @@ mat-form-field.loading { justify-content: center; } +.loading-row { + display: flex; + gap: .5em; + height: calc(100vh - 96px - 56px - 48px - 45px - 1.5em); + color: #707070; + font-weight: 500; + width: 100%; + font-size: 12px; + align-items: center; + justify-content: center; +} + .mdc-data-table__cell:has(chart) { overflow: initial; } From 3bd69fd6d97acef4f4bec41ca663c9efa35308e3 Mon Sep 17 00:00:00 2001 From: fufuu Date: Thu, 6 Jun 2024 10:45:18 +0200 Subject: [PATCH 021/126] hotfix --- src/app/views/session-api/session-api.component.html | 4 ++-- .../request-database-table.component.scss | 7 +++++++ .../request-rest-table/request-rest-table.component.scss | 8 ++++++++ 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/app/views/session-api/session-api.component.html b/src/app/views/session-api/session-api.component.html index 7fb53dd..a245ca3 100644 --- a/src/app/views/session-api/session-api.component.html +++ b/src/app/views/session-api/session-api.component.html @@ -118,13 +118,13 @@ -
+
info Aucun résultat
-
+
Chargement en cours... diff --git a/src/app/views/session-detail/components/request-database-table/request-database-table.component.scss b/src/app/views/session-detail/components/request-database-table/request-database-table.component.scss index e69de29..131e88b 100644 --- a/src/app/views/session-detail/components/request-database-table/request-database-table.component.scss +++ b/src/app/views/session-detail/components/request-database-table/request-database-table.component.scss @@ -0,0 +1,7 @@ +.mat-mdc-row .mat-mdc-cell { + cursor: pointer; +} + +.mat-mdc-row:hover .mat-mdc-cell { + background-color: rgb(206, 206, 206); +} \ No newline at end of file diff --git a/src/app/views/session-detail/components/request-rest-table/request-rest-table.component.scss b/src/app/views/session-detail/components/request-rest-table/request-rest-table.component.scss index a755ca7..780ed25 100644 --- a/src/app/views/session-detail/components/request-rest-table/request-rest-table.component.scss +++ b/src/app/views/session-detail/components/request-rest-table/request-rest-table.component.scss @@ -1,3 +1,11 @@ .searchwidth { flex-grow: 1; +} + +.mat-mdc-row .mat-mdc-cell { + cursor: pointer; +} + +.mat-mdc-row:hover .mat-mdc-cell { + background-color: rgb(206, 206, 206); } \ No newline at end of file From e678cc409065e505bce7a4b9e3e071b5da6800df Mon Sep 17 00:00:00 2001 From: YoussefDahi Date: Thu, 6 Jun 2024 10:51:37 +0200 Subject: [PATCH 022/126] disabled timeline element selection --- .../components/request-timeline/request-timeline.component.ts | 1 + src/app/views/session-detail/session-detail.component.ts | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/app/views/session-detail/components/request-timeline/request-timeline.component.ts b/src/app/views/session-detail/components/request-timeline/request-timeline.component.ts index bef08d0..3b67a3b 100644 --- a/src/app/views/session-detail/components/request-timeline/request-timeline.component.ts +++ b/src/app/views/session-detail/components/request-timeline/request-timeline.component.ts @@ -70,6 +70,7 @@ export class RequestTimelineComponent { min: timeline_start, max: timeline_end, clickToUse: true, + selectable : false, tooltip: { followMouse: true }, diff --git a/src/app/views/session-detail/session-detail.component.ts b/src/app/views/session-detail/session-detail.component.ts index 5b44724..8cff20c 100644 --- a/src/app/views/session-detail/session-detail.component.ts +++ b/src/app/views/session-detail/session-detail.component.ts @@ -56,7 +56,7 @@ export class SessionDetailComponent implements OnDestroy { next: (data: { id: string, type: sessionType }) => { this.sessionParent = data; }, - error: err => console.log(err) + error: err => {} }) } } From d36597f85df9f1d66ce0f913bbf154c5bf726cf5 Mon Sep 17 00:00:00 2001 From: fufuu Date: Wed, 3 Jul 2024 10:01:18 +0200 Subject: [PATCH 023/126] adaptation --- src/app/shared/model/trace.model.ts | 2 +- src/app/shared/model/v3/trace.model.ts | 124 ++++++++++++++++++ src/app/shared/services/stats.service.ts | 5 + src/app/shared/services/trace.service.ts | 7 +- src/app/views/constants.ts | 6 +- .../session-api/session-api.component.html | 8 +- .../session-api/session-api.component.ts | 22 ++-- .../session-main/session-main.component.html | 8 +- .../session-main/session-main.component.ts | 9 +- 9 files changed, 160 insertions(+), 31 deletions(-) create mode 100644 src/app/shared/model/v3/trace.model.ts diff --git a/src/app/shared/model/trace.model.ts b/src/app/shared/model/trace.model.ts index a17ac8b..9c365f5 100644 --- a/src/app/shared/model/trace.model.ts +++ b/src/app/shared/model/trace.model.ts @@ -11,7 +11,7 @@ export interface Request { stages: RunnableStage[]; } -export interface RestRequest extends Request { +export interface RestRequest extends Request{ method: string; protocol: string; host: string; diff --git a/src/app/shared/model/v3/trace.model.ts b/src/app/shared/model/v3/trace.model.ts new file mode 100644 index 0000000..465d389 --- /dev/null +++ b/src/app/shared/model/v3/trace.model.ts @@ -0,0 +1,124 @@ +export interface InstanceRestSession extends RestSession { + instanceId: string; + instanceUser: string; + appName: string; + mask: number; +} + +export interface InstanceMainSession extends MainSession { + instanceId: string; + instanceUser: string; + appName: string; + mask: number; +} + +export interface RestSession extends RestRequest { + name: string; + requests: Array; + queries: Array; + stages: Array; + ftpRequests: Array; + mailRequests: Array; + userAgent: string; +} + +export interface MainSession extends RunnableStage { + id: string; + type: string; + requests: Array; + queries: Array; + stages: Array; + ftpRequests: Array; + mailRequests: Array; +} + +export interface RestRequest extends SessionStage { + id: string; + method: string; + protocol: string; + host: string; + port: number; + path: string; + query: string; + contentType: string; + authScheme: string; + status: number; + inDataSize: number; + outDataSize: number; + exception: ExceptionInfo; + inContentEncoding: string; + outContentEncoding: string; +} + +export interface DatabaseRequest { + host: string; + port: number; + database: string; + driverVersion: string; + databaseName: string; + databaseVersion: string; + actions: Array; + commands: Array; +} + +export interface FtpRequest { + protocol: string; + host: string; + port: number; + serverVersion: string; + clientVersion: string; + actions: Array; +} + +export interface MailRequest { + host: string; + port: number; + actions: Array; + mails: Array; +} + +export interface RunnableStage extends SessionStage { + name: string; + location: string; + exception: ExceptionInfo; +} + +export interface DatabaseRequestStage extends RequestStage { + count: Array; +} + +export interface FtpRequestStage extends RequestStage { + args: Array; +} + +export interface MailRequestStage extends RequestStage { + +} + +export interface Mail { + subject: string; + contentType: string; + from: Array; + recipients: Array; + replyTo: Array; + size: number; +} + +export interface RequestStage { + name: string; + start: Date; + end: Date; + exception: ExceptionInfo; +} + +export interface SessionStage { + user: string; + start: Date; + end: Date; + threadName: string; +} + +export interface ExceptionInfo { + type: string; + message: string; +} \ No newline at end of file diff --git a/src/app/shared/services/stats.service.ts b/src/app/shared/services/stats.service.ts index 6872249..33c00c0 100644 --- a/src/app/shared/services/stats.service.ts +++ b/src/app/shared/services/stats.service.ts @@ -21,4 +21,9 @@ export class StatsService { let url = `${localStorage.getItem('server')}/stat/mainsession`; return this.http.get(url, { params: params }); } + + getInstance(params: any) { + let url = `${localStorage.getItem('server')}/stat/instance`; + return this.http.get(url, { params: params }); + } } \ No newline at end of file diff --git a/src/app/shared/services/trace.service.ts b/src/app/shared/services/trace.service.ts index c236f2b..ebc07fd 100644 --- a/src/app/shared/services/trace.service.ts +++ b/src/app/shared/services/trace.service.ts @@ -1,11 +1,12 @@ import { HttpClient, HttpErrorResponse } from "@angular/common/http"; import { Injectable } from "@angular/core"; -import { catchError, throwError } from "rxjs"; +import { Observable, catchError, throwError } from "rxjs"; +import { RestSession } from "../model/v3/trace.model"; @Injectable({ providedIn: 'root' }) export class TraceService { - readonly INCOMING_REQUEST_URL = `${localStorage.getItem('server')}/trace/session/api`; - readonly MAIN_REQUEST_URL = `${localStorage.getItem('server')}/trace/session/main`; + readonly INCOMING_REQUEST_URL = `${localStorage.getItem('server')}/v3/trace/session/api`; + readonly MAIN_REQUEST_URL = `${localStorage.getItem('server')}/v3/trace/session/main`; constructor(private http: HttpClient) { } diff --git a/src/app/views/constants.ts b/src/app/views/constants.ts index 6274891..ad12e59 100644 --- a/src/app/views/constants.ts +++ b/src/app/views/constants.ts @@ -408,11 +408,11 @@ export class FilterConstants { static readonly SESSION_API: Filter[] = [ { key: 'query', label: 'Query params', type: 'input', row: 2, col: 1, op: Operation.like }, - { key: 'status', label: 'Status', type: 'select', row: 3, col: 1, options: [{ status: '200' }, { status: '201' }, { status: '202' }, { status: '400' }, { status: '401' }, { status: '403' }, { status: '404' }, { status: '405' }, { status: '409' }, { status: '415' }, { status: '500' }, { status: '503' }], op: Operation.like }, - { key: 'method', label: 'Method', type: 'select', width: 20, row: 1, col: 1, options: [{ method: 'GET' }, { method: 'PUT' }, { method: 'POST' }, { method: 'DELETE' }, { method: 'OPTIONS' }], op: Operation.eq }, + { key: 'status', label: 'Status', type: 'select', row: 3, col: 1, endpoint: "/stat/apisession", query: { 'column.distinct': 'status:status', 'order': 'status.asc' }, op: Operation.eq }, + { key: 'method', label: 'Method', type: 'select', width: 20, row: 1, col: 1, endpoint: "/stat/apisession", query: { 'column.distinct': 'method:method', 'order': 'method.asc' }, op: Operation.eq }, { key: 'path', label: 'Path', type: 'input', row: 1, col: 2, op: Operation.like }, { key: 'api_name', label: 'Nom API', type: 'select', row: 3, col: 2, endpoint: "/stat/apisession", query: { 'column.distinct': 'api_name.coalesce(null):api_name', 'api_name.not': 'null', 'order': 'api_name.coalesce(null).asc' }, op: Operation.eq }, - { key: 'user', label: 'Utilisateur', type: 'select', row: 3, col: 3, endpoint: "/stat/apisession", query: { 'column.distinct': 'user.coalesce(null)', 'user.not': 'null', 'order': 'user.coalesce(null).asc' }, op: Operation.eq } + { key: 'user', label: 'Utilisateur', type: 'select', row: 3, col: 3, endpoint: "/stat/instance", query: { 'column.distinct': 'user.coalesce(null)', 'user.not': 'null', 'order': 'user.coalesce(null).asc' }, op: Operation.eq } // new Filter("err_type", "Exception", 'select', 50, "/stat/apisession", null, null, { 'column.distinct': 'err_type:err_type', 'order': 'err_type.asc' }), // new Filter("address", "adresse", 'input', 50), // new Filter("os", "OS", 'select', 50, "/stat/apisession", null, null, { 'column.distinct': 'os', 'order': 'os.asc' }), diff --git a/src/app/views/session-api/session-api.component.html b/src/app/views/session-api/session-api.component.html index a245ca3..ecef8a7 100644 --- a/src/app/views/session-api/session-api.component.html +++ b/src/app/views/session-api/session-api.component.html @@ -70,7 +70,7 @@ Serveur -
{{row.application.name || ''}}
+ {{row.appName || ''}}
@@ -100,18 +100,18 @@ - + Durée
{{ getElapsedTime(row.end,row.start) | number :'1.2-3'}}s
+ matTooltipClass="mat-tooltip">{{ getElapsedTime(row.end, row.start) | number :'1.2-3'}}s
Client - {{row.user || 'N/A'}} + {{row.instanceUser || 'N/A'}} diff --git a/src/app/views/session-api/session-api.component.ts b/src/app/views/session-api/session-api.component.ts index 66d1ccc..fadf2a7 100644 --- a/src/app/views/session-api/session-api.component.ts +++ b/src/app/views/session-api/session-api.component.ts @@ -14,7 +14,7 @@ import { EnvRouter } from '../session-detail/session-detail.component'; import { application, makePeriod } from 'src/environments/environment'; import { FilterConstants, FilterPreset, FilterMap } from '../constants'; import { FilterService } from 'src/app/shared/services/filter.service'; -import { T } from '@angular/cdk/keycodes'; +import { InstanceMainSession, InstanceRestSession, RestSession } from 'src/app/shared/model/v3/trace.model'; @Component({ @@ -24,8 +24,8 @@ import { T } from '@angular/cdk/keycodes'; export class SessionApiComponent implements OnInit, OnDestroy { filterConstants = FilterConstants; nameDataList: any[]; - displayedColumns: string[] = ['status', 'app_name', 'method/path', 'query', 'start', 'Durée', 'user']; - dataSource: MatTableDataSource = new MatTableDataSource(); + displayedColumns: string[] = ['status', 'app_name', 'method/path', 'query', 'start', 'durée', 'user']; + dataSource: MatTableDataSource = new MatTableDataSource(); isLoading = true; serverNameIsLoading = true; subscriptions: Subscription[] = []; @@ -41,7 +41,6 @@ export class SessionApiComponent implements OnInit, OnDestroy { params: Partial<{ env: string, start: Date, end: Date, serveurs: string[] }> = {}; advancedParams: Partial<{ [key: string]: any }> ={} - advancedParamsChip: Partial<{ [key: string]: any }> ={} focusFieldName: any; @ViewChild(MatPaginator) paginator: MatPaginator; @@ -66,7 +65,7 @@ export class SessionApiComponent implements OnInit, OnDestroy { } this.patchDateValue(this.params.start, new Date(this.params.end.getFullYear(), this.params.end.getMonth(), this.params.end.getDate() - 1)); - this.subscriptions.push(this._statsService.getSessionApi( { 'column.distinct': 'app_name', 'order': 'app_name.asc' }) + this.subscriptions.push(this._statsService.getInstance( { 'column.distinct': 'app_name', 'order': 'app_name.asc' }) .pipe(finalize(()=> this.serverNameIsLoading = false)) .subscribe({ next: (appNames: { appName: string }[]) => { @@ -121,8 +120,7 @@ export class SessionApiComponent implements OnInit, OnDestroy { 'env': this.params.env, 'appname': this.params.serveurs, 'start': this.params.start.toISOString(), - 'end': this.params.end.toISOString(), - 'lazy': false + 'end': this.params.end.toISOString() }; if(this.advancedParams){ Object.assign(params, this.advancedParams); @@ -132,7 +130,7 @@ export class SessionApiComponent implements OnInit, OnDestroy { this.dataSource = new MatTableDataSource([]); this.subscriptions.push(this._traceService.getIncomingRequestByCriteria(params) .subscribe({ - next: (d: IncomingRequest[]) => { + next: (d: InstanceRestSession[]) => { if (d) { this.dataSource = new MatTableDataSource(d); this.dataSource.paginator = this.paginator; @@ -143,20 +141,20 @@ export class SessionApiComponent implements OnInit, OnDestroy { if (columnName == "name/port") return row["host"] + ":" + row["port"] as string; if (columnName == "method/path") return row['path'] as string; if (columnName == "start") return row['start'] as string; - if (columnName == "Durée") return (row["end"] - row["start"]) + if (columnName == "durée") return (row["end"] - row["start"]) var columnValue = row[columnName as keyof any] as string; return columnValue; } - this.dataSource.filterPredicate = (data: IncomingRequest, filter: string) => { + this.dataSource.filterPredicate = (data: InstanceRestSession, filter: string) => { var map: Map = new Map(JSON.parse(filter)); let isMatch = true; for (let [key, value] of map.entries()) { if (key == 'filter') { - isMatch = isMatch && (value == '' || (data.application.name?.toLowerCase().includes(value) || + isMatch = isMatch && (value == '' || (data.appName?.toLowerCase().includes(value) || data.method?.toLowerCase().includes(value) || data.query?.toLowerCase().includes(value) || - data.user?.toLowerCase().includes(value) || data.path?.toLowerCase().includes(value))); + data.instanceUser?.toLowerCase().includes(value) || data.path?.toLowerCase().includes(value))); } else if (key == 'status') { const s = data.status.toString(); isMatch = isMatch && (!value.length || (value.some((status: any) => { diff --git a/src/app/views/session-main/session-main.component.html b/src/app/views/session-main/session-main.component.html index d9f402e..11f7111 100644 --- a/src/app/views/session-main/session-main.component.html +++ b/src/app/views/session-main/session-main.component.html @@ -44,7 +44,7 @@ Serveur - {{row.application.name || ''}} + {{row.appName || ''}} @@ -52,7 +52,7 @@ Session -
+
{{row.name || 'N/A'}}
@@ -63,7 +63,7 @@ Chemin -
+
{{row.location ||'N/A'}}
@@ -84,7 +84,7 @@ - + Durée
= new MatTableDataSource(); - mainRequestList: MainRequest[]; + displayedColumns: string[] = ['status', 'app_name', 'session', 'location', 'start', 'durée', 'user']; + dataSource: MatTableDataSource = new MatTableDataSource(); + mainRequestList: InstanceMainSession[]; serverFilterForm = new FormGroup({ launchmode: new FormControl(""), dateRangePicker: new FormGroup({ @@ -88,7 +89,7 @@ export class SessionMainComponent implements OnInit, OnDestroy { this.isLoading = true; this.dataSource.data = []; - this.subscription = this._traceService.getMainRequestByCriteria(params).subscribe((d: MainRequest[]) => { + this.subscription = this._traceService.getMainRequestByCriteria(params).subscribe((d: InstanceMainSession[]) => { if (d) { this.dataSource = new MatTableDataSource(d); this.dataSource.paginator = this.paginator; From fe68302e7e8b45794d1f82080d431a2f38dfc943 Mon Sep 17 00:00:00 2001 From: fufuu Date: Mon, 8 Jul 2024 14:04:12 +0200 Subject: [PATCH 024/126] nouvelle modelisation --- src/app/app.component.ts | 2 +- src/app/app.module.ts | 6 +- src/app/shared/model/v3/trace.model.ts | 52 +++++++++++--- src/app/shared/services/stats.service.ts | 8 +-- src/app/shared/services/trace.service.ts | 22 +++++- src/app/shared/util.ts | 3 +- .../session-api/session-api.component.ts | 4 +- .../request-database-table.component.html | 2 +- .../request-database-table.component.ts | 7 +- .../request-rest-table.component.html | 2 +- .../request-rest-table.component.ts | 9 +-- .../request-timeline.component.ts | 11 +-- .../session-detail.component.html | 38 +++++----- .../session-detail.component.ts | 69 ++++++++++++------- .../session-main/session-main.component.html | 14 +++- .../session-main/session-main.component.ts | 5 +- .../views/stats-api/stats-api.component.html | 8 +-- .../views/stats-api/stats-api.component.ts | 17 +++-- .../views/stats-app/stats-app.component.ts | 18 ++--- .../stats-database.component.ts | 16 ++--- .../views/stats-user/stats-user.component.ts | 10 +-- 21 files changed, 200 insertions(+), 123 deletions(-) diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 20cb90d..e965737 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -28,7 +28,7 @@ export class AppComponent implements OnInit { private _router: EnvRouter, private _service: StatsService) { this.isLoadingEnv = true; - this.subscriptions.push(this._service.getSessionApi({'column.distinct': 'environement', 'order': 'environement.asc'}) + this.subscriptions.push(this._service.getInstance({'column.distinct': 'environement', 'order': 'environement.asc'}) .pipe(finalize(() => this.isLoadingEnv = false)) .subscribe({ next: (res: {environement: string}[]) => { diff --git a/src/app/app.module.ts b/src/app/app.module.ts index a33cc96..cf4d273 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -30,12 +30,12 @@ const routes: Route[] = [ { path: 'session', children: [ { - path: 'api', + path: 'rest', component: SessionApiComponent, title: 'Liste des API' }, { - path: 'api/:id/tree', + path: 'rest/:id/tree', component: TreeComponent, title: 'Arbre d\'appels API' }, @@ -59,7 +59,7 @@ const routes: Route[] = [ return 'Detail de l\'API'; }, }, - { path: '**', pathMatch: 'full', redirectTo: `/session/api` } + { path: '**', pathMatch: 'full', redirectTo: `/session/rest` } ] }, { diff --git a/src/app/shared/model/v3/trace.model.ts b/src/app/shared/model/v3/trace.model.ts index 465d389..de9c10d 100644 --- a/src/app/shared/model/v3/trace.model.ts +++ b/src/app/shared/model/v3/trace.model.ts @@ -16,20 +16,22 @@ export interface RestSession extends RestRequest { name: string; requests: Array; queries: Array; - stages: Array; + stages: Array; ftpRequests: Array; mailRequests: Array; + ldapRequests: Array; userAgent: string; } -export interface MainSession extends RunnableStage { +export interface MainSession extends LocalRequest { id: string; type: string; requests: Array; queries: Array; - stages: Array; + stages: Array; ftpRequests: Array; mailRequests: Array; + ldapRequests: Array; } export interface RestRequest extends SessionStage { @@ -50,18 +52,19 @@ export interface RestRequest extends SessionStage { outContentEncoding: string; } -export interface DatabaseRequest { +export interface DatabaseRequest extends SessionStage { host: string; port: number; - database: string; + name: string; + schema: string; driverVersion: string; - databaseName: string; - databaseVersion: string; + productName: string; + productVersion: string; actions: Array; commands: Array; } -export interface FtpRequest { +export interface FtpRequest extends SessionStage { protocol: string; host: string; port: number; @@ -70,19 +73,26 @@ export interface FtpRequest { actions: Array; } -export interface MailRequest { +export interface MailRequest extends SessionStage { host: string; port: number; actions: Array; mails: Array; } -export interface RunnableStage extends SessionStage { +export interface LocalRequest extends SessionStage { name: string; location: string; exception: ExceptionInfo; } +export interface NamingRequest extends SessionStage { + protocol: string; + host: string; + port: number; + actions: Array; +} + export interface DatabaseRequestStage extends RequestStage { count: Array; } @@ -95,6 +105,10 @@ export interface MailRequestStage extends RequestStage { } +export interface NamingRequestStage extends RequestStage { + args: Array; +} + export interface Mail { subject: string; contentType: string; @@ -118,7 +132,25 @@ export interface SessionStage { threadName: string; } +export interface Session { + id: string; + +} + export interface ExceptionInfo { type: string; message: string; +} + +export interface InstanceEnvironment { + name: string; + version: string; + address: string; + env: string; + os: string; + re: string; + user: string; + type: string; + instant: Date; + collector: string; } \ No newline at end of file diff --git a/src/app/shared/services/stats.service.ts b/src/app/shared/services/stats.service.ts index 33c00c0..6b28cad 100644 --- a/src/app/shared/services/stats.service.ts +++ b/src/app/shared/services/stats.service.ts @@ -12,18 +12,18 @@ export class StatsService { return this.http.get(url, { params: params }); } - getSessionApi(params: any) { - let url = `${localStorage.getItem('server')}/stat/apisession`; + getSessionRest(params: any) { + let url = `${localStorage.getItem('server')}/jquery/session/rest`; return this.http.get(url, { params: params }); } getSessionMain(params: any) { - let url = `${localStorage.getItem('server')}/stat/mainsession`; + let url = `${localStorage.getItem('server')}/jquery/session/main`; return this.http.get(url, { params: params }); } getInstance(params: any) { - let url = `${localStorage.getItem('server')}/stat/instance`; + let url = `${localStorage.getItem('server')}/jquery/instance`; return this.http.get(url, { params: params }); } } \ No newline at end of file diff --git a/src/app/shared/services/trace.service.ts b/src/app/shared/services/trace.service.ts index ebc07fd..2ec5337 100644 --- a/src/app/shared/services/trace.service.ts +++ b/src/app/shared/services/trace.service.ts @@ -1,11 +1,11 @@ import { HttpClient, HttpErrorResponse } from "@angular/common/http"; import { Injectable } from "@angular/core"; import { Observable, catchError, throwError } from "rxjs"; -import { RestSession } from "../model/v3/trace.model"; +import { DatabaseRequest, InstanceEnvironment, InstanceRestSession, LocalRequest, RestRequest, RestSession } from "../model/v3/trace.model"; @Injectable({ providedIn: 'root' }) export class TraceService { - readonly INCOMING_REQUEST_URL = `${localStorage.getItem('server')}/v3/trace/session/api`; + readonly INCOMING_REQUEST_URL = `${localStorage.getItem('server')}/v3/trace/session/rest`; readonly MAIN_REQUEST_URL = `${localStorage.getItem('server')}/v3/trace/session/main`; constructor(private http: HttpClient) { @@ -36,7 +36,23 @@ export class TraceService { } getSessionParentByChildId(id: string){ - return this.http.get(`${localStorage.getItem('server')}/trace/session/api/${id}/parent`).pipe(catchError(this.handleError)) + return this.http.get(`${localStorage.getItem('server')}/trace/session/rest/${id}/parent`).pipe(catchError(this.handleError)) + } + + getRestRequests(id: string): Observable> { + return this.http.get>(`${localStorage.getItem('server')}/v3/trace/session/${id}/request/rest`); + } + + getDatabaseRequests(id: string): Observable> { + return this.http.get>(`${localStorage.getItem('server')}/v3/trace/session/${id}/request/database`); + } + + getLocalRequests(id: string): Observable> { + return this.http.get>(`${localStorage.getItem('server')}/v3/trace/session/${id}/request/local`); + } + + getInstance(id: string): Observable { + return this.http.get(`${localStorage.getItem('server')}/v3/trace/instance/${id}`); } private handleError( error: HttpErrorResponse){ diff --git a/src/app/shared/util.ts b/src/app/shared/util.ts index b67c2c9..94990b4 100644 --- a/src/app/shared/util.ts +++ b/src/app/shared/util.ts @@ -1,6 +1,7 @@ import { DatePipe } from "@angular/common"; import { ChartGroup } from "./model/chart.model"; import { Filter, FilterMap, Operation } from "../views/constants"; +import { InstanceRestSession } from "./model/v3/trace.model"; export class Utils { @@ -104,7 +105,7 @@ export class Utils { return result; } - static getSessionUrl(selectedSession: any) { + static getSessionUrl(selectedSession: InstanceRestSession) { return `${selectedSession?.protocol ? selectedSession?.protocol + '://' : ''}${selectedSession?.host ? selectedSession?.host : ''}${selectedSession?.port > 0 ? ':' + selectedSession?.port : ''}${selectedSession?.path ? selectedSession?.path : ''}${selectedSession?.query ? '?' + selectedSession?.query : ''}` } diff --git a/src/app/views/session-api/session-api.component.ts b/src/app/views/session-api/session-api.component.ts index fadf2a7..cde2f83 100644 --- a/src/app/views/session-api/session-api.component.ts +++ b/src/app/views/session-api/session-api.component.ts @@ -192,9 +192,9 @@ export class SessionApiComponent implements OnInit, OnDestroy { selectedRequest(event: MouseEvent, row: any) { if (event.ctrlKey) { - this._router.open(`#/session/api/${row}`, '_blank') + this._router.open(`#/session/rest/${row}`, '_blank') } else { - this._router.navigate(['/session/api', row], { + this._router.navigate(['/session/rest', row], { queryParams: { 'env': this.params.env } }); } diff --git a/src/app/views/session-detail/components/request-database-table/request-database-table.component.html b/src/app/views/session-detail/components/request-database-table/request-database-table.component.html index 337ffe1..8e0e8ad 100644 --- a/src/app/views/session-detail/components/request-database-table/request-database-table.component.html +++ b/src/app/views/session-detail/components/request-database-table/request-database-table.component.html @@ -2,7 +2,7 @@ - + + + + + + + diff --git a/src/app/views/session-main/session-main.component.ts b/src/app/views/session-main/session-main.component.ts index 2960460..96fe3ba 100644 --- a/src/app/views/session-main/session-main.component.ts +++ b/src/app/views/session-main/session-main.component.ts @@ -23,7 +23,7 @@ import { InstanceMainSession } from 'src/app/shared/model/v3/trace.model'; export class SessionMainComponent implements OnInit, OnDestroy { filterConstants = FilterConstants; utils: Utils = new Utils(); - displayedColumns: string[] = ['status', 'app_name', 'session', 'location', 'start', 'durée', 'user']; + displayedColumns: string[] = ['status', 'app_name', 'type', 'name', 'location', 'start', 'durée', 'user']; dataSource: MatTableDataSource = new MatTableDataSource(); mainRequestList: InstanceMainSession[]; serverFilterForm = new FormGroup({ @@ -96,7 +96,8 @@ export class SessionMainComponent implements OnInit, OnDestroy { this.dataSource.sort = this.sort this.dataSource.sortingDataAccessor = (row: any, columnName: string) => { if (columnName == "app_name") return row["application"]["name"] as string; - if (columnName == "session") return row["name"] as string; + if (columnName == "type") return row["type"] as string; + if (columnName == "name") return row["name"] as string; if (columnName == "location") return row['location'] as string; if (columnName == "start") return row['start'] as string; if (columnName == "Durée") return (row["end"] - row["start"]) diff --git a/src/app/views/stats-api/stats-api.component.html b/src/app/views/stats-api/stats-api.component.html index adaabe1..90652c8 100644 --- a/src/app/views/stats-api/stats-api.component.html +++ b/src/app/views/stats-api/stats-api.component.html @@ -1,4 +1,4 @@ - + @@ -17,9 +17,9 @@ - - {{requests.infos?.data[0]?.appName}} - +
{ + observable: this._statsService.getSessionRest({ 'column': `count_succes:countSucces,count_error_client:countErrorClient,count_error_server:countErrorServer,count_slowest:elapsedTimeSlowest,count_slow:elapsedTimeSlow,count_medium:elapsedTimeMedium,count_fast:elapsedTimeFast,count_fastest:elapsedTimeFastest,elapsedtime.avg:avg,elapsedtime.max:max,rest_session.start.${groupedBy}:date,rest_session.start.year:year`, 'rest_session.instance_env': 'instance.id', 'api_name': name, 'rest_session.start.ge': start.toISOString(), 'rest_session.start.lt': end.toISOString(), 'instance.environement': env, 'order': `rest_session.start.year.asc,rest_session.start.${groupedBy}.asc`, ...advancedParams }).pipe(map((r: any[]) => { formatters[groupedBy](r, this._datePipe); return r; })) }, - repartitionRequestByPeriodLine: { observable: this._statsService.getSessionApi({ 'column': `count:count,count_error_server:countErrorServer,count_slowest:countSlowest,start.date:date`, 'api_name': name, 'start.ge': new Date(now.getFullYear(), now.getMonth(), now.getDate() - 6).toISOString(), 'start.lt': now.toISOString(), 'environement': env, 'order': 'start.date.asc', ...advancedParams }) }, // 7 derniers jours - repartitionUserPolar: { observable: this._statsService.getSessionApi({ 'column': "count:count,user:user", 'api_name': name, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'environement': env, 'user.not': 'null', 'order': 'count.desc', ...advancedParams }).pipe(map((r: any[]) => r.slice(0, 5))) }, + repartitionRequestByPeriodLine: { observable: this._statsService.getSessionRest({ 'column': `count:count,count_error_server:countErrorServer,count_slowest:countSlowest,rest_session.start.date:date`, 'rest_session.instance_env': 'instance.id', 'api_name': name, 'rest_session.start.ge': new Date(now.getFullYear(), now.getMonth(), now.getDate() - 6).toISOString(), 'rest_session.start.lt': now.toISOString(), 'instance.environement': env, 'order': 'rest_session.start.date.asc', ...advancedParams }) }, // 7 derniers jours + repartitionUserPolar: { observable: this._statsService.getSessionRest({ 'column': "count:count,instance.user:user", 'rest_session.instance_env': 'instance.id', 'api_name': name, 'rest_session.start.ge': start.toISOString(), 'rest_session.start.lt': end.toISOString(), 'instance.environement': env, 'instance.user.not': 'null', 'order': 'count.desc', ...advancedParams }).pipe(map((r: any[]) => r.slice(0, 5))) }, repartitionUserBar: { - observable: this._statsService.getSessionApi({ 'column': `count:count,start.${groupedBy}:date,start.year:year,user:user`, 'api_name': name, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'environement': env, 'user.not': 'null', 'order': `start.year.asc,start.${groupedBy}.asc`, ...advancedParams }).pipe(map((r: any[]) => { + observable: this._statsService.getSessionRest({ 'column': `count:count,rest_session.start.${groupedBy}:date,rest_session.start.year:year,instance.user:user`, 'rest_session.instance_env': 'instance.id', 'api_name': name, 'rest_session.start.ge': start.toISOString(), 'rest_session.start.lt': end.toISOString(), 'instance.environement': env, 'instance.user.not': 'null', 'order': `rest_session.start.year.asc,rest_session.start.${groupedBy}.asc`, ...advancedParams }).pipe(map((r: any[]) => { let groupBy = groupingBy(r, 'user'); let results: { count: number, user: string, date: any, year: any }[] = Object.entries(groupBy).map((value: [string, any[]]) => { return { @@ -163,9 +162,9 @@ export class StatsApiComponent implements OnInit, OnDestroy { return r; })) }, - dependentsTable: { observable: this._statsService.getSessionApi({ 'column': "count:count,count_succes:countSucces,count_error_client:countErrClient,count_error_server:countErrServer,apisession2.api_name:name", "apisession.id": "apirequest.parent", "apirequest.id": "apisession2.id", 'apisession.api_name': name, 'apisession.start.ge': start.toISOString(), 'apisession.start.lt': end.toISOString(), 'apisession2.start.ge': start.toISOString(), 'apisession2.start.lt': end.toISOString(), 'environement': env, 'apisession2.api_name.not': 'null', 'order': 'count.desc', ...advancedParams }) }, - dependenciesTable: { observable: this._statsService.getSessionApi({ 'column': "count:count,count_succes:countSucces,count_error_client:countErrClient,count_error_server:countErrServer,apisession.api_name:name", "apisession.id": "apirequest.parent", "apirequest.id": "apisession2.id", 'apisession2.api_name': name, 'apisession2.start.ge': start.toISOString(), 'apisession2.start.lt': end.toISOString(), 'apisession.start.ge': start.toISOString(), 'apisession.start.lt': end.toISOString(), 'environement': env, 'apisession.api_name.not': 'null', 'order': 'count.desc', ...advancedParams }) }, - exceptionsTable: { observable: this._statsService.getSessionApi({ 'column': 'count,err_type,err_msg', 'err.group': '', "status.ge": 500, "environement": env, "api_name": name, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'order': 'count.desc', ...advancedParams })} + dependentsTable: { observable: this._statsService.getSessionRest({ 'column': "count:count,count_succes:countSucces,count_error_client:countErrClient,count_error_server:countErrServer,rest_session2.api_name:name", 'rest_session.instance_env': 'instance.id', "rest_session.id": "rest_request.parent", "rest_request.remote": "rest_session2.id", 'rest_session.api_name': name, 'rest_session.start.ge': start.toISOString(), 'rest_session.start.lt': end.toISOString(), 'rest_session2.start.ge': start.toISOString(), 'rest_session2.start.lt': end.toISOString(), 'instance.environement': env, 'rest_session2.api_name.not': 'null', 'order': 'count.desc', ...advancedParams }) }, + dependenciesTable: { observable: this._statsService.getSessionRest({ 'column': "count:count,count_succes:countSucces,count_error_client:countErrClient,count_error_server:countErrServer,rest_session.api_name:name", 'rest_session.instance_env': 'instance.id', "rest_session.id": "rest_request.parent", "rest_request.remote": "rest_session2.id", 'rest_session2.api_name': name, 'rest_session2.start.ge': start.toISOString(), 'rest_session2.start.lt': end.toISOString(), 'rest_session.start.ge': start.toISOString(), 'rest_session.start.lt': end.toISOString(), 'instance.environement': env, 'rest_session.api_name.not': 'null', 'order': 'count.desc', ...advancedParams }) }, + exceptionsTable: { observable: this._statsService.getSessionRest({ 'column': 'count,err_type,err_msg', 'rest_session.instance_env': 'instance.id', 'err.group': '', "status.ge": 500, "instance.environement": env, "api_name": name, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'order': 'count.desc', ...advancedParams })} }; } diff --git a/src/app/views/stats-app/stats-app.component.ts b/src/app/views/stats-app/stats-app.component.ts index 0df3975..b84f872 100644 --- a/src/app/views/stats-app/stats-app.component.ts +++ b/src/app/views/stats-app/stats-app.component.ts @@ -130,17 +130,17 @@ export class StatsAppComponent implements OnInit, OnDestroy { let now = new Date(); var groupedBy = periodManagement(start, end); return { - repartitionTimeAndTypeResponse: { observable: this._statsService.getSessionApi({ "column": "count_slowest:elapsedTimeSlowest,count_slow:elapsedTimeSlow,count_medium:elapsedTimeMedium,count_fast:elapsedTimeFast,count_fastest:elapsedTimeFastest,count_succes:countSucces,count_error_server:countErrorServer,count_error_client:countErrorClient", 'app_name': name, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'environement': env, ...advancedParams }) }, + repartitionTimeAndTypeResponse: { observable: this._statsService.getSessionRest({ "column": "count_slowest:elapsedTimeSlowest,count_slow:elapsedTimeSlow,count_medium:elapsedTimeMedium,count_fast:elapsedTimeFast,count_fastest:elapsedTimeFastest,count_succes:countSucces,count_error_server:countErrorServer,count_error_client:countErrorClient", 'app_name': name, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'environement': env, ...advancedParams }) }, repartitionTimeAndTypeResponseByPeriod: { - observable: this._statsService.getSessionApi({ 'column': `count_succes:countSucces,count_error_client:countErrorClient,count_error_server:countErrorServer,count_slowest:elapsedTimeSlowest,count_slow:elapsedTimeSlow,count_medium:elapsedTimeMedium,count_fast:elapsedTimeFast,count_fastest:elapsedTimeFastest,elapsedtime.avg:avg,elapsedtime.max:max,start.${groupedBy}:date,start.year:year`, 'app_name': name, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'environement': env, 'order': `start.year.asc,start.${groupedBy}.asc`, ...advancedParams }).pipe(map(((r: any[]) => { + observable: this._statsService.getSessionRest({ 'column': `count_succes:countSucces,count_error_client:countErrorClient,count_error_server:countErrorServer,count_slowest:elapsedTimeSlowest,count_slow:elapsedTimeSlow,count_medium:elapsedTimeMedium,count_fast:elapsedTimeFast,count_fastest:elapsedTimeFastest,elapsedtime.avg:avg,elapsedtime.max:max,start.${groupedBy}:date,start.year:year`, 'app_name': name, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'environement': env, 'order': `start.year.asc,start.${groupedBy}.asc`, ...advancedParams }).pipe(map(((r: any[]) => { formatters[groupedBy](r, this._datePipe); return r; }))) }, - repartitionRequestByPeriodLine: { observable: this._statsService.getSessionApi({ 'column': "count:count,count_error_server:countErrorServer,count_slowest:countSlowest,start.date:date", 'app_name': name, 'start.ge': new Date(now.getFullYear(), now.getMonth(), now.getDate() - 6).toISOString(), 'start.lt': now.toISOString(), 'environement': env, 'order': 'start.date.asc', ...advancedParams }) }, - repartitionUserPolar: { observable: this._statsService.getSessionApi({ 'column': "count:count,user:user", 'app_name': name, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'environement': env, 'user.not': 'null', 'order': 'count.desc', ...advancedParams }).pipe(map((r: any[]) => r.slice(0, 5))) }, + repartitionRequestByPeriodLine: { observable: this._statsService.getSessionRest({ 'column': "count:count,count_error_server:countErrorServer,count_slowest:countSlowest,start.date:date", 'app_name': name, 'start.ge': new Date(now.getFullYear(), now.getMonth(), now.getDate() - 6).toISOString(), 'start.lt': now.toISOString(), 'environement': env, 'order': 'start.date.asc', ...advancedParams }) }, + repartitionUserPolar: { observable: this._statsService.getSessionRest({ 'column': "count:count,user:user", 'app_name': name, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'environement': env, 'user.not': 'null', 'order': 'count.desc', ...advancedParams }).pipe(map((r: any[]) => r.slice(0, 5))) }, repartitionUserBar: { - observable: this._statsService.getSessionApi({ 'column': `count:count,start.${groupedBy}:date,start.year:year,user:user`, 'app_name': name, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'environement': env, 'user.not': 'null', 'order': `start.year.asc,start.${groupedBy}.asc`, ...advancedParams }).pipe(map((r: any[]) => { + observable: this._statsService.getSessionRest({ 'column': `count:count,start.${groupedBy}:date,start.year:year,user:user`, 'app_name': name, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'environement': env, 'user.not': 'null', 'order': `start.year.asc,start.${groupedBy}.asc`, ...advancedParams }).pipe(map((r: any[]) => { let groupBy = groupingBy(r, 'user'); let results: { count: number, user: string, date: any, year: any }[] = Object.entries(groupBy).map((value: [string, any[]]) => { return { @@ -160,10 +160,10 @@ export class StatsAppComponent implements OnInit, OnDestroy { return r; })) }, - repartitionApiBar: { observable: this._statsService.getSessionApi({ 'column': "count_succes:countSucces,count_error_client:countErrorClient,count_error_server:countErrorServer,api_name", 'app_name': name, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'environement': env, 'api_name.not': 'null', 'order': 'count.desc', ...advancedParams }).pipe(map((d: any) => d.slice(0, 5))) }, - dependentsTable: { observable: this._statsService.getSessionApi({ 'column': "count:count,count_succes:countSucces,count_error_client:countErrClient,count_error_server:countErrServer,apisession2.app_name:name", "apisession.id": "apirequest.parent", "apirequest.id": "apisession2.id", 'apisession.app_name': name, 'apisession.start.ge': start.toISOString(), 'apisession.start.lt': end.toISOString(), 'apisession2.start.ge': start.toISOString(), 'apisession2.start.lt': end.toISOString(), 'environement': env, 'apisession2.app_name.not': 'null', 'order': 'count.desc', ...advancedParams }) }, - dependenciesTable: { observable: this._statsService.getSessionApi({ 'column': "count:count,count_succes:countSucces,count_error_client:countErrClient,count_error_server:countErrServer,apisession.app_name:name", "apisession.id": "apirequest.parent", "apirequest.id": "apisession2.id", 'apisession2.app_name': name, 'apisession2.start.ge': start.toISOString(), 'apisession2.start.lt': end.toISOString(), 'apisession.start.ge': start.toISOString(), 'apisession.start.lt': end.toISOString(), 'environement': env, 'apisession.app_name.not': 'null', 'order': 'count.desc', ...advancedParams }) }, - exceptionsTable: { observable: this._statsService.getSessionApi({ 'column': 'count,err_type,err_msg', 'err.group': '', "status.ge": 500, "environement": env, "app_name": name, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'order': 'count.desc', ...advancedParams })} + repartitionApiBar: { observable: this._statsService.getSessionRest({ 'column': "count_succes:countSucces,count_error_client:countErrorClient,count_error_server:countErrorServer,api_name", 'app_name': name, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'environement': env, 'api_name.not': 'null', 'order': 'count.desc', ...advancedParams }).pipe(map((d: any) => d.slice(0, 5))) }, + dependentsTable: { observable: this._statsService.getSessionRest({ 'column': "count:count,count_succes:countSucces,count_error_client:countErrClient,count_error_server:countErrServer,apisession2.app_name:name", "apisession.id": "apirequest.parent", "apirequest.id": "apisession2.id", 'apisession.app_name': name, 'apisession.start.ge': start.toISOString(), 'apisession.start.lt': end.toISOString(), 'apisession2.start.ge': start.toISOString(), 'apisession2.start.lt': end.toISOString(), 'environement': env, 'apisession2.app_name.not': 'null', 'order': 'count.desc', ...advancedParams }) }, + dependenciesTable: { observable: this._statsService.getSessionRest({ 'column': "count:count,count_succes:countSucces,count_error_client:countErrClient,count_error_server:countErrServer,apisession.app_name:name", "apisession.id": "apirequest.parent", "apirequest.id": "apisession2.id", 'apisession2.app_name': name, 'apisession2.start.ge': start.toISOString(), 'apisession2.start.lt': end.toISOString(), 'apisession.start.ge': start.toISOString(), 'apisession.start.lt': end.toISOString(), 'environement': env, 'apisession.app_name.not': 'null', 'order': 'count.desc', ...advancedParams }) }, + exceptionsTable: { observable: this._statsService.getSessionRest({ 'column': 'count,err_type,err_msg', 'err.group': '', "status.ge": 500, "environement": env, "app_name": name, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'order': 'count.desc', ...advancedParams })} }; }; diff --git a/src/app/views/stats-database/stats-database.component.ts b/src/app/views/stats-database/stats-database.component.ts index ab77034..d513582 100644 --- a/src/app/views/stats-database/stats-database.component.ts +++ b/src/app/views/stats-database/stats-database.component.ts @@ -79,7 +79,7 @@ export class StatsDatabaseComponent implements OnInit { this.dbNameListIsLoading = true; this.serverFilterForm.controls.dbnameControl.reset(); this.serverFilterForm.controls.dbnameControl.disable(); - this._statsService.getSessionApi({ 'column.distinct': 'dbquery.db&dbquery.parent=apisession.id&order=dbquery.db.asc', 'apisession.environement': this.env }).pipe(catchError(error => of(error))) + this._statsService.getSessionRest({ 'column.distinct': 'dbquery.db&dbquery.parent=apisession.id&order=dbquery.db.asc', 'apisession.environement': this.env }).pipe(catchError(error => of(error))) .subscribe({ next: (res: { db: string }[]) => { this.dbNameDataList = res.map((s: any) => s.db) @@ -135,22 +135,22 @@ export class StatsDatabaseComponent implements OnInit { let now = new Date(); var groupedBy = periodManagement(start, end); return { - dbInfo: { observable: this._statsService.getSessionApi({ 'column.distinct': 'dbquery.host,dbquery.db,dbquery.driver,dbquery.db_name,dbquery.db_version', 'dbquery.parent': 'apisession.id', "apisession.environement": env, "dbquery.db": db, 'dbquery.start.ge': start.toISOString(), 'dbquery.start.lt': end.toISOString(), 'apisession.start.ge': start.toISOString(), 'apisession.start.lt': end.toISOString() }) }, - countOkKoSlowest: { observable: this._statsService.getSessionApi({ 'column': 'dbquery.count_db_error:countErrorServer,dbquery.count:count,dbquery.count_slowest:countSlowest,dbquery.start.date:date', 'dbquery.parent': 'apisession.id', "apisession.environement": env, "dbquery.db": db, 'apisession.start.ge': new Date(now.getFullYear(), now.getMonth(), now.getDate() - 6).toISOString(), 'apisession.start.lt': now.toISOString(), 'dbquery.start.ge': new Date(now.getFullYear(), now.getMonth(), now.getDate() - 7).toISOString(), 'dbquery.start.lt': now.toISOString()}) }, - countMinMaxAvg: { observable: this._statsService.getSessionApi({ 'column': `dbquery.count_db_succes:countDbSucces,dbquery.elapsedtime.max:max,dbquery.elapsedtime.avg:avg,dbquery.start.${groupedBy}:date,dbquery.start.year:year`, 'dbquery.parent': 'apisession.id', "apisession.environement": env, "dbquery.db": db, 'apisession.start.ge': start.toISOString(), 'apisession.start.lt': end.toISOString(), 'dbquery.start.ge': start.toISOString(), 'dbquery.start.lt': end.toISOString(), 'order': `dbquery.start.year.asc,dbquery.start.${groupedBy}.asc` }).pipe(map(((r: any[]) => { + dbInfo: { observable: this._statsService.getSessionRest({ 'column.distinct': 'dbquery.host,dbquery.db,dbquery.driver,dbquery.db_name,dbquery.db_version', 'dbquery.parent': 'apisession.id', "apisession.environement": env, "dbquery.db": db, 'dbquery.start.ge': start.toISOString(), 'dbquery.start.lt': end.toISOString(), 'apisession.start.ge': start.toISOString(), 'apisession.start.lt': end.toISOString() }) }, + countOkKoSlowest: { observable: this._statsService.getSessionRest({ 'column': 'dbquery.count_db_error:countErrorServer,dbquery.count:count,dbquery.count_slowest:countSlowest,dbquery.start.date:date', 'dbquery.parent': 'apisession.id', "apisession.environement": env, "dbquery.db": db, 'apisession.start.ge': new Date(now.getFullYear(), now.getMonth(), now.getDate() - 6).toISOString(), 'apisession.start.lt': now.toISOString(), 'dbquery.start.ge': new Date(now.getFullYear(), now.getMonth(), now.getDate() - 7).toISOString(), 'dbquery.start.lt': now.toISOString()}) }, + countMinMaxAvg: { observable: this._statsService.getSessionRest({ 'column': `dbquery.count_db_succes:countDbSucces,dbquery.elapsedtime.max:max,dbquery.elapsedtime.avg:avg,dbquery.start.${groupedBy}:date,dbquery.start.year:year`, 'dbquery.parent': 'apisession.id', "apisession.environement": env, "dbquery.db": db, 'apisession.start.ge': start.toISOString(), 'apisession.start.lt': end.toISOString(), 'dbquery.start.ge': start.toISOString(), 'dbquery.start.lt': end.toISOString(), 'order': `dbquery.start.year.asc,dbquery.start.${groupedBy}.asc` }).pipe(map(((r: any[]) => { formatters[groupedBy](r, this._datePipe); return r; }))) }, countRepartitionBySpeedBar: { - observable: this._statsService.getSessionApi({ 'column': `dbquery.count_slowest:elapsedTimeSlowest,dbquery.count_slow:elapsedTimeSlow,dbquery.count_medium:elapsedTimeMedium,dbquery.count_fast:elapsedTimeFast,dbquery.count_fastest:elapsedTimeFastest,dbquery.start.${groupedBy}:date,dbquery.start.year:year`, 'dbquery.parent': 'apisession.id', "apisession.environement": env, "dbquery.db": db, 'apisession.start.ge': start.toISOString(), 'apisession.start.lt': end.toISOString(), 'dbquery.start.ge': start.toISOString(), 'dbquery.start.lt': end.toISOString(), 'order': `dbquery.start.year.asc,dbquery.start.${groupedBy}.asc` }).pipe(map(((r: any[]) => { + observable: this._statsService.getSessionRest({ 'column': `dbquery.count_slowest:elapsedTimeSlowest,dbquery.count_slow:elapsedTimeSlow,dbquery.count_medium:elapsedTimeMedium,dbquery.count_fast:elapsedTimeFast,dbquery.count_fastest:elapsedTimeFastest,dbquery.start.${groupedBy}:date,dbquery.start.year:year`, 'dbquery.parent': 'apisession.id', "apisession.environement": env, "dbquery.db": db, 'apisession.start.ge': start.toISOString(), 'apisession.start.lt': end.toISOString(), 'dbquery.start.ge': start.toISOString(), 'dbquery.start.lt': end.toISOString(), 'order': `dbquery.start.year.asc,dbquery.start.${groupedBy}.asc` }).pipe(map(((r: any[]) => { formatters[groupedBy](r, this._datePipe); return r; }))) }, - countRepartitionBySpeedPie: { observable: this._statsService.getSessionApi({ 'column': 'dbquery.count_slowest:elapsedTimeSlowest,dbquery.count_slow:elapsedTimeSlow,dbquery.count_medium:elapsedTimeMedium,dbquery.count_fast:elapsedTimeFast,dbquery.count_fastest:elapsedTimeFastest', 'dbquery.parent': 'apisession.id', "apisession.environement": env, "dbquery.db": db, 'apisession.start.ge': start.toISOString(), 'apisession.start.lt': end.toISOString(), 'dbquery.start.ge': start.toISOString(), 'dbquery.start.lt': end.toISOString()}) }, - exceptions: { observable: this._statsService.getSessionApi({ 'column': 'count,dbaction.err_type,dbaction.err_msg', 'dbaction.err.group': '', 'dbaction.parent': 'dbquery.id', 'dbquery.parent': 'apisession.id', 'order': 'count.desc', "apisession.environement": env, "dbquery.db": db, 'apisession.start.ge': start.toISOString(), 'apisession.start.lt': end.toISOString(), 'dbquery.start.ge': start.toISOString(), 'dbquery.start.lt': end.toISOString() })}, - usersInfo: { observable: this._statsService.getSessionApi({ 'column': 'count:countRows,dbquery.user', 'dbquery.parent': 'apisession.id', "apisession.environement": env, "dbquery.db": db, 'apisession.start.ge': start.toISOString(), 'apisession.start.lt': end.toISOString(), 'dbquery.start.ge': start.toISOString(), 'dbquery.start.lt': end.toISOString() }) } + countRepartitionBySpeedPie: { observable: this._statsService.getSessionRest({ 'column': 'dbquery.count_slowest:elapsedTimeSlowest,dbquery.count_slow:elapsedTimeSlow,dbquery.count_medium:elapsedTimeMedium,dbquery.count_fast:elapsedTimeFast,dbquery.count_fastest:elapsedTimeFastest', 'dbquery.parent': 'apisession.id', "apisession.environement": env, "dbquery.db": db, 'apisession.start.ge': start.toISOString(), 'apisession.start.lt': end.toISOString(), 'dbquery.start.ge': start.toISOString(), 'dbquery.start.lt': end.toISOString()}) }, + exceptions: { observable: this._statsService.getSessionRest({ 'column': 'count,dbaction.err_type,dbaction.err_msg', 'dbaction.err.group': '', 'dbaction.parent': 'dbquery.id', 'dbquery.parent': 'apisession.id', 'order': 'count.desc', "apisession.environement": env, "dbquery.db": db, 'apisession.start.ge': start.toISOString(), 'apisession.start.lt': end.toISOString(), 'dbquery.start.ge': start.toISOString(), 'dbquery.start.lt': end.toISOString() })}, + usersInfo: { observable: this._statsService.getSessionRest({ 'column': 'count:countRows,dbquery.user', 'dbquery.parent': 'apisession.id', "apisession.environement": env, "dbquery.db": db, 'apisession.start.ge': start.toISOString(), 'apisession.start.lt': end.toISOString(), 'dbquery.start.ge': start.toISOString(), 'dbquery.start.lt': end.toISOString() }) } } } diff --git a/src/app/views/stats-user/stats-user.component.ts b/src/app/views/stats-user/stats-user.component.ts index 8d58e95..f8468d0 100644 --- a/src/app/views/stats-user/stats-user.component.ts +++ b/src/app/views/stats-user/stats-user.component.ts @@ -120,16 +120,16 @@ export class StatsUserComponent implements OnInit, OnDestroy { let now = new Date(); var groupedBy = periodManagement(start, end); return { - repartitionTimeAndTypeResponse: { observable: this._statsService.getSessionApi({ 'column': "count_slowest:elapsedTimeSlowest,count_slow:elapsedTimeSlow,count_medium:elapsedTimeMedium,count_fast:elapsedTimeFast,count_fastest:elapsedTimeFastest,count_succes:countSucces,count_error_server:countErrorServer,count_error_client:countErrorClient", 'user': name, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'environement': env, ...advancedParams }) }, + repartitionTimeAndTypeResponse: { observable: this._statsService.getSessionRest({ 'column': "count_slowest:elapsedTimeSlowest,count_slow:elapsedTimeSlow,count_medium:elapsedTimeMedium,count_fast:elapsedTimeFast,count_fastest:elapsedTimeFastest,count_succes:countSucces,count_error_server:countErrorServer,count_error_client:countErrorClient", 'user': name, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'environement': env, ...advancedParams }) }, repartitionTimeAndTypeResponseByPeriod: { - observable: this._statsService.getSessionApi({ 'column': `count_succes:countSucces,count_error_client:countErrorClient,count_error_server:countErrorServer,count_slowest:elapsedTimeSlowest,count_slow:elapsedTimeSlow,count_medium:elapsedTimeMedium,count_fast:elapsedTimeFast,count_fastest:elapsedTimeFastest,elapsedtime.avg:avg,elapsedtime.max:max,start.${groupedBy}:date,start.year:year`, 'user': name, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'environement': env, 'order': `start.year.asc,start.${groupedBy}.asc`, ...advancedParams }).pipe(map(((r: any[]) => { + observable: this._statsService.getSessionRest({ 'column': `count_succes:countSucces,count_error_client:countErrorClient,count_error_server:countErrorServer,count_slowest:elapsedTimeSlowest,count_slow:elapsedTimeSlow,count_medium:elapsedTimeMedium,count_fast:elapsedTimeFast,count_fastest:elapsedTimeFastest,elapsedtime.avg:avg,elapsedtime.max:max,start.${groupedBy}:date,start.year:year`, 'user': name, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'environement': env, 'order': `start.year.asc,start.${groupedBy}.asc`, ...advancedParams }).pipe(map(((r: any[]) => { formatters[groupedBy](r, this._datePipe); return r; }))) }, - repartitionRequestByPeriodLine: { observable: this._statsService.getSessionApi({ 'column': "count:count,count_error_server:countErrorServer,count_slowest:countSlowest,start.date:date", 'user': name, 'start.ge': new Date(now.getFullYear(), now.getMonth(), now.getDate() - 6).toISOString(), 'start.lt': now.toISOString(), 'environement': env, 'order': 'start.date.asc', ...advancedParams }) }, - repartitionApiBar: { observable: this._statsService.getSessionApi({ 'column': "count_succes:countSucces,count_error_client:countErrorClient,count_error_server:countErrorServer,api_name", 'user': name, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'environement': env, 'api_name.not': 'null', 'order': 'count.desc', ...advancedParams }).pipe(map((d: any) => d.slice(0, 5))) }, - exceptionsTable: { observable: this._statsService.getSessionApi({ 'column': 'count,err_type,err_msg', 'err.group': '', "status.ge": 500, "environement": env, 'user': name, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'order': 'count.desc', ...advancedParams })}, + repartitionRequestByPeriodLine: { observable: this._statsService.getSessionRest({ 'column': "count:count,count_error_server:countErrorServer,count_slowest:countSlowest,start.date:date", 'user': name, 'start.ge': new Date(now.getFullYear(), now.getMonth(), now.getDate() - 6).toISOString(), 'start.lt': now.toISOString(), 'environement': env, 'order': 'start.date.asc', ...advancedParams }) }, + repartitionApiBar: { observable: this._statsService.getSessionRest({ 'column': "count_succes:countSucces,count_error_client:countErrorClient,count_error_server:countErrorServer,api_name", 'user': name, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'environement': env, 'api_name.not': 'null', 'order': 'count.desc', ...advancedParams }).pipe(map((d: any) => d.slice(0, 5))) }, + exceptionsTable: { observable: this._statsService.getSessionRest({ 'column': 'count,err_type,err_msg', 'err.group': '', "status.ge": 500, "environement": env, 'user': name, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'order': 'count.desc', ...advancedParams })}, sessionTable: { observable: this._statsService.getSessionMain({ 'column': "name,start:date,elapsedtime,location,app_name", 'user': name, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'environement': env, 'order': 'start.date.desc' }) } }; } From a5dcdcb504ac1fe802e1d6ceeeb42a3074fd9a40 Mon Sep 17 00:00:00 2001 From: fufuu Date: Wed, 10 Jul 2024 10:01:07 +0200 Subject: [PATCH 025/126] remise a niveau --- src/app/app.module.ts | 8 ++++---- src/app/shared/services/stats.service.ts | 14 ++++++++++++-- src/app/shared/services/trace.service.ts | 6 +++++- .../views/session-api/session-api.component.ts | 4 ++-- .../session-detail.component.html | 4 ++-- .../session-detail/session-detail.component.ts | 8 ++++---- src/app/views/stats-api/stats-api.component.ts | 16 ++++++++-------- src/app/views/stats-app/stats-app.component.ts | 18 +++++++++--------- .../stats-database.component.html | 4 ++-- .../stats-database/stats-database.component.ts | 16 ++++++++-------- .../views/stats-user/stats-user.component.html | 4 ++-- .../views/stats-user/stats-user.component.ts | 12 ++++++------ 12 files changed, 64 insertions(+), 50 deletions(-) diff --git a/src/app/app.module.ts b/src/app/app.module.ts index cf4d273..0862832 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -30,14 +30,14 @@ const routes: Route[] = [ { path: 'session', children: [ { - path: 'rest', + path: 'api', component: SessionApiComponent, title: 'Liste des API' }, { - path: 'rest/:id/tree', + path: ':type/:id/tree', component: TreeComponent, - title: 'Arbre d\'appels API' + title: 'Arbre d\'appels de la Session' }, { path: 'main', @@ -59,7 +59,7 @@ const routes: Route[] = [ return 'Detail de l\'API'; }, }, - { path: '**', pathMatch: 'full', redirectTo: `/session/rest` } + { path: '**', pathMatch: 'full', redirectTo: `/session/api` } ] }, { diff --git a/src/app/shared/services/stats.service.ts b/src/app/shared/services/stats.service.ts index 6b28cad..a95a239 100644 --- a/src/app/shared/services/stats.service.ts +++ b/src/app/shared/services/stats.service.ts @@ -12,16 +12,26 @@ export class StatsService { return this.http.get(url, { params: params }); } - getSessionRest(params: any) { + getRestSession(params: any) { let url = `${localStorage.getItem('server')}/jquery/session/rest`; return this.http.get(url, { params: params }); } - getSessionMain(params: any) { + getMainSession(params: any) { let url = `${localStorage.getItem('server')}/jquery/session/main`; return this.http.get(url, { params: params }); } + getDatabaseRequest(params: any) { + let url = `${localStorage.getItem('server')}/jquery/request/database`; + return this.http.get(url, { params: params }); + } + + getException(params: any) { + let url = `${localStorage.getItem('server')}/jquery/exception`; + return this.http.get(url, { params: params }); + } + getInstance(params: any) { let url = `${localStorage.getItem('server')}/jquery/instance`; return this.http.get(url, { params: params }); diff --git a/src/app/shared/services/trace.service.ts b/src/app/shared/services/trace.service.ts index 2ec5337..8c02e1e 100644 --- a/src/app/shared/services/trace.service.ts +++ b/src/app/shared/services/trace.service.ts @@ -28,9 +28,13 @@ export class TraceService { } getTreeRequestById(id: string) { - return this.http.get(`${localStorage.getItem('server')}/trace/session/${id}/tree`); + return this.http.get(`${this.INCOMING_REQUEST_URL}/${id}/tree`); } + getTreeMainById(id: string) { + return this.http.get(`${this.MAIN_REQUEST_URL}/${id}/tree`); + } + getDbRequestById(id: number){ return this.http.get(`${localStorage.getItem('server')}/trace/session/db/${id}`); } diff --git a/src/app/views/session-api/session-api.component.ts b/src/app/views/session-api/session-api.component.ts index cde2f83..fadf2a7 100644 --- a/src/app/views/session-api/session-api.component.ts +++ b/src/app/views/session-api/session-api.component.ts @@ -192,9 +192,9 @@ export class SessionApiComponent implements OnInit, OnDestroy { selectedRequest(event: MouseEvent, row: any) { if (event.ctrlKey) { - this._router.open(`#/session/rest/${row}`, '_blank') + this._router.open(`#/session/api/${row}`, '_blank') } else { - this._router.navigate(['/session/rest', row], { + this._router.navigate(['/session/api', row], { queryParams: { 'env': this.params.env } }); } diff --git a/src/app/views/session-detail/session-detail.component.html b/src/app/views/session-detail/session-detail.component.html index 0d93262..2a4b25a 100644 --- a/src/app/views/session-detail/session-detail.component.html +++ b/src/app/views/session-detail/session-detail.component.html @@ -9,7 +9,7 @@ [style.pointer-events]="selectedSession?.type =='VIEW' ? 'none' : 'all'" matTooltip="Statistique API"> settings_suggest - {{selectedSessionType =='rest' ? (selectedSession?.name|| 'N/A') + {{selectedSessionType =='api' ? (selectedSession?.name|| 'N/A') : '[' + selectedSession?.type + '] ' + selectedSession?.name || 'N/A'}} @@ -25,7 +25,7 @@ -
+
[{{selectedSession?.method}}] diff --git a/src/app/views/session-detail/session-detail.component.ts b/src/app/views/session-detail/session-detail.component.ts index dbe279e..f5fdc90 100644 --- a/src/app/views/session-detail/session-detail.component.ts +++ b/src/app/views/session-detail/session-detail.component.ts @@ -69,7 +69,7 @@ export class SessionDetailComponent implements OnDestroy { this.groupQueriesBySchema(); // Check if parent exist this.sessionParent = null; - if (this.selectedSessionType == "rest") { + if (this.selectedSessionType == "api") { this._traceService.getSessionParentByChildId(id).subscribe({ next: (data: { id: string, type: SessionType }) => { this.sessionParent = data; @@ -85,9 +85,9 @@ export class SessionDetailComponent implements OnDestroy { selectedRequest(event: { event: MouseEvent, row: any }) { if (event.row) { if (event.event.ctrlKey) { - this._router.open(`#/session/rest/${event.row}`, '_blank',) + this._router.open(`#/session/api/${event.row}`, '_blank',) } else { - this._router.navigate(['/session', 'rest', event.row], { queryParams: { env: this.env } }); // TODO remove env FIX BUG + this._router.navigate(['/session', 'api', event.row], { queryParams: { env: this.env } }); // TODO remove env FIX BUG } } } @@ -113,7 +113,7 @@ export class SessionDetailComponent implements OnDestroy { } getSessionDetailBorder() { - if (this.selectedSessionType == "rest") + if (this.selectedSessionType == "api") return Utils.statusBorderCard((this.selectedSession)?.status) if (this.selectedSessionType == "main") return Utils.statusBorderCard(!!(this.selectedSession)?.exception?.message) diff --git a/src/app/views/stats-api/stats-api.component.ts b/src/app/views/stats-api/stats-api.component.ts index 258a6b1..c27dda5 100644 --- a/src/app/views/stats-api/stats-api.component.ts +++ b/src/app/views/stats-api/stats-api.component.ts @@ -132,17 +132,17 @@ export class StatsApiComponent implements OnInit, OnDestroy { let now = new Date(); var groupedBy = periodManagement(start, end); return { - repartitionTimeAndTypeResponse: { observable: this._statsService.getSessionRest({ 'column': "count_slowest:elapsedTimeSlowest,count_slow:elapsedTimeSlow,count_medium:elapsedTimeMedium,count_fast:elapsedTimeFast,count_fastest:elapsedTimeFastest,count_succes:countSucces,count_error_server:countErrorServer,count_error_client:countErrorClient", 'rest_session.instance_env': 'instance.id', 'api_name': name, 'rest_session.start.ge': start.toISOString(), 'rest_session.start.lt': end.toISOString(), 'instance.environement': env, ...advancedParams }) }, + repartitionTimeAndTypeResponse: { observable: this._statsService.getRestSession({ 'column': "count_slowest:elapsedTimeSlowest,count_slow:elapsedTimeSlow,count_medium:elapsedTimeMedium,count_fast:elapsedTimeFast,count_fastest:elapsedTimeFastest,count_succes:countSucces,count_error_server:countErrorServer,count_error_client:countErrorClient", 'rest_session.instance_env': 'instance.id', 'api_name': name, 'rest_session.start.ge': start.toISOString(), 'rest_session.start.lt': end.toISOString(), 'instance.environement': env, ...advancedParams }) }, repartitionTimeAndTypeResponseByPeriod: { - observable: this._statsService.getSessionRest({ 'column': `count_succes:countSucces,count_error_client:countErrorClient,count_error_server:countErrorServer,count_slowest:elapsedTimeSlowest,count_slow:elapsedTimeSlow,count_medium:elapsedTimeMedium,count_fast:elapsedTimeFast,count_fastest:elapsedTimeFastest,elapsedtime.avg:avg,elapsedtime.max:max,rest_session.start.${groupedBy}:date,rest_session.start.year:year`, 'rest_session.instance_env': 'instance.id', 'api_name': name, 'rest_session.start.ge': start.toISOString(), 'rest_session.start.lt': end.toISOString(), 'instance.environement': env, 'order': `rest_session.start.year.asc,rest_session.start.${groupedBy}.asc`, ...advancedParams }).pipe(map((r: any[]) => { + observable: this._statsService.getRestSession({ 'column': `count_succes:countSucces,count_error_client:countErrorClient,count_error_server:countErrorServer,count_slowest:elapsedTimeSlowest,count_slow:elapsedTimeSlow,count_medium:elapsedTimeMedium,count_fast:elapsedTimeFast,count_fastest:elapsedTimeFastest,elapsedtime.avg:avg,elapsedtime.max:max,rest_session.start.${groupedBy}:date,rest_session.start.year:year`, 'rest_session.instance_env': 'instance.id', 'api_name': name, 'rest_session.start.ge': start.toISOString(), 'rest_session.start.lt': end.toISOString(), 'instance.environement': env, 'order': `rest_session.start.year.asc,rest_session.start.${groupedBy}.asc`, ...advancedParams }).pipe(map((r: any[]) => { formatters[groupedBy](r, this._datePipe); return r; })) }, - repartitionRequestByPeriodLine: { observable: this._statsService.getSessionRest({ 'column': `count:count,count_error_server:countErrorServer,count_slowest:countSlowest,rest_session.start.date:date`, 'rest_session.instance_env': 'instance.id', 'api_name': name, 'rest_session.start.ge': new Date(now.getFullYear(), now.getMonth(), now.getDate() - 6).toISOString(), 'rest_session.start.lt': now.toISOString(), 'instance.environement': env, 'order': 'rest_session.start.date.asc', ...advancedParams }) }, // 7 derniers jours - repartitionUserPolar: { observable: this._statsService.getSessionRest({ 'column': "count:count,instance.user:user", 'rest_session.instance_env': 'instance.id', 'api_name': name, 'rest_session.start.ge': start.toISOString(), 'rest_session.start.lt': end.toISOString(), 'instance.environement': env, 'instance.user.not': 'null', 'order': 'count.desc', ...advancedParams }).pipe(map((r: any[]) => r.slice(0, 5))) }, + repartitionRequestByPeriodLine: { observable: this._statsService.getRestSession({ 'column': `count:count,count_error_server:countErrorServer,count_slowest:countSlowest,rest_session.start.date:date`, 'rest_session.instance_env': 'instance.id', 'api_name': name, 'rest_session.start.ge': new Date(now.getFullYear(), now.getMonth(), now.getDate() - 6).toISOString(), 'rest_session.start.lt': now.toISOString(), 'instance.environement': env, 'order': 'rest_session.start.date.asc', ...advancedParams }) }, // 7 derniers jours + repartitionUserPolar: { observable: this._statsService.getRestSession({ 'column': "count:count,instance.user:user", 'rest_session.instance_env': 'instance.id', 'api_name': name, 'rest_session.start.ge': start.toISOString(), 'rest_session.start.lt': end.toISOString(), 'instance.environement': env, 'instance.user.not': 'null', 'order': 'count.desc', ...advancedParams }).pipe(map((r: any[]) => r.slice(0, 5))) }, repartitionUserBar: { - observable: this._statsService.getSessionRest({ 'column': `count:count,rest_session.start.${groupedBy}:date,rest_session.start.year:year,instance.user:user`, 'rest_session.instance_env': 'instance.id', 'api_name': name, 'rest_session.start.ge': start.toISOString(), 'rest_session.start.lt': end.toISOString(), 'instance.environement': env, 'instance.user.not': 'null', 'order': `rest_session.start.year.asc,rest_session.start.${groupedBy}.asc`, ...advancedParams }).pipe(map((r: any[]) => { + observable: this._statsService.getRestSession({ 'column': `count:count,rest_session.start.${groupedBy}:date,rest_session.start.year:year,instance.user:user`, 'rest_session.instance_env': 'instance.id', 'api_name': name, 'rest_session.start.ge': start.toISOString(), 'rest_session.start.lt': end.toISOString(), 'instance.environement': env, 'instance.user.not': 'null', 'order': `rest_session.start.year.asc,rest_session.start.${groupedBy}.asc`, ...advancedParams }).pipe(map((r: any[]) => { let groupBy = groupingBy(r, 'user'); let results: { count: number, user: string, date: any, year: any }[] = Object.entries(groupBy).map((value: [string, any[]]) => { return { @@ -162,9 +162,9 @@ export class StatsApiComponent implements OnInit, OnDestroy { return r; })) }, - dependentsTable: { observable: this._statsService.getSessionRest({ 'column': "count:count,count_succes:countSucces,count_error_client:countErrClient,count_error_server:countErrServer,rest_session2.api_name:name", 'rest_session.instance_env': 'instance.id', "rest_session.id": "rest_request.parent", "rest_request.remote": "rest_session2.id", 'rest_session.api_name': name, 'rest_session.start.ge': start.toISOString(), 'rest_session.start.lt': end.toISOString(), 'rest_session2.start.ge': start.toISOString(), 'rest_session2.start.lt': end.toISOString(), 'instance.environement': env, 'rest_session2.api_name.not': 'null', 'order': 'count.desc', ...advancedParams }) }, - dependenciesTable: { observable: this._statsService.getSessionRest({ 'column': "count:count,count_succes:countSucces,count_error_client:countErrClient,count_error_server:countErrServer,rest_session.api_name:name", 'rest_session.instance_env': 'instance.id', "rest_session.id": "rest_request.parent", "rest_request.remote": "rest_session2.id", 'rest_session2.api_name': name, 'rest_session2.start.ge': start.toISOString(), 'rest_session2.start.lt': end.toISOString(), 'rest_session.start.ge': start.toISOString(), 'rest_session.start.lt': end.toISOString(), 'instance.environement': env, 'rest_session.api_name.not': 'null', 'order': 'count.desc', ...advancedParams }) }, - exceptionsTable: { observable: this._statsService.getSessionRest({ 'column': 'count,err_type,err_msg', 'rest_session.instance_env': 'instance.id', 'err.group': '', "status.ge": 500, "instance.environement": env, "api_name": name, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'order': 'count.desc', ...advancedParams })} + dependentsTable: { observable: this._statsService.getRestSession({ 'column': "count:count,count_succes:countSucces,count_error_client:countErrClient,count_error_server:countErrServer,rest_session2.api_name:name", 'rest_session.instance_env': 'instance.id', "rest_session.id": "rest_request.parent", "rest_request.remote": "rest_session2.id", 'rest_session.api_name': name, 'rest_session.start.ge': start.toISOString(), 'rest_session.start.lt': end.toISOString(), 'rest_session2.start.ge': start.toISOString(), 'rest_session2.start.lt': end.toISOString(), 'instance.environement': env, 'rest_session2.api_name.not': 'null', 'order': 'count.desc', ...advancedParams }) }, + dependenciesTable: { observable: this._statsService.getRestSession({ 'column': "count:count,count_succes:countSucces,count_error_client:countErrClient,count_error_server:countErrServer,rest_session.api_name:name", 'rest_session.instance_env': 'instance.id', "rest_session.id": "rest_request.parent", "rest_request.remote": "rest_session2.id", 'rest_session2.api_name': name, 'rest_session2.start.ge': start.toISOString(), 'rest_session2.start.lt': end.toISOString(), 'rest_session.start.ge': start.toISOString(), 'rest_session.start.lt': end.toISOString(), 'instance.environement': env, 'rest_session.api_name.not': 'null', 'order': 'count.desc', ...advancedParams }) }, + exceptionsTable: { observable: this._statsService.getRestSession({ 'column': 'count,err_type,err_msg', 'rest_session.instance_env': 'instance.id', 'err.group': '', "status.ge": 500, "instance.environement": env, "api_name": name, 'rest_session.start.ge': start.toISOString(), 'rest_session.start.lt': end.toISOString(), 'order': 'count.desc', ...advancedParams })} }; } diff --git a/src/app/views/stats-app/stats-app.component.ts b/src/app/views/stats-app/stats-app.component.ts index b84f872..f03daf8 100644 --- a/src/app/views/stats-app/stats-app.component.ts +++ b/src/app/views/stats-app/stats-app.component.ts @@ -130,17 +130,17 @@ export class StatsAppComponent implements OnInit, OnDestroy { let now = new Date(); var groupedBy = periodManagement(start, end); return { - repartitionTimeAndTypeResponse: { observable: this._statsService.getSessionRest({ "column": "count_slowest:elapsedTimeSlowest,count_slow:elapsedTimeSlow,count_medium:elapsedTimeMedium,count_fast:elapsedTimeFast,count_fastest:elapsedTimeFastest,count_succes:countSucces,count_error_server:countErrorServer,count_error_client:countErrorClient", 'app_name': name, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'environement': env, ...advancedParams }) }, + repartitionTimeAndTypeResponse: { observable: this._statsService.getRestSession({ "column": "count_slowest:elapsedTimeSlowest,count_slow:elapsedTimeSlow,count_medium:elapsedTimeMedium,count_fast:elapsedTimeFast,count_fastest:elapsedTimeFastest,count_succes:countSucces,count_error_server:countErrorServer,count_error_client:countErrorClient", 'rest_session.instance_env': 'instance.id', 'instance.app_name': name, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'instance.environement': env, ...advancedParams }) }, repartitionTimeAndTypeResponseByPeriod: { - observable: this._statsService.getSessionRest({ 'column': `count_succes:countSucces,count_error_client:countErrorClient,count_error_server:countErrorServer,count_slowest:elapsedTimeSlowest,count_slow:elapsedTimeSlow,count_medium:elapsedTimeMedium,count_fast:elapsedTimeFast,count_fastest:elapsedTimeFastest,elapsedtime.avg:avg,elapsedtime.max:max,start.${groupedBy}:date,start.year:year`, 'app_name': name, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'environement': env, 'order': `start.year.asc,start.${groupedBy}.asc`, ...advancedParams }).pipe(map(((r: any[]) => { + observable: this._statsService.getRestSession({ 'column': `count_succes:countSucces,count_error_client:countErrorClient,count_error_server:countErrorServer,count_slowest:elapsedTimeSlowest,count_slow:elapsedTimeSlow,count_medium:elapsedTimeMedium,count_fast:elapsedTimeFast,count_fastest:elapsedTimeFastest,elapsedtime.avg:avg,elapsedtime.max:max,start.${groupedBy}:date,start.year:year`, 'rest_session.instance_env': 'instance.id', 'instance.app_name': name, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'instance.environement': env, 'order': `start.year.asc,start.${groupedBy}.asc`, ...advancedParams }).pipe(map(((r: any[]) => { formatters[groupedBy](r, this._datePipe); return r; }))) }, - repartitionRequestByPeriodLine: { observable: this._statsService.getSessionRest({ 'column': "count:count,count_error_server:countErrorServer,count_slowest:countSlowest,start.date:date", 'app_name': name, 'start.ge': new Date(now.getFullYear(), now.getMonth(), now.getDate() - 6).toISOString(), 'start.lt': now.toISOString(), 'environement': env, 'order': 'start.date.asc', ...advancedParams }) }, - repartitionUserPolar: { observable: this._statsService.getSessionRest({ 'column': "count:count,user:user", 'app_name': name, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'environement': env, 'user.not': 'null', 'order': 'count.desc', ...advancedParams }).pipe(map((r: any[]) => r.slice(0, 5))) }, + repartitionRequestByPeriodLine: { observable: this._statsService.getRestSession({ 'column': "count:count,count_error_server:countErrorServer,count_slowest:countSlowest,rest_session.start.date:date", 'rest_session.instance_env': 'instance.id', 'instance.app_name': name, 'rest_session.start.ge': new Date(now.getFullYear(), now.getMonth(), now.getDate() - 6).toISOString(), 'rest_session.start.lt': now.toISOString(), 'instance.environement': env, 'order': 'rest_session.start.date.asc', ...advancedParams }) }, + repartitionUserPolar: { observable: this._statsService.getRestSession({ 'column': "count:count,instance.user:user", 'rest_session.instance_env': 'instance.id', 'instance.app_name': name, 'rest_session.start.ge': start.toISOString(), 'rest_session.start.lt': end.toISOString(), 'instance.environement': env, 'instance.user.not': 'null', 'order': 'count.desc', ...advancedParams }).pipe(map((r: any[]) => r.slice(0, 5))) }, repartitionUserBar: { - observable: this._statsService.getSessionRest({ 'column': `count:count,start.${groupedBy}:date,start.year:year,user:user`, 'app_name': name, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'environement': env, 'user.not': 'null', 'order': `start.year.asc,start.${groupedBy}.asc`, ...advancedParams }).pipe(map((r: any[]) => { + observable: this._statsService.getRestSession({ 'column': `count:count,rest_session.start.${groupedBy}:date,rest_session.start.year:year,instance.user:user`, 'rest_session.instance_env': 'instance.id', 'instance.app_name': name, 'rest_session.start.ge': start.toISOString(), 'rest_session.start.lt': end.toISOString(), 'instance.environement': env, 'instance.user.not': 'null', 'order': `rest_session.start.year.asc,rest_session.start.${groupedBy}.asc`, ...advancedParams }).pipe(map((r: any[]) => { let groupBy = groupingBy(r, 'user'); let results: { count: number, user: string, date: any, year: any }[] = Object.entries(groupBy).map((value: [string, any[]]) => { return { @@ -160,10 +160,10 @@ export class StatsAppComponent implements OnInit, OnDestroy { return r; })) }, - repartitionApiBar: { observable: this._statsService.getSessionRest({ 'column': "count_succes:countSucces,count_error_client:countErrorClient,count_error_server:countErrorServer,api_name", 'app_name': name, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'environement': env, 'api_name.not': 'null', 'order': 'count.desc', ...advancedParams }).pipe(map((d: any) => d.slice(0, 5))) }, - dependentsTable: { observable: this._statsService.getSessionRest({ 'column': "count:count,count_succes:countSucces,count_error_client:countErrClient,count_error_server:countErrServer,apisession2.app_name:name", "apisession.id": "apirequest.parent", "apirequest.id": "apisession2.id", 'apisession.app_name': name, 'apisession.start.ge': start.toISOString(), 'apisession.start.lt': end.toISOString(), 'apisession2.start.ge': start.toISOString(), 'apisession2.start.lt': end.toISOString(), 'environement': env, 'apisession2.app_name.not': 'null', 'order': 'count.desc', ...advancedParams }) }, - dependenciesTable: { observable: this._statsService.getSessionRest({ 'column': "count:count,count_succes:countSucces,count_error_client:countErrClient,count_error_server:countErrServer,apisession.app_name:name", "apisession.id": "apirequest.parent", "apirequest.id": "apisession2.id", 'apisession2.app_name': name, 'apisession2.start.ge': start.toISOString(), 'apisession2.start.lt': end.toISOString(), 'apisession.start.ge': start.toISOString(), 'apisession.start.lt': end.toISOString(), 'environement': env, 'apisession.app_name.not': 'null', 'order': 'count.desc', ...advancedParams }) }, - exceptionsTable: { observable: this._statsService.getSessionRest({ 'column': 'count,err_type,err_msg', 'err.group': '', "status.ge": 500, "environement": env, "app_name": name, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'order': 'count.desc', ...advancedParams })} + repartitionApiBar: { observable: this._statsService.getRestSession({ 'column': "count_succes:countSucces,count_error_client:countErrorClient,count_error_server:countErrorServer,api_name", 'rest_session.instance_env': 'instance.id', 'instance.app_name': name, 'rest_session.start.ge': start.toISOString(), 'rest_session.start.lt': end.toISOString(), 'instance.environement': env, 'api_name.not': 'null', 'order': 'count.desc', ...advancedParams }).pipe(map((d: any) => d.slice(0, 5))) }, + dependentsTable: { observable: this._statsService.getRestSession({ 'column': "count:count,count_succes:countSucces,count_error_client:countErrClient,count_error_server:countErrServer,instance.app_name:name", 'rest_session.instance_env': 'instance.id', "rest_session.id": "rest_request.parent", "rest_request.remote": "rest_session2.id", 'instance.app_name': name, 'rest_session.start.ge': start.toISOString(), 'rest_session.start.lt': end.toISOString(), 'rest_session2.start.ge': start.toISOString(), 'rest_session2.start.lt': end.toISOString(), 'instance.environement': env, 'instance.app_name.not': 'null', 'order': 'count.desc', ...advancedParams }) }, + dependenciesTable: { observable: this._statsService.getRestSession({ 'column': "count:count,count_succes:countSucces,count_error_client:countErrClient,count_error_server:countErrServer,instance.app_name:name", 'rest_session.instance_env': 'instance.id', "rest_session.id": "rest_request.parent", "rest_request.remote": "rest_session2.id", 'instance.app_name': name, 'rest_session2.start.ge': start.toISOString(), 'rest_session2.start.lt': end.toISOString(), 'rest_session.start.ge': start.toISOString(), 'rest_session.start.lt': end.toISOString(), 'instance.environement': env, 'instance.app_name.not': 'null', 'order': 'count.desc', ...advancedParams }) }, + exceptionsTable: { observable: this._statsService.getRestSession({ 'column': 'count,err_type,err_msg', 'err.group': '', 'rest_session.instance_env': 'instance.id', "status.ge": 500, "instance.environement": env, "instance.app_name": name, 'rest_session.start.ge': start.toISOString(), 'rest_session.start.lt': end.toISOString(), 'order': 'count.desc', ...advancedParams })} }; }; diff --git a/src/app/views/stats-database/stats-database.component.html b/src/app/views/stats-database/stats-database.component.html index bf86a88..b76ee8b 100644 --- a/src/app/views/stats-database/stats-database.component.html +++ b/src/app/views/stats-database/stats-database.component.html @@ -49,10 +49,10 @@
-
+
diff --git a/src/app/views/stats-database/stats-database.component.ts b/src/app/views/stats-database/stats-database.component.ts index d513582..4637481 100644 --- a/src/app/views/stats-database/stats-database.component.ts +++ b/src/app/views/stats-database/stats-database.component.ts @@ -79,7 +79,7 @@ export class StatsDatabaseComponent implements OnInit { this.dbNameListIsLoading = true; this.serverFilterForm.controls.dbnameControl.reset(); this.serverFilterForm.controls.dbnameControl.disable(); - this._statsService.getSessionRest({ 'column.distinct': 'dbquery.db&dbquery.parent=apisession.id&order=dbquery.db.asc', 'apisession.environement': this.env }).pipe(catchError(error => of(error))) + this._statsService.getRestSession({ 'column.distinct': 'dbquery.db&dbquery.parent=apisession.id&order=dbquery.db.asc', 'apisession.environement': this.env }).pipe(catchError(error => of(error))) .subscribe({ next: (res: { db: string }[]) => { this.dbNameDataList = res.map((s: any) => s.db) @@ -135,22 +135,22 @@ export class StatsDatabaseComponent implements OnInit { let now = new Date(); var groupedBy = periodManagement(start, end); return { - dbInfo: { observable: this._statsService.getSessionRest({ 'column.distinct': 'dbquery.host,dbquery.db,dbquery.driver,dbquery.db_name,dbquery.db_version', 'dbquery.parent': 'apisession.id', "apisession.environement": env, "dbquery.db": db, 'dbquery.start.ge': start.toISOString(), 'dbquery.start.lt': end.toISOString(), 'apisession.start.ge': start.toISOString(), 'apisession.start.lt': end.toISOString() }) }, - countOkKoSlowest: { observable: this._statsService.getSessionRest({ 'column': 'dbquery.count_db_error:countErrorServer,dbquery.count:count,dbquery.count_slowest:countSlowest,dbquery.start.date:date', 'dbquery.parent': 'apisession.id', "apisession.environement": env, "dbquery.db": db, 'apisession.start.ge': new Date(now.getFullYear(), now.getMonth(), now.getDate() - 6).toISOString(), 'apisession.start.lt': now.toISOString(), 'dbquery.start.ge': new Date(now.getFullYear(), now.getMonth(), now.getDate() - 7).toISOString(), 'dbquery.start.lt': now.toISOString()}) }, - countMinMaxAvg: { observable: this._statsService.getSessionRest({ 'column': `dbquery.count_db_succes:countDbSucces,dbquery.elapsedtime.max:max,dbquery.elapsedtime.avg:avg,dbquery.start.${groupedBy}:date,dbquery.start.year:year`, 'dbquery.parent': 'apisession.id', "apisession.environement": env, "dbquery.db": db, 'apisession.start.ge': start.toISOString(), 'apisession.start.lt': end.toISOString(), 'dbquery.start.ge': start.toISOString(), 'dbquery.start.lt': end.toISOString(), 'order': `dbquery.start.year.asc,dbquery.start.${groupedBy}.asc` }).pipe(map(((r: any[]) => { + dbInfo: { observable: this._statsService.getDatabaseRequest({ 'column.distinct': 'host,db,driver,db_name,db_version', 'database_request.parent': 'rest_session.id', 'rest_session.instance_env': 'instance.id', "instance.environement": env, "db": db, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'rest_session.start.ge': start.toISOString(), 'rest_session.start.lt': end.toISOString() }) }, + countOkKoSlowest: { observable: this._statsService.getDatabaseRequest({ 'column': 'count_db_error:countErrorServer,count:count,count_slowest:countSlowest,start.date:date', 'database_request.parent': 'rest_session.id', 'rest_session.instance_env': 'instance.id', "instance.environement": env, "db": db, 'rest_session.start.ge': new Date(now.getFullYear(), now.getMonth(), now.getDate() - 6).toISOString(), 'rest_session.start.lt': now.toISOString(), 'start.ge': new Date(now.getFullYear(), now.getMonth(), now.getDate() - 7).toISOString(), 'start.lt': now.toISOString()}) }, + countMinMaxAvg: { observable: this._statsService.getDatabaseRequest({ 'column': `count_db_succes:countDbSucces,elapsedtime.max:max,elapsedtime.avg:avg,start.${groupedBy}:date,start.year:year`, 'database_request.parent': 'rest_session.id', 'rest_session.instance_env': 'instance.id', "instance.environement": env, "db": db, 'rest_session.start.ge': start.toISOString(), 'rest_session.start.lt': end.toISOString(), 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'order': `start.year.asc,start.${groupedBy}.asc` }).pipe(map(((r: any[]) => { formatters[groupedBy](r, this._datePipe); return r; }))) }, countRepartitionBySpeedBar: { - observable: this._statsService.getSessionRest({ 'column': `dbquery.count_slowest:elapsedTimeSlowest,dbquery.count_slow:elapsedTimeSlow,dbquery.count_medium:elapsedTimeMedium,dbquery.count_fast:elapsedTimeFast,dbquery.count_fastest:elapsedTimeFastest,dbquery.start.${groupedBy}:date,dbquery.start.year:year`, 'dbquery.parent': 'apisession.id', "apisession.environement": env, "dbquery.db": db, 'apisession.start.ge': start.toISOString(), 'apisession.start.lt': end.toISOString(), 'dbquery.start.ge': start.toISOString(), 'dbquery.start.lt': end.toISOString(), 'order': `dbquery.start.year.asc,dbquery.start.${groupedBy}.asc` }).pipe(map(((r: any[]) => { + observable: this._statsService.getDatabaseRequest({ 'column': `count_slowest:elapsedTimeSlowest,count_slow:elapsedTimeSlow,count_medium:elapsedTimeMedium,count_fast:elapsedTimeFast,count_fastest:elapsedTimeFastest,start.${groupedBy}:date,start.year:year`, 'database_request.parent': 'rest_session.id', 'rest_session.instance_env': 'instance.id', "instance.environement": env, "db": db, 'rest_session.start.ge': start.toISOString(), 'rest_session.start.lt': end.toISOString(), 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'order': `start.year.asc,start.${groupedBy}.asc` }).pipe(map(((r: any[]) => { formatters[groupedBy](r, this._datePipe); return r; }))) }, - countRepartitionBySpeedPie: { observable: this._statsService.getSessionRest({ 'column': 'dbquery.count_slowest:elapsedTimeSlowest,dbquery.count_slow:elapsedTimeSlow,dbquery.count_medium:elapsedTimeMedium,dbquery.count_fast:elapsedTimeFast,dbquery.count_fastest:elapsedTimeFastest', 'dbquery.parent': 'apisession.id', "apisession.environement": env, "dbquery.db": db, 'apisession.start.ge': start.toISOString(), 'apisession.start.lt': end.toISOString(), 'dbquery.start.ge': start.toISOString(), 'dbquery.start.lt': end.toISOString()}) }, - exceptions: { observable: this._statsService.getSessionRest({ 'column': 'count,dbaction.err_type,dbaction.err_msg', 'dbaction.err.group': '', 'dbaction.parent': 'dbquery.id', 'dbquery.parent': 'apisession.id', 'order': 'count.desc', "apisession.environement": env, "dbquery.db": db, 'apisession.start.ge': start.toISOString(), 'apisession.start.lt': end.toISOString(), 'dbquery.start.ge': start.toISOString(), 'dbquery.start.lt': end.toISOString() })}, - usersInfo: { observable: this._statsService.getSessionRest({ 'column': 'count:countRows,dbquery.user', 'dbquery.parent': 'apisession.id', "apisession.environement": env, "dbquery.db": db, 'apisession.start.ge': start.toISOString(), 'apisession.start.lt': end.toISOString(), 'dbquery.start.ge': start.toISOString(), 'dbquery.start.lt': end.toISOString() }) } + countRepartitionBySpeedPie: { observable: this._statsService.getDatabaseRequest({ 'column': 'count_slowest:elapsedTimeSlowest,count_slow:elapsedTimeSlow,count_medium:elapsedTimeMedium,count_fast:elapsedTimeFast,count_fastest:elapsedTimeFastest', 'database_request.parent': 'rest_session.id', 'rest_session.instance_env': 'instance.id', "instance.environement": env, "db": db, 'rest_session.start.ge': start.toISOString(), 'rest_session.start.lt': end.toISOString(), 'start.ge': start.toISOString(), 'start.lt': end.toISOString()}) }, + exceptions: { observable: this._statsService.getException({ 'column': 'count,err_type,err_msg', 'err.group': '', 'exception.parent': 'database_request.id', 'database_request.parent': 'rest_session.id', 'rest_session.instance_env': 'instance.id', "instance.environement": env, "database_request.db": db, 'rest_session.start.ge': start.toISOString(), 'rest_session.start.lt': end.toISOString(), 'database_request.start.ge': start.toISOString(), 'database_request.start.lt': end.toISOString(), 'order': 'count.desc' })} + // usersInfo: { observable: this._statsService.getDatabaseRequest({ 'column': 'count:countRows,dbquery.user', 'dbquery.parent': 'apisession.id', "apisession.environement": env, "dbquery.db": db, 'apisession.start.ge': start.toISOString(), 'apisession.start.lt': end.toISOString(), 'dbquery.start.ge': start.toISOString(), 'dbquery.start.lt': end.toISOString() }) } } } diff --git a/src/app/views/stats-user/stats-user.component.html b/src/app/views/stats-user/stats-user.component.html index 9a0f24c..077cf07 100644 --- a/src/app/views/stats-user/stats-user.component.html +++ b/src/app/views/stats-user/stats-user.component.html @@ -68,10 +68,10 @@ [data]="requests.repartitionTimeAndTypeResponseByPeriod?.data" [isLoading]="requests.repartitionTimeAndTypeResponseByPeriod?.isLoading" />
-
+
\ No newline at end of file diff --git a/src/app/views/stats-user/stats-user.component.ts b/src/app/views/stats-user/stats-user.component.ts index f8468d0..3e2d810 100644 --- a/src/app/views/stats-user/stats-user.component.ts +++ b/src/app/views/stats-user/stats-user.component.ts @@ -120,17 +120,17 @@ export class StatsUserComponent implements OnInit, OnDestroy { let now = new Date(); var groupedBy = periodManagement(start, end); return { - repartitionTimeAndTypeResponse: { observable: this._statsService.getSessionRest({ 'column': "count_slowest:elapsedTimeSlowest,count_slow:elapsedTimeSlow,count_medium:elapsedTimeMedium,count_fast:elapsedTimeFast,count_fastest:elapsedTimeFastest,count_succes:countSucces,count_error_server:countErrorServer,count_error_client:countErrorClient", 'user': name, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'environement': env, ...advancedParams }) }, + repartitionTimeAndTypeResponse: { observable: this._statsService.getRestSession({ 'column': "count_slowest:elapsedTimeSlowest,count_slow:elapsedTimeSlow,count_medium:elapsedTimeMedium,count_fast:elapsedTimeFast,count_fastest:elapsedTimeFastest,count_succes:countSucces,count_error_server:countErrorServer,count_error_client:countErrorClient", 'rest_session.instance_env': 'instance.id', 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'instance.environement': env, 'instance.user': name, ...advancedParams }) }, repartitionTimeAndTypeResponseByPeriod: { - observable: this._statsService.getSessionRest({ 'column': `count_succes:countSucces,count_error_client:countErrorClient,count_error_server:countErrorServer,count_slowest:elapsedTimeSlowest,count_slow:elapsedTimeSlow,count_medium:elapsedTimeMedium,count_fast:elapsedTimeFast,count_fastest:elapsedTimeFastest,elapsedtime.avg:avg,elapsedtime.max:max,start.${groupedBy}:date,start.year:year`, 'user': name, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'environement': env, 'order': `start.year.asc,start.${groupedBy}.asc`, ...advancedParams }).pipe(map(((r: any[]) => { + observable: this._statsService.getRestSession({ 'column': `count_succes:countSucces,count_error_client:countErrorClient,count_error_server:countErrorServer,count_slowest:elapsedTimeSlowest,count_slow:elapsedTimeSlow,count_medium:elapsedTimeMedium,count_fast:elapsedTimeFast,count_fastest:elapsedTimeFastest,elapsedtime.avg:avg,elapsedtime.max:max,start.${groupedBy}:date,start.year:year`, 'rest_session.instance_env': 'instance.id', 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'instance.user': name, 'instance.environement': env, 'order': `start.year.asc,start.${groupedBy}.asc`, ...advancedParams }).pipe(map(((r: any[]) => { formatters[groupedBy](r, this._datePipe); return r; }))) }, - repartitionRequestByPeriodLine: { observable: this._statsService.getSessionRest({ 'column': "count:count,count_error_server:countErrorServer,count_slowest:countSlowest,start.date:date", 'user': name, 'start.ge': new Date(now.getFullYear(), now.getMonth(), now.getDate() - 6).toISOString(), 'start.lt': now.toISOString(), 'environement': env, 'order': 'start.date.asc', ...advancedParams }) }, - repartitionApiBar: { observable: this._statsService.getSessionRest({ 'column': "count_succes:countSucces,count_error_client:countErrorClient,count_error_server:countErrorServer,api_name", 'user': name, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'environement': env, 'api_name.not': 'null', 'order': 'count.desc', ...advancedParams }).pipe(map((d: any) => d.slice(0, 5))) }, - exceptionsTable: { observable: this._statsService.getSessionRest({ 'column': 'count,err_type,err_msg', 'err.group': '', "status.ge": 500, "environement": env, 'user': name, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'order': 'count.desc', ...advancedParams })}, - sessionTable: { observable: this._statsService.getSessionMain({ 'column': "name,start:date,elapsedtime,location,app_name", 'user': name, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'environement': env, 'order': 'start.date.desc' }) } + repartitionRequestByPeriodLine: { observable: this._statsService.getRestSession({ 'column': "count:count,count_error_server:countErrorServer,count_slowest:countSlowest,start.date:date", 'rest_session.instance_env': 'instance.id', 'start.ge': new Date(now.getFullYear(), now.getMonth(), now.getDate() - 6).toISOString(), 'start.lt': now.toISOString(), 'instance.environement': env, 'instance.user': name, 'order': 'start.date.asc', ...advancedParams }) }, + repartitionApiBar: { observable: this._statsService.getRestSession({ 'column': "count_succes:countSucces,count_error_client:countErrorClient,count_error_server:countErrorServer,api_name", 'rest_session.instance_env': 'instance.id', 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'instance.environement': env, 'instance.user': name, 'api_name.not': 'null', 'order': 'count.desc', ...advancedParams }).pipe(map((d: any) => d.slice(0, 5))) }, + // exceptionsTable: { observable: this._statsService.getException({ 'column': 'count,err_type,err_msg', 'err.group': '', "status.ge": 500, "environement": env, 'user': name, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'order': 'count.desc', ...advancedParams })}, + sessionTable: { observable: this._statsService.getMainSession({ 'column': "name,start:date,elapsedtime,location,instance.app_name", 'main_session.instance_env': 'instance.id', 'instance.user': name, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'instance.environement': env, 'order': 'start.date.desc' }) } }; } From ec7c56218c2f03f01c3187f798b28705e34e8a4e Mon Sep 17 00:00:00 2001 From: fufuu Date: Wed, 10 Jul 2024 10:13:25 +0200 Subject: [PATCH 026/126] rename --- src/app/app.component.ts | 4 +- .../advanced-filter-modal.component.ts | 6 +-- src/app/shared/services/stats.service.ts | 39 ------------------- src/app/views/constants.ts | 16 ++++---- .../session-api/session-api.component.ts | 4 +- .../views/stats-api/stats-api.component.ts | 4 +- .../views/stats-app/stats-app.component.ts | 4 +- .../stats-database.component.ts | 4 +- .../views/stats-user/stats-user.component.ts | 4 +- 9 files changed, 23 insertions(+), 62 deletions(-) delete mode 100644 src/app/shared/services/stats.service.ts diff --git a/src/app/app.component.ts b/src/app/app.component.ts index e965737..d1b3f09 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -5,7 +5,7 @@ import { Subscription, distinctUntilChanged, filter, finalize, skip } from 'rxjs import { application, environment } from 'src/environments/environment'; import { EnvRouter } from './views/session-detail/session-detail.component'; import { MatDrawer } from '@angular/material/sidenav'; -import { StatsService } from './shared/services/stats.service'; +import { JQueryService } from './shared/services/jquery.service'; import { FilterService } from './shared/services/filter.service'; @@ -26,7 +26,7 @@ export class AppComponent implements OnInit { constructor( private _activatedRoute: ActivatedRoute, private _router: EnvRouter, - private _service: StatsService) { + private _service: JQueryService) { this.isLoadingEnv = true; this.subscriptions.push(this._service.getInstance({'column.distinct': 'environement', 'order': 'environement.asc'}) .pipe(finalize(() => this.isLoadingEnv = false)) diff --git a/src/app/shared/components/stats/advanced-filter/advanced-filter-modal/advanced-filter-modal.component.ts b/src/app/shared/components/stats/advanced-filter/advanced-filter-modal/advanced-filter-modal.component.ts index 9fea439..9e74ae1 100644 --- a/src/app/shared/components/stats/advanced-filter/advanced-filter-modal/advanced-filter-modal.component.ts +++ b/src/app/shared/components/stats/advanced-filter/advanced-filter-modal/advanced-filter-modal.component.ts @@ -5,7 +5,7 @@ import { MAT_DIALOG_DATA, MatDialogRef } from "@angular/material/dialog"; import { Filter, FilterMap, FilterPreset } from "src/app/views/constants"; import { COMMA, ENTER } from '@angular/cdk/keycodes'; import { Subscription, catchError, finalize, of } from "rxjs"; -import { StatsService } from "src/app/shared/services/stats.service"; +import { JQueryService } from "src/app/shared/services/jquery.service"; import { MatAutocompleteSelectedEvent } from "@angular/material/autocomplete"; import { FilterService } from "src/app/shared/services/filter.service"; @@ -18,7 +18,7 @@ import { FilterService } from "src/app/shared/services/filter.service"; export class AdvancedFilterComponent implements OnInit, AfterContentChecked, OnDestroy { private _fb = inject(FormBuilder); - private _statsService = inject(StatsService); + private _statsService = inject(JQueryService); private _ref = inject(ChangeDetectorRef); private _filter = inject(FilterService); @@ -122,7 +122,7 @@ export class AdvancedFilterComponent implements OnInit, AfterContentChecked, OnD getSelectData(field: Filter) { field.isLoading = true; - this.subscriptions.push(this._statsService.getSessionByEndpoint(field.endpoint, field.query) // url + this.subscriptions.push(this._statsService.getJqueryData(field.endpoint, field.query) // url .pipe(finalize(() => { field.isLoading = false; })) .pipe( catchError(error => { diff --git a/src/app/shared/services/stats.service.ts b/src/app/shared/services/stats.service.ts deleted file mode 100644 index a95a239..0000000 --- a/src/app/shared/services/stats.service.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { HttpClient } from "@angular/common/http"; -import { Injectable } from "@angular/core"; - -@Injectable({ providedIn: 'root' }) -export class StatsService { - constructor(private http: HttpClient) { - - } - - getSessionByEndpoint(endpoint:string ,params: any) { - let url = `${localStorage.getItem('server')}${endpoint}`; - return this.http.get(url, { params: params }); - } - - getRestSession(params: any) { - let url = `${localStorage.getItem('server')}/jquery/session/rest`; - return this.http.get(url, { params: params }); - } - - getMainSession(params: any) { - let url = `${localStorage.getItem('server')}/jquery/session/main`; - return this.http.get(url, { params: params }); - } - - getDatabaseRequest(params: any) { - let url = `${localStorage.getItem('server')}/jquery/request/database`; - return this.http.get(url, { params: params }); - } - - getException(params: any) { - let url = `${localStorage.getItem('server')}/jquery/exception`; - return this.http.get(url, { params: params }); - } - - getInstance(params: any) { - let url = `${localStorage.getItem('server')}/jquery/instance`; - return this.http.get(url, { params: params }); - } -} \ No newline at end of file diff --git a/src/app/views/constants.ts b/src/app/views/constants.ts index ad12e59..797681b 100644 --- a/src/app/views/constants.ts +++ b/src/app/views/constants.ts @@ -408,11 +408,11 @@ export class FilterConstants { static readonly SESSION_API: Filter[] = [ { key: 'query', label: 'Query params', type: 'input', row: 2, col: 1, op: Operation.like }, - { key: 'status', label: 'Status', type: 'select', row: 3, col: 1, endpoint: "/stat/apisession", query: { 'column.distinct': 'status:status', 'order': 'status.asc' }, op: Operation.eq }, - { key: 'method', label: 'Method', type: 'select', width: 20, row: 1, col: 1, endpoint: "/stat/apisession", query: { 'column.distinct': 'method:method', 'order': 'method.asc' }, op: Operation.eq }, + { key: 'status', label: 'Status', type: 'select', row: 3, col: 1, endpoint: "session/rest", query: { 'column.distinct': 'status:status', 'order': 'status.asc' }, op: Operation.eq }, + { key: 'method', label: 'Method', type: 'select', width: 20, row: 1, col: 1, endpoint: "session/rest", query: { 'column.distinct': 'method:method', 'order': 'method.asc' }, op: Operation.eq }, { key: 'path', label: 'Path', type: 'input', row: 1, col: 2, op: Operation.like }, - { key: 'api_name', label: 'Nom API', type: 'select', row: 3, col: 2, endpoint: "/stat/apisession", query: { 'column.distinct': 'api_name.coalesce(null):api_name', 'api_name.not': 'null', 'order': 'api_name.coalesce(null).asc' }, op: Operation.eq }, - { key: 'user', label: 'Utilisateur', type: 'select', row: 3, col: 3, endpoint: "/stat/instance", query: { 'column.distinct': 'user.coalesce(null)', 'user.not': 'null', 'order': 'user.coalesce(null).asc' }, op: Operation.eq } + { key: 'api_name', label: 'Nom API', type: 'select', row: 3, col: 2, endpoint: "session/rest", query: { 'column.distinct': 'api_name.coalesce(null):api_name', 'api_name.not': 'null', 'order': 'api_name.coalesce(null).asc' }, op: Operation.eq }, + { key: 'user', label: 'Utilisateur', type: 'select', row: 3, col: 3, endpoint: "session/rest", query: { 'column.distinct': 'user.coalesce(null)', 'user.not': 'null', 'order': 'user.coalesce(null).asc' }, op: Operation.eq } // new Filter("err_type", "Exception", 'select', 50, "/stat/apisession", null, null, { 'column.distinct': 'err_type:err_type', 'order': 'err_type.asc' }), // new Filter("address", "adresse", 'input', 50), // new Filter("os", "OS", 'select', 50, "/stat/apisession", null, null, { 'column.distinct': 'os', 'order': 'os.asc' }), @@ -423,9 +423,9 @@ export class FilterConstants { ] static readonly SESSION_MAIN: Filter[] = [ - { key: 'name', label: 'Serveur', type: 'select', row: 2, col: 1, endpoint: '/stat/mainsession', query: { 'column.distinct': 'session.name.coalesce(null)', 'session.name.not': 'null', 'order': 'session.name.coalesce(null).asc' }, op: Operation.eq }, + { key: 'name', label: 'Serveur', type: 'select', row: 2, col: 1, endpoint: 'session/main', query: { 'column.distinct': 'name.coalesce(null)', 'name.not': 'null', 'order': 'name.coalesce(null).asc' }, op: Operation.eq }, { key: 'location', label: 'Chemin', type: 'input', row: 1, col: 1, op: Operation.like }, - { key: 'user', label: 'Utilisateur', type: 'select', row: 2, col: 2, endpoint: '/stat/mainsession', query: { 'column.distinct': 'user.coalesce(null)', 'user.not': 'null', 'order': 'user.coalesce(null).asc' }, op: Operation.eq } + { key: 'user', label: 'Utilisateur', type: 'select', row: 2, col: 2, endpoint: 'session/main', query: { 'column.distinct': 'user.coalesce(null)', 'user.not': 'null', 'order': 'user.coalesce(null).asc' }, op: Operation.eq } // new Filter("err_type", "Exception", 'select', 50, "/stat/mainsession", null, null, { 'column.distinct': 'err_type:err_type', 'order': 'err_type.asc' }), // new Filter("os", "OS", 'select', 50, "/stat/mainsession", null, null, { 'column.distinct': 'os', 'order': 'os.asc' }), @@ -435,7 +435,7 @@ export class FilterConstants { static readonly STATS_API: Filter[] = [ { key: 'query', label: 'Query params', type: 'input', row: 1, col: 1, op: Operation.like }, { key: 'status', label: 'Status', type: 'select', row: 2, col: 1, options: [{ status: '200' }, { status: '201' }, { status: '202' }, { status: '400' }, { status: '401' }, { status: '403' }, { status: '404' }, { status: '405' }, { status: '409' }, { status: '415' }, { status: '500' }, { status: '503' }], op: Operation.eq }, - { key: 'user', label: 'Utilisateur', type: 'select', row: 2, col: 2, endpoint: '/stat/apisession', query: { 'column.distinct': 'user.coalesce(null)', 'user.not': 'null', 'order': 'user.coalesce(null).asc' }, op: Operation.eq }, + { key: 'user', label: 'Utilisateur', type: 'select', row: 2, col: 2, endpoint: 'session/rest', query: { 'column.distinct': 'user.coalesce(null)', 'user.not': 'null', 'order': 'user.coalesce(null).asc' }, op: Operation.eq }, //new Filter("os", "OS", 'select', 50, "/stat/apisession", null, null, { 'column.distinct': 'os', 'order': 'os.asc' }), //new Filter("re", "RE", 'select', 50, "/stat/apisession", null, null, { 'column.distinct': 're', 'order': 're.asc' }), //new Filter("err_type", "Exception", 'select', 50, "/stat/apisession", null, null, { 'column.distinct': 'err_type:err_type', 'order': 'err_type.asc' }), @@ -446,7 +446,7 @@ export class FilterConstants { { key: 'query', label: 'Query params', type: 'input', row: 1, col: 2, op: Operation.like }, { key: 'method', label: 'Method', type: 'select', width: 20, row: 1, col: 1, options: [{ method: 'GET' }, { method: 'PUT' }, { method: 'POST' }, { method: 'DELETE' }, { method: 'OPTIONS' }], op: Operation.eq }, { key: 'status', label: 'Status', type: 'select', row: 3, col: 1, options: [{ status: '200' }, { status: '201' }, { status: '202' }, { status: '400' }, { status: '401' }, { status: '403' }, { status: '404' }, { status: '405' }, { status: '409' }, { status: '415' }, { status: '500' }, { status: '503' }], op: Operation.eq }, - { key: 'user', label: 'Utilisateur', type: 'select', row: 3, col: 2, endpoint: '/stat/apisession', query: { 'column.distinct': 'user.coalesce(null)', 'user.not': 'null', 'order': 'user.coalesce(null).asc' }, op: Operation.eq }, + { key: 'user', label: 'Utilisateur', type: 'select', row: 3, col: 2, endpoint: 'session/rest', query: { 'column.distinct': 'user.coalesce(null)', 'user.not': 'null', 'order': 'user.coalesce(null).asc' }, op: Operation.eq }, { key: 'path', label: 'Path', type: 'input', row: 2, col: 1, op: Operation.like } //new Filter("os", "OS", 'select', 50, "/stat/apisession", null, null, { 'column.distinct': 'os', 'order': 'os.asc' }), diff --git a/src/app/views/session-api/session-api.component.ts b/src/app/views/session-api/session-api.component.ts index fadf2a7..0a086a4 100644 --- a/src/app/views/session-api/session-api.component.ts +++ b/src/app/views/session-api/session-api.component.ts @@ -8,7 +8,7 @@ import { ActivatedRoute, Params } from '@angular/router'; import { BehaviorSubject, Observable, Subscription, finalize } from 'rxjs'; import { IncomingRequest } from 'src/app/shared/model/trace.model'; import { Utils } from 'src/app/shared/util'; -import { StatsService } from 'src/app/shared/services/stats.service'; +import { JQueryService } from 'src/app/shared/services/jquery.service'; import { TraceService } from 'src/app/shared/services/trace.service'; import { EnvRouter } from '../session-detail/session-detail.component'; import { application, makePeriod } from 'src/environments/environment'; @@ -47,7 +47,7 @@ export class SessionApiComponent implements OnInit, OnDestroy { @ViewChild(MatSort, { static: true }) sort: MatSort; constructor(private _router: EnvRouter, - private _statsService: StatsService, + private _statsService: JQueryService, private _traceService: TraceService, private _activatedRoute: ActivatedRoute, private _location: Location, diff --git a/src/app/views/stats-api/stats-api.component.ts b/src/app/views/stats-api/stats-api.component.ts index c27dda5..3d7cbcb 100644 --- a/src/app/views/stats-api/stats-api.component.ts +++ b/src/app/views/stats-api/stats-api.component.ts @@ -1,6 +1,6 @@ import { Component, OnDestroy, OnInit, inject } from "@angular/core"; import { EnvRouter } from "../session-detail/session-detail.component"; -import { StatsService } from "src/app/shared/services/stats.service"; +import { JQueryService } from "src/app/shared/services/jquery.service"; import { DatePipe, Location } from '@angular/common'; import { ActivatedRoute, Params } from "@angular/router"; import { FormControl, FormGroup, Validators } from "@angular/forms"; @@ -18,7 +18,7 @@ export class StatsApiComponent implements OnInit, OnDestroy { constants = Constants; filterConstants = FilterConstants; private _activatedRoute = inject(ActivatedRoute); - private _statsService = inject(StatsService); + private _statsService = inject(JQueryService); private _router = inject(EnvRouter); private _location = inject(Location); private _datePipe = inject(DatePipe); diff --git a/src/app/views/stats-app/stats-app.component.ts b/src/app/views/stats-app/stats-app.component.ts index f03daf8..aae90f4 100644 --- a/src/app/views/stats-app/stats-app.component.ts +++ b/src/app/views/stats-app/stats-app.component.ts @@ -1,7 +1,7 @@ import { Component, OnDestroy, OnInit, inject } from "@angular/core"; import { EnvRouter } from "../session-detail/session-detail.component"; import { DatePipe, Location } from '@angular/common'; -import { StatsService } from "src/app/shared/services/stats.service"; +import { JQueryService } from "src/app/shared/services/jquery.service"; import { ActivatedRoute, Params } from "@angular/router"; import { FormControl, FormGroup, Validators } from "@angular/forms"; import { BehaviorSubject, Observable, Subscription, combineLatest, finalize, map } from "rxjs"; @@ -18,7 +18,7 @@ export class StatsAppComponent implements OnInit, OnDestroy { constants = Constants filterConstants = FilterConstants; private _activatedRoute = inject(ActivatedRoute); - private _statsService = inject(StatsService); + private _statsService = inject(JQueryService); private _router = inject(EnvRouter); private _location = inject(Location); private _datePipe = inject(DatePipe); diff --git a/src/app/views/stats-database/stats-database.component.ts b/src/app/views/stats-database/stats-database.component.ts index 4637481..2808983 100644 --- a/src/app/views/stats-database/stats-database.component.ts +++ b/src/app/views/stats-database/stats-database.component.ts @@ -3,7 +3,7 @@ import { ActivatedRoute, Params, Router } from '@angular/router'; import { Observable, Subscription, catchError, combineLatest, finalize, map, of } from 'rxjs'; import { DatePipe, Location } from '@angular/common'; import { FormControl, FormGroup, Validators } from '@angular/forms'; -import { StatsService } from 'src/app/shared/services/stats.service'; +import { JQueryService } from 'src/app/shared/services/jquery.service'; import { MatTableDataSource } from '@angular/material/table'; import { Constants } from '../constants'; import { application, makePeriod } from 'src/environments/environment'; @@ -18,7 +18,7 @@ export class StatsDatabaseComponent implements OnInit { private _activatedRoute = inject(ActivatedRoute); private _router = inject(Router); private _datePipe = inject(DatePipe); - private _statsService = inject(StatsService); + private _statsService = inject(JQueryService); private _location = inject(Location); constants = Constants; diff --git a/src/app/views/stats-user/stats-user.component.ts b/src/app/views/stats-user/stats-user.component.ts index 3e2d810..be942f5 100644 --- a/src/app/views/stats-user/stats-user.component.ts +++ b/src/app/views/stats-user/stats-user.component.ts @@ -1,6 +1,6 @@ import { Component, OnDestroy, OnInit, inject } from "@angular/core"; import { EnvRouter } from "../session-detail/session-detail.component"; -import { StatsService } from "src/app/shared/services/stats.service"; +import { JQueryService } from "src/app/shared/services/jquery.service"; import { ActivatedRoute, Params } from "@angular/router"; import { DatePipe, Location } from '@angular/common'; import { FormControl, FormGroup, Validators } from "@angular/forms"; @@ -19,7 +19,7 @@ export class StatsUserComponent implements OnInit, OnDestroy { filterConstants = FilterConstants; private _activatedRoute = inject(ActivatedRoute); - private _statsService = inject(StatsService); + private _statsService = inject(JQueryService); private _router = inject(EnvRouter); private _location = inject(Location); private _datePipe = inject(DatePipe); From d68daaf3b32965cdbf0af7d9fa770e61ded417ef Mon Sep 17 00:00:00 2001 From: fufuu Date: Wed, 10 Jul 2024 10:14:24 +0200 Subject: [PATCH 027/126] rename --- src/app/shared/services/jquery.service.ts | 39 +++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 src/app/shared/services/jquery.service.ts diff --git a/src/app/shared/services/jquery.service.ts b/src/app/shared/services/jquery.service.ts new file mode 100644 index 0000000..8dc3a98 --- /dev/null +++ b/src/app/shared/services/jquery.service.ts @@ -0,0 +1,39 @@ +import { HttpClient } from "@angular/common/http"; +import { Injectable } from "@angular/core"; + +@Injectable({ providedIn: 'root' }) +export class JQueryService { + constructor(private http: HttpClient) { + + } + + getJqueryData(endpoint:string, params: any) { + let url = `${localStorage.getItem('server')}/jquery/${endpoint}`; + return this.http.get(url, { params: params }); + } + + getRestSession(params: any) { + let url = `${localStorage.getItem('server')}/jquery/session/rest`; + return this.http.get(url, { params: params }); + } + + getMainSession(params: any) { + let url = `${localStorage.getItem('server')}/jquery/session/main`; + return this.http.get(url, { params: params }); + } + + getDatabaseRequest(params: any) { + let url = `${localStorage.getItem('server')}/jquery/request/database`; + return this.http.get(url, { params: params }); + } + + getException(params: any) { + let url = `${localStorage.getItem('server')}/jquery/exception`; + return this.http.get(url, { params: params }); + } + + getInstance(params: any) { + let url = `${localStorage.getItem('server')}/jquery/instance`; + return this.http.get(url, { params: params }); + } +} \ No newline at end of file From bef794a46d5d54a07d506cc8c3738aa43e37f389 Mon Sep 17 00:00:00 2001 From: YoussefDahi Date: Thu, 11 Jul 2024 14:08:19 +0200 Subject: [PATCH 028/126] duration/size pipe --- src/app/shared/pipe/duration.pipe.ts | 27 +++++++++++++++++++ src/app/shared/pipe/size.pipe.ts | 25 +++++++++++++++++ src/app/shared/shared.module.ts | 8 +++++- .../session-main/session-main.component.html | 3 ++- 4 files changed, 61 insertions(+), 2 deletions(-) create mode 100644 src/app/shared/pipe/duration.pipe.ts create mode 100644 src/app/shared/pipe/size.pipe.ts diff --git a/src/app/shared/pipe/duration.pipe.ts b/src/app/shared/pipe/duration.pipe.ts new file mode 100644 index 0000000..514c9b1 --- /dev/null +++ b/src/app/shared/pipe/duration.pipe.ts @@ -0,0 +1,27 @@ +import { Pipe, PipeTransform } from "@angular/core"; + +@Pipe({ + name:"duration" +}) + +export class DurationPipe implements PipeTransform { + + transform(value: any, ...args: any[]):string { + if(!value && value !== 0) return ''; + + const remainingSeconds = Math.floor(value % 60); + const minutes = Math.floor((value % 3600) / 60); + const hours = Math.floor(value/3600); + + const hourString = hours > 0 ? `${hours}h` : '' + const minuteString = minutes > 0 ? `${minutes}min` : '' + const secondString = `${remainingSeconds}s` + + if (hours > 0) { + return `${hourString}, ${minuteString || '0 min'} ${secondString && `: ${secondString}`}` + } else if (!hours && minutes > 0) { + return `${minuteString} ${secondString && `: ${secondString}`}` + } + return secondString; + } +} \ No newline at end of file diff --git a/src/app/shared/pipe/size.pipe.ts b/src/app/shared/pipe/size.pipe.ts new file mode 100644 index 0000000..e8f6009 --- /dev/null +++ b/src/app/shared/pipe/size.pipe.ts @@ -0,0 +1,25 @@ +import { Pipe, PipeTransform } from "@angular/core"; + +@Pipe({ + name:"size" +}) + +export class SizePipe implements PipeTransform { + + transform(value: any, ...args: any[]):string { + if(!value) return ''; + if(value < 1024){ + return `${value}octets`; + } + const units= ['ko','Mo' ]; + let size = value / 1024; + let ui = 0; + + while( size>= 1024 && ui < units.length -1){ + size /= 1024; + ui++; + } + + return `${size.toFixed(2)} ${units[ui]}`; + } +} \ No newline at end of file diff --git a/src/app/shared/shared.module.ts b/src/app/shared/shared.module.ts index 5d9fe7f..edc2afd 100644 --- a/src/app/shared/shared.module.ts +++ b/src/app/shared/shared.module.ts @@ -7,6 +7,8 @@ import { AdvancedFilterTriggerComponent } from './components/stats/advanced-filt import { AdvancedFilterRecapComponent } from './components/stats/advanced-filter/advanced-filter-recap/advanced-filter-recap.component'; import { AdvancedFilterComponent } from './components/stats/advanced-filter/advanced-filter-modal/advanced-filter-modal.component'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { DurationPipe } from './pipe/duration.pipe'; +import { SizePipe } from './pipe/size.pipe'; @NgModule({ imports: [ @@ -20,13 +22,17 @@ import { FormsModule, ReactiveFormsModule } from '@angular/forms'; AdvancedFilterComponent, AdvancedFilterRecapComponent, AdvancedFilterTriggerComponent, - FilterRowPipe + FilterRowPipe, + DurationPipe, + SizePipe ], exports: [ HeaderPageComponent, AdvancedFilterComponent, AdvancedFilterRecapComponent, AdvancedFilterTriggerComponent, + DurationPipe, + SizePipe ] }) export class SharedModule { } diff --git a/src/app/views/session-main/session-main.component.html b/src/app/views/session-main/session-main.component.html index acd7375..43aa8e8 100644 --- a/src/app/views/session-main/session-main.component.html +++ b/src/app/views/session-main/session-main.component.html @@ -97,7 +97,8 @@
From 8ae09c4e25e581273f192ad162d6e22d700cdb72 Mon Sep 17 00:00:00 2001 From: fufuu Date: Thu, 11 Jul 2024 14:24:01 +0200 Subject: [PATCH 029/126] nouvelle modelisation --- src/app/app.module.ts | 2 +- src/app/shared/model/v3/trace.model.ts | 5 +- src/app/shared/services/trace.service.ts | 42 +++--- .../db-request-detail.component.ts | 121 ++++++++---------- .../session-api/session-api.component.ts | 3 +- .../request-database-table.component.html | 6 +- .../request-database-table.component.ts | 3 +- .../request-rest-table.component.ts | 1 - .../request-timeline.component.ts | 1 - .../session-detail.component.html | 6 +- .../session-detail.component.ts | 15 ++- .../session-main/session-main.component.ts | 3 +- src/app/views/tree/tree.component.ts | 2 +- 13 files changed, 101 insertions(+), 109 deletions(-) diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 0862832..040e0d3 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -45,7 +45,7 @@ const routes: Route[] = [ title: 'Liste des Sessions' }, { - path: ':type/:id/db/:dbid', + path: ':type/:id/database/:dbid', component: DbRequestDetailComponent, title: 'Detail de la requête SQL' }, diff --git a/src/app/shared/model/v3/trace.model.ts b/src/app/shared/model/v3/trace.model.ts index de9c10d..76896a8 100644 --- a/src/app/shared/model/v3/trace.model.ts +++ b/src/app/shared/model/v3/trace.model.ts @@ -62,6 +62,9 @@ export interface DatabaseRequest extends SessionStage { productVersion: string; actions: Array; commands: Array; + + idRequest: number; + completed: boolean; } export interface FtpRequest extends SessionStage { @@ -94,7 +97,7 @@ export interface NamingRequest extends SessionStage { } export interface DatabaseRequestStage extends RequestStage { - count: Array; + count?: Array; } export interface FtpRequestStage extends RequestStage { diff --git a/src/app/shared/services/trace.service.ts b/src/app/shared/services/trace.service.ts index 8c02e1e..27fd7ec 100644 --- a/src/app/shared/services/trace.service.ts +++ b/src/app/shared/services/trace.service.ts @@ -1,7 +1,7 @@ import { HttpClient, HttpErrorResponse } from "@angular/common/http"; import { Injectable } from "@angular/core"; import { Observable, catchError, throwError } from "rxjs"; -import { DatabaseRequest, InstanceEnvironment, InstanceRestSession, LocalRequest, RestRequest, RestSession } from "../model/v3/trace.model"; +import { DatabaseRequest, DatabaseRequestStage, InstanceEnvironment, InstanceMainSession, InstanceRestSession, LocalRequest, RestRequest, RestSession } from "../model/v3/trace.model"; @Injectable({ providedIn: 'root' }) export class TraceService { @@ -11,32 +11,28 @@ export class TraceService { constructor(private http: HttpClient) { } - getIncomingRequestByCriteria(params: any) { - return this.http.get(this.INCOMING_REQUEST_URL, { params: params }); + getRestSessions(params: any): Observable> { + return this.http.get>(`${localStorage.getItem('server')}/v3/trace/session/rest`, { params: params }); } - getIncomingRequestById(id: string) { - return this.http.get(`${this.INCOMING_REQUEST_URL}/${id}`); + getRestSession(id: string) { + return this.http.get(`${localStorage.getItem('server')}/v3/trace/session/rest/${id}`); } - getMainRequestByCriteria(params: any) { - return this.http.get(this.MAIN_REQUEST_URL, { params: params }); + getMainSessions(params: any): Observable> { + return this.http.get>(`${localStorage.getItem('server')}/v3/trace/session/main`, { params: params }); } - getMainRequestById(id: string) { - return this.http.get(`${this.MAIN_REQUEST_URL}/${id}`); + getMainSession(id: string) { + return this.http.get(`${localStorage.getItem('server')}/v3/trace/session/main/${id}`); } - getTreeRequestById(id: string) { - return this.http.get(`${this.INCOMING_REQUEST_URL}/${id}/tree`); + getTreeRequest(id: string) { + return this.http.get(`${localStorage.getItem('server')}/v3/trace/session/rest/${id}/tree`); } - getTreeMainById(id: string) { - return this.http.get(`${this.MAIN_REQUEST_URL}/${id}/tree`); - } - - getDbRequestById(id: number){ - return this.http.get(`${localStorage.getItem('server')}/trace/session/db/${id}`); + getTreeMain(id: string) { + return this.http.get(`${localStorage.getItem('server')}/v3/trace/session/main/${id}/tree`); } getSessionParentByChildId(id: string){ @@ -47,10 +43,18 @@ export class TraceService { return this.http.get>(`${localStorage.getItem('server')}/v3/trace/session/${id}/request/rest`); } - getDatabaseRequests(id: string): Observable> { - return this.http.get>(`${localStorage.getItem('server')}/v3/trace/session/${id}/request/database`); + getDatabaseRequests(idSession: string): Observable>; + getDatabaseRequests(idSession: string, idDatabase: number): Observable; + getDatabaseRequests(idSession: string, idDatabase?: number): Observable { + if(idDatabase) + return this.http.get(`${localStorage.getItem('server')}/v3/trace/session/${idSession}/request/database/${idDatabase}`); + return this.http.get(`${localStorage.getItem('server')}/v3/trace/session/${idSession}/request/database`); } + getDatabaseRequestStages(idSession: string, idDatabase: number): Observable> { + return this.http.get>(`${localStorage.getItem('server')}/v3/trace/session/${idSession}/request/database/${idDatabase}/stage`); + }; + getLocalRequests(id: string): Observable> { return this.http.get>(`${localStorage.getItem('server')}/v3/trace/session/${id}/request/local`); } diff --git a/src/app/views/db-request-detail/db-request-detail.component.ts b/src/app/views/db-request-detail/db-request-detail.component.ts index cd8c56b..690092f 100644 --- a/src/app/views/db-request-detail/db-request-detail.component.ts +++ b/src/app/views/db-request-detail/db-request-detail.component.ts @@ -1,7 +1,7 @@ -import { Component, ElementRef,NgZone, OnDestroy, ViewChild } from '@angular/core'; +import { Component, ElementRef, NgZone, OnDestroy, ViewChild } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; -import { combineLatest } from "rxjs"; +import { combineLatest, forkJoin } from "rxjs"; import { Timeline } from 'vis-timeline'; import { DatabaseAction } from 'src/app/shared/model/trace.model'; import { Utils } from 'src/app/shared/util'; @@ -9,14 +9,7 @@ import { DatePipe, Location } from '@angular/common'; import { TraceService } from 'src/app/shared/services/trace.service'; import { application } from 'src/environments/environment'; import { EnvRouter } from '../session-detail/session-detail.component'; - - -export interface UserData { - id: string; - name: string; - progress: string; - fruit: string; -} +import { DatabaseRequest, DatabaseRequestStage } from 'src/app/shared/model/v3/trace.model'; @Component({ templateUrl: './db-request-detail.component.html', @@ -25,13 +18,13 @@ export interface UserData { }) export class DbRequestDetailComponent implements OnDestroy { utils: Utils = new Utils; - selectedQuery: any; + selectedQuery: DatabaseRequest; dbQueryId: number; dbQueryParentId: string; dbQueryParentType: string; isComplete: boolean = true; isLoading: boolean = false; - paramsSubscription: any; + paramsSubscription: any; timeLine: any; env: any; pipe = new DatePipe('fr-FR') @@ -40,10 +33,9 @@ export class DbRequestDetailComponent implements OnDestroy { constructor(private _activatedRoute: ActivatedRoute, private _traceService: TraceService, - private zone: NgZone, private _router: EnvRouter, private _location: Location) { - this.paramsSubscription = combineLatest([ + this.paramsSubscription = combineLatest([ this._activatedRoute.params, this._activatedRoute.queryParams ]).subscribe({ @@ -53,25 +45,23 @@ export class DbRequestDetailComponent implements OnDestroy { this.dbQueryParentType = params.type; this.env = queryParams.env || application.default_env; this._location.replaceState(`${this._router.url.split('?')[0]}?env=${this.env}`) - this.getDbRequestById(this.dbQueryId); + this.getDbRequestById(); } - }); - } - - - - + }); + } - getDbRequestById(id: number) { + getDbRequestById() { this.isLoading = true; - this._traceService.getDbRequestById(id).subscribe({ - next: (d: any) => { - if (d) { - this.selectedQuery = d; + forkJoin({ + query: this._traceService.getDatabaseRequests(this.dbQueryParentId, this.dbQueryId), + stages: this._traceService.getDatabaseRequestStages(this.dbQueryParentId, this.dbQueryId) + }).subscribe({ + next: res => { + if (res) { + this.selectedQuery = res.query; + this.selectedQuery.actions = res.stages; //this.groupQueriesBySchema(); // this.configDbactions(this.selectedQuery) - - this.visjs(); this.isLoading = false; this.isComplete = true; @@ -88,34 +78,33 @@ export class DbRequestDetailComponent implements OnDestroy { } visjs() { - let timeline_end = +(this.selectedQuery.end * 1000) - let timeline_start = +this.selectedQuery.start * 1000 - let dataArray = this.selectedQuery.actions; - this.sortInnerArrayByDate(dataArray); - - let g = new Set() - dataArray.forEach((c: any) =>{ - g.add(c.type); - }); + let timeline_end = +this.selectedQuery.end * 1000; + let timeline_start = +this.selectedQuery.start * 1000; + let actions = this.selectedQuery.actions; + this.sortInnerArrayByDate(actions) + let g = new Set(); + actions.forEach((c: DatabaseRequestStage) => { + g.add(c.name); + }); let groups = Array.from(g).map((g: string) => ({ id: g, content: g })) - - dataArray = dataArray.map((c: any, i: number) => { - let e:any = { - group: c.type, - // content: "c.type", - start: Math.trunc(c.start * 1000), - end: Math.trunc(c.end * 1000), - title: `${this.pipe.transform(new Date(c.start * 1000), 'HH:mm:ss.SSS')} - ${this.pipe.transform(new Date(c.end * 1000), 'HH:mm:ss.SSS')}
-

${c.type}${c?.count? '('+c?.count+')': ''}: ${this.getElapsedTime(c.end, c.start).toFixed(3)}s

`, + + let dataArray = actions.map((c: DatabaseRequestStage, i: number) => { + let e: any = { + group: c.name, + // content: "c.type", + start: Math.trunc(+c.start * 1000), + end: Math.trunc(+c.end * 1000), + title: `${this.pipe.transform(new Date(+c.start * 1000), 'HH:mm:ss.SSS')} - ${this.pipe.transform(new Date(+c.end * 1000), 'HH:mm:ss.SSS')}
+

${c.name}${c?.count ? '(' + c?.count + ')' : ''}: ${this.getElapsedTime(+c.end, +c.start).toFixed(3)}s

`, //className : 'vis-dot', } e.type = e.start == e.end ? 'point' : 'range' - if(c?.exception?.message || c?.exception?.classname){ - e.className ='bdd-failed'; + if (c?.exception?.message || c?.exception?.type) { + e.className = 'bdd-failed'; e.title += `
${c?.exception?.message}
`; // TODO : fix css on tooltip } - + return e; }) @@ -126,9 +115,9 @@ export class DbRequestDetailComponent implements OnDestroy { this.timeLine = new Timeline(this.timelineContainer.nativeElement, dataArray, groups, { //stack:false, - // min: timeline_start, - // max: timeline_end, - selectable : false, + // min: timeline_start, + // max: timeline_end, + selectable: false, clickToUse: true, tooltip: { followMouse: true @@ -139,7 +128,7 @@ export class DbRequestDetailComponent implements OnDestroy { }); } - getElapsedTime(end: number, start: number,) { + getElapsedTime(end: number, start: number) { // return (new Date(end * 1000).getTime() - new Date(start * 1000).getTime()) / 1000 return end - start; } @@ -151,7 +140,7 @@ export class DbRequestDetailComponent implements OnDestroy { statusBorder(status: any) { return Utils.statusBorder(status); } - + getStateColorBool() { return Utils.getStateColorBool(this.selectedQuery?.completed) } @@ -167,13 +156,13 @@ export class DbRequestDetailComponent implements OnDestroy { } - configDbactions(query: any) { + configDbactions(query: DatabaseRequest) { query.actions.forEach((db: any, i: number) => { if (query.actions[i + 1]) { - let diffElapsed = new Date(db.end * 1000).getTime() - new Date(query.actions[i + 1].start * 1000).getTime(); + let diffElapsed = new Date(db.end * 1000).getTime() - new Date(+query.actions[i + 1].start * 1000).getTime(); if (diffElapsed != 0) { - query.actions.splice(i + 1, 0, { 'type': ' ', 'exception': { 'classname': null, 'message': null }, 'start': db.end, 'end': query.actions[i + 1].start }) + query.actions.splice(i + 1, 0, { 'name': ' ', 'exception': { 'type': null, 'message': null }, 'start': db.end, 'end': query.actions[i + 1].start }) } } }); @@ -184,17 +173,17 @@ export class DbRequestDetailComponent implements OnDestroy { } - navigate(event:MouseEvent,targetType: string,extraParam?:string) { + navigate(event: MouseEvent, targetType: string, extraParam?: string) { let params: any[] = []; switch (targetType) { case "parent": params.push('session', this.dbQueryParentType, this.dbQueryParentId) } - if(event.ctrlKey){ - this._router.open(`#/${params.join('/')}`,'_blank') - }else { + if (event.ctrlKey) { + this._router.open(`#/${params.join('/')}`, '_blank') + } else { this._router.navigate(params, { - queryParams: { env: this.env } + queryParams: { env: this.env } }); } } @@ -210,8 +199,8 @@ export class DbRequestDetailComponent implements OnDestroy { }); } - isQueryCompleted(query: any): boolean { - return query.actions.every((a: any) => !a?.exception?.classname && !a?.exception?.message); + isQueryCompleted(query: DatabaseRequest): boolean { + return query.actions.every((a: DatabaseRequestStage) => !a?.exception?.type && !a?.exception?.message); } getCommand(commands: string[]): string { @@ -224,8 +213,8 @@ export class DbRequestDetailComponent implements OnDestroy { return command; } - getException(actions: DatabaseAction[]): DatabaseAction{ - return actions.filter(a => a?.exception?.message || a?.exception?.classname)[0] + getException(actions: DatabaseRequestStage[]): DatabaseRequestStage { + return actions.filter(a => a?.exception?.message || a?.exception?.type)[0] } ngOnDestroy() { diff --git a/src/app/views/session-api/session-api.component.ts b/src/app/views/session-api/session-api.component.ts index 0a086a4..0cb3136 100644 --- a/src/app/views/session-api/session-api.component.ts +++ b/src/app/views/session-api/session-api.component.ts @@ -6,7 +6,6 @@ import { MatTableDataSource } from '@angular/material/table'; import { Location } from '@angular/common'; import { ActivatedRoute, Params } from '@angular/router'; import { BehaviorSubject, Observable, Subscription, finalize } from 'rxjs'; -import { IncomingRequest } from 'src/app/shared/model/trace.model'; import { Utils } from 'src/app/shared/util'; import { JQueryService } from 'src/app/shared/services/jquery.service'; import { TraceService } from 'src/app/shared/services/trace.service'; @@ -128,7 +127,7 @@ export class SessionApiComponent implements OnInit, OnDestroy { this.isLoading = true; this.dataSource = new MatTableDataSource([]); - this.subscriptions.push(this._traceService.getIncomingRequestByCriteria(params) + this.subscriptions.push(this._traceService.getRestSessions(params) .subscribe({ next: (d: InstanceRestSession[]) => { if (d) { diff --git a/src/app/views/session-detail/components/request-database-table/request-database-table.component.html b/src/app/views/session-detail/components/request-database-table/request-database-table.component.html index 8e0e8ad..5a5761c 100644 --- a/src/app/views/session-detail/components/request-database-table/request-database-table.component.html +++ b/src/app/views/session-detail/components/request-database-table/request-database-table.component.html @@ -2,7 +2,7 @@
= new MatTableDataSource(); + displayedColumns: string[] = ['status', 'host', 'schema', 'start', 'duree']; + dataSource: MatTableDataSource = new MatTableDataSource(); @ViewChild('paginator', {static: true}) paginator: MatPaginator; @ViewChild('sort', {static: true}) sort: MatSort; - @Input() set requests(requests: OutcomingQuery[]) { + @Input() set requests(requests: DatabaseRequest[]) { if(requests) { this.dataSource = new MatTableDataSource(requests); this.dataSource.paginator = this.paginator; diff --git a/src/app/views/session-detail/components/request-rest-table/request-rest-table.component.html b/src/app/views/session-detail/components/request-rest-table/request-rest-table.component.html index 0028bf5..04936cf 100644 --- a/src/app/views/session-detail/components/request-rest-table/request-rest-table.component.html +++ b/src/app/views/session-detail/components/request-rest-table/request-rest-table.component.html @@ -29,7 +29,7 @@ matSortActive="date_debut" matSortDirection="desc"> - + = new MatTableDataSource(); + displayedColumns: string[] = ['status', 'host', 'path', 'start', 'duree']; + dataSource: MatTableDataSource = new MatTableDataSource(); filterTable = new Map(); @ViewChild('paginator', {static: true}) paginator: MatPaginator; @ViewChild('sort', {static: true}) sort: MatSort; - @Input() set requests(requests: OutcomingRequest[]) { + @Input() set requests(requests: RestRequest[]) { if(requests) { this.dataSource = new MatTableDataSource(requests); this.dataSource.paginator = this.paginator; @@ -67,7 +68,7 @@ const sortingDataAccessor = (row: any, columnName: string) => { return columnValue; } -const filterPredicate = (data: OutcomingRequest, filter: string) => { +const filterPredicate = (data: RestRequest, filter: string) => { var map: Map = new Map(JSON.parse(filter)); let isMatch = true; for (let [key, value] of map.entries()) { diff --git a/src/app/views/session-detail/components/request-timeline/request-timeline.component.ts b/src/app/views/session-detail/components/request-timeline/request-timeline.component.ts index 3b67a3b..95945bc 100644 --- a/src/app/views/session-detail/components/request-timeline/request-timeline.component.ts +++ b/src/app/views/session-detail/components/request-timeline/request-timeline.component.ts @@ -3,6 +3,7 @@ import { Component, ElementRef, Input, OnInit, ViewChild, inject } from "@angula import { OutcomingQuery, OutcomingRequest, Request, RunnableStage } from "src/app/shared/model/trace.model"; import { Timeline } from "vis-timeline"; import { EnvRouter } from "../../session-detail.component"; +import { DatabaseRequest, LocalRequest, RestRequest } from "src/app/shared/model/v3/trace.model"; @Component({ selector: 'request-timeline-table', @@ -21,9 +22,9 @@ export class RequestTimelineComponent { if (request) { let timeline_end = +request.end * 1000 let timeline_start = +request.start * 1000 - let dataArray: any = [...request.requests, - ...request.queries, - ...request.stages.map((s: any) => ({ ...s, isStage: true }))]; + let dataArray: any = [...request.requests, + ...request.queries, + ...request.stages.map((s: any) => ({ ...s, isStage: true }))]; dataArray.splice(0, 0, { ...request, isStage: true }) this.sortInnerArrayByDate(dataArray); @@ -31,7 +32,7 @@ export class RequestTimelineComponent { let data: any; let groups: any; let isWebapp = false, title = ''; - if (request.launchMode != null && request.launchMode === "WEBAPP") { + if (request.launchMode != null && request.launchMode === "VIEW") { groups = [{ id: 0, content: request?.application?.re }]; title = 'path'; isWebapp = true; @@ -88,7 +89,7 @@ export class RequestTimelineComponent { this.timeline.on('select', function (props: any) { let id = props.items[0]; if (isNaN(+id)) { - that._router.navigate(['/session', 'api', id]); + that._router.navigate(['/session', 'rest', id]); } }); diff --git a/src/app/views/session-detail/session-detail.component.html b/src/app/views/session-detail/session-detail.component.html index bab65d7..0d93262 100644 --- a/src/app/views/session-detail/session-detail.component.html +++ b/src/app/views/session-detail/session-detail.component.html @@ -5,13 +5,13 @@ settings_suggest - {{selectedSessionType =='api' ? (selectedSession?.name|| 'N/A') + {{selectedSessionType =='rest' ? (selectedSession?.name|| 'N/A') : '[' - + selectedSession?.launchMode + '] ' + selectedSession?.name || 'N/A'}} + + selectedSession?.type + '] ' + selectedSession?.name || 'N/A'}}
Session Type
- {{row.name || 'N/A'}} + {{row.type || 'N/A'}}
Nom +
+ {{row.name || 'N/A'}} +
+
{{ utils.convertSeconds(getElapsedTime(row.end,row.start)) }} + matTooltipClass="mat-tooltip"> + {{ getElapsedTime(row.end,row.start) | duration}}
- + @@ -48,7 +48,7 @@ + (click)="selectedQuery($event, row.idRequest)">
{{getCommand(element.commands)}}
- {{element["schema"] || 'N/A'}} + {{element["name"] || 'N/A'}}
settings_suggest {{selectedSessionType =='api' ? (selectedSession?.name|| 'N/A') @@ -97,8 +97,8 @@ matTooltip="Statistique Base de donnée"> {{ item.key }} -
{{ item.value[0].databaseName }} v.{{ - item.value[0].databaseVersion}}
+
{{ item.value[0].productName }} v.{{ + item.value[0].productVersion}}
diff --git a/src/app/views/session-detail/session-detail.component.ts b/src/app/views/session-detail/session-detail.component.ts index f5fdc90..42c97ca 100644 --- a/src/app/views/session-detail/session-detail.component.ts +++ b/src/app/views/session-detail/session-detail.component.ts @@ -44,10 +44,10 @@ export class SessionDetailComponent implements OnDestroy { getSessionById(id: string) { this.isLoading = true; - var traceService = (this.selectedSessionType == "main" ? this._traceService.getMainRequestById(id) : this._traceService.getIncomingRequestById(id)); + var traceService = (this.selectedSessionType == "main" ? this._traceService.getMainSession(id) : this._traceService.getRestSession(id)); traceService .pipe( - switchMap((s: InstanceRestSession | InstanceRestSession) => { + switchMap((s: InstanceMainSession | InstanceRestSession) => { return forkJoin({ session: of(s), instance: this._traceService.getInstance(s.instanceId), @@ -93,11 +93,12 @@ export class SessionDetailComponent implements OnDestroy { } selectedQuery(event: { event: MouseEvent, row: any }) { // TODO finish this + console.log(event); if (event.row) { if (event.event.ctrlKey) { - this._router.open(`#/session/${this.selectedSessionType}/${this.selectedSession.id}/db/${event.row}`, '_blank',) + this._router.open(`#/session/${this.selectedSessionType}/${this.selectedSession.id}/database/${event.row}`, '_blank',) } else { - this._router.navigate(['/session', this.selectedSessionType, this.selectedSession.id, 'db', event.row], { + this._router.navigate(['/session', this.selectedSessionType, this.selectedSession.id, 'database', event.row], { queryParams: { env: this.instance.env } }); } @@ -123,11 +124,11 @@ export class SessionDetailComponent implements OnDestroy { groupQueriesBySchema() { if (this.selectedSession.queries) { this.queryBySchema = this.selectedSession.queries.reduce((acc: any, item) => { - if (!acc[item.schema]) { - acc[item.schema] = [] + if (!acc[item.name]) { + acc[item.name] = [] } - acc[item.schema].push(item); + acc[item.name].push(item); return acc; }, []); } diff --git a/src/app/views/session-main/session-main.component.ts b/src/app/views/session-main/session-main.component.ts index 96fe3ba..f8a932e 100644 --- a/src/app/views/session-main/session-main.component.ts +++ b/src/app/views/session-main/session-main.component.ts @@ -6,7 +6,6 @@ import { MatTableDataSource } from '@angular/material/table'; import { ActivatedRoute, Params, Router } from '@angular/router'; import { BehaviorSubject, Subscription } from 'rxjs'; import { Location } from '@angular/common'; -import { MainRequest } from 'src/app/shared/model/trace.model'; import { Utils } from 'src/app/shared/util'; import { TraceService } from 'src/app/shared/services/trace.service'; import { EnvRouter } from '../session-detail/session-detail.component'; @@ -89,7 +88,7 @@ export class SessionMainComponent implements OnInit, OnDestroy { this.isLoading = true; this.dataSource.data = []; - this.subscription = this._traceService.getMainRequestByCriteria(params).subscribe((d: InstanceMainSession[]) => { + this.subscription = this._traceService.getMainSessions(params).subscribe((d: InstanceMainSession[]) => { if (d) { this.dataSource = new MatTableDataSource(d); this.dataSource.paginator = this.paginator; diff --git a/src/app/views/tree/tree.component.ts b/src/app/views/tree/tree.component.ts index cb13ab7..fe764d6 100644 --- a/src/app/views/tree/tree.component.ts +++ b/src/app/views/tree/tree.component.ts @@ -53,7 +53,7 @@ export class TreeComponent implements OnDestroy { this.env = v.queryParams.env || application.default_env; this._location.replaceState(`${this._router.url.split('?')[0]}?env=${this.env}`) this.isLoading = true; - this._traceService.getTreeRequestById(this.id).pipe(finalize(() => this.isLoading = false)).subscribe(d => { + this._traceService.getTreeRequest(this.id).pipe(finalize(() => this.isLoading = false)).subscribe(d => { this.exchange = {}; this.exchange['remoteTrace'] = d; From 2cb3709936f51ca21b993f32e1aabe78d2cfdaf3 Mon Sep 17 00:00:00 2001 From: YoussefDahi Date: Fri, 12 Jul 2024 14:20:44 +0200 Subject: [PATCH 030/126] adaptation de la tree au nouveau model / not DONE --- src/app/views/tree/tree.component.ts | 91 ++++++++++++++-------------- 1 file changed, 46 insertions(+), 45 deletions(-) diff --git a/src/app/views/tree/tree.component.ts b/src/app/views/tree/tree.component.ts index fe764d6..5e0822c 100644 --- a/src/app/views/tree/tree.component.ts +++ b/src/app/views/tree/tree.component.ts @@ -116,10 +116,9 @@ export class TreeComponent implements OnDestroy { this.graph.getLabel = function (cell: any) { if (cell?.isVertex() && cell.value && typeof cell.value === 'object') { if (cell.value.hasOwnProperty('data')) { - return cell.value.data[0].remoteTrace.application.name; + return cell.value.data[0].remoteTrace.appName; // } - - return cell.value.remoteTrace.application.name; + return cell.value.remoteTrace.appName; } return mx.mxGraph.prototype.getLabel.apply(this, arguments); } @@ -162,7 +161,7 @@ export class TreeComponent implements OnDestroy { - // listners + // listners this.graph.addListener(mx.mxEvent.DOUBLE_CLICK, function (sender: any, evt: any) { @@ -182,24 +181,24 @@ export class TreeComponent implements OnDestroy { cellCopy.data.forEach((s: any) => { - if (!cell.target.value.data[0].hasOwnProperty('schema')) { + if (!cell.target.value.data[0].hasOwnProperty('name')) { - s.remoteTrace.requests = s.remoteTrace.requests.filter((r: any) => { if (r) return (r?.remoteTrace?.application?.name == cell.target.value.data[0].remoteTrace.application.name || r?.remoteTrace?.name == cell.target.value.data[0].remoteTrace.name) }) - s.remoteTrace.queries = [] + s.remoteTrace.restRequests = s.remoteTrace.restRequests.filter((r: any) => { if (r) return (r?.remoteTrace?.application?.name == cell.target.value.data[0].appName || r?.remoteTrace?.name == cell.target.value.data[0].remoteTrace.name) }) + s.remoteTrace.databaseRequests = [] } else { // to be changed - if (s.remoteTrace.queries.length >= 1) { - s.remoteTrace.queries = cell.target.value.data + if (s.remoteTrace.databaseRequests.length >= 1) { + s.remoteTrace.databaseRequests = cell.target.value.data } else { - s.remoteTrace.queries = []; + s.remoteTrace.databaseRequests = []; } - s.remoteTrace.requests = [] + s.remoteTrace.restRequests = [] } - if ((s.remoteTrace.queries.length >= 1 || s.remoteTrace.requests.length >= 1)) { - s.remoteTrace.application.oldName = s.remoteTrace.application.name; - s.remoteTrace.application.name = s.remoteTrace.name; - if (s.remoteTrace["@type"] == "api") + if ((s.remoteTrace.databaseRequests.length >= 1 || s.remoteTrace.restRequests.length >= 1)) { + s.remoteTrace.oldName = s.remoteTrace.appName; + s.remoteTrace.appName = s.remoteTrace.name; + if (s.remoteTrace["@type"] == "rest") s.remoteTrace["@type"] = "endpoint" self.selectedExchange = cellCopy self.setnode(s, null, self.detailed) @@ -246,7 +245,7 @@ export class TreeComponent implements OnDestroy { } // console.log(cellState.cell) } - + } else { // this.selectedExchange = undefined; }*/ @@ -272,6 +271,7 @@ export class TreeComponent implements OnDestroy { } else value = cell.target.value + switch (value.remoteTrace['@type']) { case 'main': break; @@ -279,16 +279,16 @@ export class TreeComponent implements OnDestroy { case 'db': modal += ` ${value.completed ? "réussi" : "échoué"}
` modal += `Thread : ${value.threadName || 'N/A'}
` - modal += `Schema : ${value.schema || 'N/A'}
` + modal += `name : ${value.name || 'N/A'}
` modal += `Hôte : ${value.host || 'N/A'}
` /*value.actions.forEach((action: any) => { if (action.exception) { modal += `${action.exception.classname || ''} ${action.exception.message || ''}` } - });*/ // removed this since we dont get the actions from the back + });*/ // removed this since we dont get the actions from the back break; - case 'api': + case 'rest': modal += ` ${value.remoteTrace.status}     ${value.remoteTrace.path}
` modal += `Thread : ${value.threadName || 'N/A'}
` modal += `Latence: ${Utils.getElapsedTime(value.remoteTrace?.start, value.start)}s
`; @@ -339,10 +339,9 @@ export class TreeComponent implements OnDestroy { let edgeLabel = '', edgeStyle = '', vertexStyle = '', bdd: any, req; //setting querries nodes - if (ex.remoteTrace.queries) { + if (ex.remoteTrace.databaseRequests) { if (detailed) { - - ex.remoteTrace.queries.forEach((q: any, i: any) => { + ex.remoteTrace.databaseRequests.forEach((q: any, i: any) => { vertexIcon = this.getVertexIconType(q) bdd = this.graph.insertVertex(this.parent, null, { data: [q] }, 0, 0, 80, 30, "shape=image;image=assets/mxgraph/" + vertexIcon + ".drawio.svg;"); edgeStyle = this.checkQueryStatus(q.completed); @@ -350,7 +349,8 @@ export class TreeComponent implements OnDestroy { this.graph.insertEdge(this.parent, null, edgeLabel, exParent, bdd, edgeStyle) }); } else { - let groupedItems = this.groupByProperty(ex.remoteTrace.queries, 'schema'); + + let groupedItems = this.groupByProperty(ex.remoteTrace.databaseRequests, 'name'); Object.keys(groupedItems).forEach((i) => { vertexIcon = this.getVertexIconType(groupedItems[i].data[0]) bdd = this.graph.insertVertex(this.parent, null, groupedItems[i], 0, 0, 80, 30, "shape=image;image=assets/mxgraph/" + vertexIcon + ".drawio.svg;") @@ -372,29 +372,29 @@ export class TreeComponent implements OnDestroy { } //setting child requests - if (ex.remoteTrace.requests) { + if (ex.remoteTrace.restRequests) { if (detailed) { - ex.remoteTrace.requests.forEach((r: any) => { + ex.remoteTrace.restRequests.forEach((r: any) => { edgeStyle = ""; if (r.remoteTrace.unknown) { r.remoteTrace = this.setUnknowHost(r); vertexStyle = r.remoteTrace.vertexStyle; } vertexIcon = this.getVertexIconType(r) - r.remoteTrace.application.name = r.remoteTrace.name; + r.appName = r.remoteTrace.name; req = this.graph.insertVertex(this.parent, null, { data: [r] }, 0, 0, 80, 30, 'shape=image;image=assets/mxgraph/api.drawio.svg;fillColor=#81D060;') edgeStyle += `strokeColor=${Utils.getStateColor(r.status)};`; edgeLabel = this.getElapsedTime(r.end, r.start) + "s" this.graph.insertEdge(this.parent, null, edgeLabel, exParent, req, edgeStyle) }) } else { - let groupedItems = this.groupRequestsByProperty(ex.remoteTrace.requests); + let groupedItems = this.groupRequestsByProperty(ex.remoteTrace.restRequests); if (groupedItems) { Object.keys(groupedItems).forEach((i) => { req = JSON.parse(JSON.stringify(groupedItems[i])); req.remoteTrace.succesCalls = groupedItems[i].succesCalls; - req.remoteTrace.parentCallCount = groupedItems[i].data.length; // number of calls + req.remoteTrace.parentCallCount = groupedItems[i].data.length; // number of calls req.remoteTrace.isRequest = true; this.setnode(req, exParent, detailed) }); @@ -426,20 +426,16 @@ export class TreeComponent implements OnDestroy { groupByProperty(array: any, property: string) { let groupedItems = array.reduce((acc: any, item: any) => { - if (!acc[item[property]]) { acc[item[property]] = {} acc[item[property]].succesCalls = 0 acc[item[property]].data = [] - acc[item[property]].remoteTrace = { "application": { "name": item[property], "@type": 'db' } }; } if (item.completed) { acc[item[property]].succesCalls += 1 } - - item.remoteTrace = {} - item.remoteTrace = { "application": { "name": item[property] }, "@type": 'db' }; + item.remoteTrace = { "@type": 'db','appName': item[property] }; acc[item[property]].data.push(item); return acc; @@ -451,7 +447,8 @@ export class TreeComponent implements OnDestroy { let groupedItems = array.reduce((acc: any, item: any) => { let property; if (item.remoteTrace) { - property = item.remoteTrace.application.name; + property = item.remoteTrace.appName; + } else { property = item.host item['remoteTrace'] = this.setUnknowHost(item); @@ -460,9 +457,9 @@ export class TreeComponent implements OnDestroy { acc[property] = {}; acc[property].data = []; acc[property].succesCalls = 0; - acc[property].remoteTrace = { "application": { "name": item[property] } }; - acc[property].remoteTrace.requests = []; - acc[property].remoteTrace.queries = []; + acc[property].remoteTrace = { "application": { "name": property } }; // maybe revert + acc[property].remoteTrace.restRequests = []; + acc[property].remoteTrace.databaseRequests = []; } if (item.status >= 200 && item.status < 300) @@ -471,8 +468,12 @@ export class TreeComponent implements OnDestroy { acc[property].data.push(item) if (item.remoteTrace['@type'] != "unknown") { - acc[property].remoteTrace?.requests.push(...item.remoteTrace.requests); - acc[property].remoteTrace?.queries.push(...item.remoteTrace.queries); + if(item.remoteTrace.restRequests){ + acc[property].remoteTrace?.restRequests.push(...item.remoteTrace.restRequests); + } + if(item.remoteTrace.databaseRequests){ + acc[property].remoteTrace?.databaseRequests.push(...item.remoteTrace?.databaseRequests); + } } return acc; @@ -514,7 +515,7 @@ export class TreeComponent implements OnDestroy { if (this.resizeSubscription) { this.resizeSubscription.unsubscribe(); } - //destroy graph + //destroy graph } checkRequestStatus(status: number): string { @@ -549,7 +550,7 @@ export class TreeComponent implements OnDestroy { } getVertexIconType(exchange: any) { - if (exchange.hasOwnProperty('databaseName')) + if (exchange.hasOwnProperty('productName')) return this.vertexIcons['DATABASE'][exchange.completed]; if (exchange.remoteTrace["@type"] == "main") @@ -609,7 +610,7 @@ export class TreeComponent implements OnDestroy { state = this.graph.view.getState(edge); if (state) { - state.shape.node.getElementsByTagName('path')[0].setAttribute('stroke-width', '4'); // link it to size in size out + state.shape.node.getElementsByTagName('path')[0].setAttribute('stroke-width', '4'); // link it to size in size out state.shape.node.getElementsByTagName('path')[0].setAttribute('stroke', 'lightGray'); if (!edge.style.includes("strokeColor=red;") && !edge.style.includes("strokeColor=orange;")) { state.shape.node.getElementsByTagName('path')[0].removeAttribute('visibility'); @@ -689,7 +690,7 @@ export class TreeComponent implements OnDestroy { let callType = ""; let target = cell.target.value.data[0]; let targetId = ""; - if (!target.hasOwnProperty('schema')) { + if (!target.hasOwnProperty('name')) { if (target.remoteTrace['@type'] == "api") { callType = "request"; @@ -714,7 +715,7 @@ export class TreeComponent implements OnDestroy { if (target.remoteTrace.hasOwnProperty('@type')) { if (target.remoteTrace['@type'] == "api") { menu.addItem('Statistique ', '../src/images/warning.gif', function () { - self._router.navigate(['/dashboard', 'api', target.remoteTrace.application.name]); + self._router.navigate(['/dashboard', 'api', target.appName]); }); } } @@ -742,7 +743,7 @@ export class TreeComponent implements OnDestroy { "404": "MICROSERVICE404", "500": "MICROSERVICE500", },*/ - "api": "MICROSERVICE", + "rest": "MICROSERVICE", "endpoint": "api", "unknown": { From 95b59cd162e41ec5d8150b3ab93e60c46c55b25e Mon Sep 17 00:00:00 2001 From: YoussefDahi Date: Mon, 15 Jul 2024 18:22:21 +0200 Subject: [PATCH 031/126] timeline visualisation fix --- .../request-timeline.component.ts | 155 +++++++++--------- .../session-detail.component.html | 2 +- 2 files changed, 81 insertions(+), 76 deletions(-) diff --git a/src/app/views/session-detail/components/request-timeline/request-timeline.component.ts b/src/app/views/session-detail/components/request-timeline/request-timeline.component.ts index 948921c..64f47fc 100644 --- a/src/app/views/session-detail/components/request-timeline/request-timeline.component.ts +++ b/src/app/views/session-detail/components/request-timeline/request-timeline.component.ts @@ -1,5 +1,5 @@ import { DatePipe } from "@angular/common"; -import { Component, ElementRef, Input, OnInit, ViewChild, inject } from "@angular/core"; +import { Component, ElementRef, Input, OnChanges, OnInit, SimpleChanges, ViewChild, inject } from "@angular/core"; import { Timeline } from "vis-timeline"; import { EnvRouter } from "../../session-detail.component"; import { DatabaseRequest, LocalRequest, RestRequest } from "src/app/shared/model/v3/trace.model"; @@ -9,7 +9,7 @@ import { DatabaseRequest, LocalRequest, RestRequest } from "src/app/shared/model templateUrl: './request-timeline.component.html', styleUrls: ['./request-timeline.component.scss'] }) -export class RequestTimelineComponent { +export class RequestTimelineComponent implements OnChanges { private _router: EnvRouter = inject(EnvRouter); timeline: any; @@ -17,84 +17,89 @@ export class RequestTimelineComponent { @ViewChild('timeline', {static: true}) timelineElement: ElementRef; - @Input() set request(request: any) { - if (request) { - let timeline_end = +request.end * 1000 - let timeline_start = +request.start * 1000 - let dataArray: any = [...request.requests, - ...request.queries, - ...request.stages.map((s: any) => ({ ...s, isStage: true }))]; - dataArray.splice(0, 0, { ...request, isStage: true }) - this.sortInnerArrayByDate(dataArray); + @Input() instance:any; + @Input() request:any; - - let data: any; - let groups: any; - let isWebapp = false, title = ''; - if (request.launchMode != null && request.launchMode === "VIEW") { - groups = [{ id: 0, content: request?.application?.re }]; - title = 'path'; - isWebapp = true; - } else { - groups = new Set(); - dataArray.forEach((c: any, i: number) => { - groups.add(c['threadName']) - }); - title = 'threadName'; - groups = Array.from(groups).map((g: string) => ({ id: g, content: g })) - } - data = dataArray.map((c: any, i: number) => { - let o = { - id: c.hasOwnProperty('schema') ? -i : c.id, - group: isWebapp ? 0 : c.threadName, - content: c.hasOwnProperty('isStage') ? '' : (c.schema || c.host || 'N/A'), - start: c.start * 1000, - end: c.end * 1000, - title: `${this.pipe.transform(new Date(c.start * 1000), 'HH:mm:ss.SSS')} - ${this.pipe.transform(new Date(c.end * 1000), 'HH:mm:ss.SSS')}
-

${c[title]}: ${this.getElapsedTime(c.end, c.start).toFixed(3)}s

`, - className: c.hasOwnProperty('schema') ? "bdd" : !c.hasOwnProperty('isStage') ? "rest" : "", - type: c.hasOwnProperty('isStage') ? 'background' : 'range' - } - if (o.end > timeline_end) { - timeline_end = o.end + ngOnChanges(changes: SimpleChanges): void { + if( changes.instance || changes.request){ + if(this.instance && this.request){ + let timeline_end = +this.request.end * 1000 + let timeline_start = +this.request.start * 1000 + let dataArray: any = [...this.request.requests, + ...this.request.queries, + ...this.request.stages.map((s: any) => ({ ...s, isStage: true }))]; + dataArray.splice(0, 0, { ...this.request, isStage: true }) + this.sortInnerArrayByDate(dataArray); + + + let data: any; + let groups: any; + let isWebapp = false, title = ''; + if (this.request.type != null && this.request.type === "VIEW") { + groups = [{ id: 0, content: this.instance.re }]; + title = 'path'; + isWebapp = true; + } else { + groups = new Set(); + dataArray.forEach((c: any, i: number) => { + groups.add(c['threadName']) + }); + title = 'threadName'; + groups = Array.from(groups).map((g: string) => ({ id: g, content: g })) } - return o; - }) - - - if (this.timeline) { // destroy if exists - this.timeline.destroy(); - } - // Create a Timeline - this.timeline = new Timeline(this.timelineElement.nativeElement, data, groups, { - min: timeline_start, - max: timeline_end, - clickToUse: true, - selectable : false, - tooltip: { - followMouse: true - }, - margin: { - item: { - horizontal: -1 + data = dataArray.map((c: any, i: number) => { + let o = { + id: c.hasOwnProperty('schema') ? -i : c.id, + group: isWebapp ? 0 : c.threadName, + content: c.hasOwnProperty('isStage') ? '' : (c.schema || c.host || 'N/A'), + start: c.start * 1000, + end: c.end * 1000, + title: `${this.pipe.transform(new Date(c.start * 1000), 'HH:mm:ss.SSS')} - ${this.pipe.transform(new Date(c.end * 1000), 'HH:mm:ss.SSS')}
+

${c[title]}: ${this.getElapsedTime(c.end, c.start).toFixed(3)}s

`, + className: c.hasOwnProperty('schema') ? "bdd" : !c.hasOwnProperty('isStage') ? "rest" : "", + type: c.hasOwnProperty('isStage') ? 'background' : 'range' } - }, - order: (a, b) => { - return b.start - a.start // inverser l'ordre + if (o.end > timeline_end) { + timeline_end = o.end + } + return o; + }) + + + if (this.timeline) { // destroy if exists + this.timeline.destroy(); } - }); - - let that = this; - this.timeline.on('select', function (props: any) { - let id = props.items[0]; - if (isNaN(+id)) { - that._router.navigate(['/session', 'rest', id]); + // Create a Timeline + this.timeline = new Timeline(this.timelineElement.nativeElement, data, groups, { + min: timeline_start, + max: timeline_end, + clickToUse: true, + selectable : false, + tooltip: { + followMouse: true + }, + margin: { + item: { + horizontal: -1 + } + }, + order: (a, b) => { + return b.start - a.start // inverser l'ordre + } + }); + + let that = this; + this.timeline.on('select', function (props: any) { + let id = props.items[0]; + if (isNaN(+id)) { + that._router.navigate(['/session', 'rest', id]); + } + }); + + if (timeline_end != +this.request.end * 1000) { + this.timeline.addCustomTime(+this.request.end * 1000, "async"); + this.timeline.setCustomTimeMarker("async", "async"); } - }); - - if (timeline_end != +request.end * 1000) { - this.timeline.addCustomTime(+request.end * 1000, "async"); - this.timeline.setCustomTimeMarker("async", "async"); } } } diff --git a/src/app/views/session-detail/session-detail.component.html b/src/app/views/session-detail/session-detail.component.html index 2a3f95d..8699e5c 100644 --- a/src/app/views/session-detail/session-detail.component.html +++ b/src/app/views/session-detail/session-detail.component.html @@ -157,7 +157,7 @@
- +
Date: Mon, 15 Jul 2024 18:32:13 +0200 Subject: [PATCH 032/126] edit : --- src/app/app.module.ts | 8 +++- .../views/dashboard/dashboard.component.html | 48 +++++++++++++++++++ .../views/dashboard/dashboard.component.scss | 0 .../views/dashboard/dashboard.component.ts | 37 ++++++++++++++ .../db-request-detail.component.ts | 48 +++++++++++++++---- src/app/views/views.module.ts | 4 +- 6 files changed, 132 insertions(+), 13 deletions(-) create mode 100644 src/app/views/dashboard/dashboard.component.html create mode 100644 src/app/views/dashboard/dashboard.component.scss create mode 100644 src/app/views/dashboard/dashboard.component.ts diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 040e0d3..f581833 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -24,6 +24,7 @@ import { StatsAppComponent } from './views/stats-app/stats-app.component'; import { StatsApiComponent } from './views/stats-api/stats-api.component'; import { StatsUserComponent } from './views/stats-user/stats-user.component'; import { DbRequestDetailComponent } from './views/db-request-detail/db-request-detail.component'; +import { DashboardComponent } from './views/dashboard/dashboard.component'; registerLocaleData(localeFr, 'fr-FR'); const routes: Route[] = [ @@ -63,7 +64,10 @@ const routes: Route[] = [ ] }, { - path: 'dashboard', children: [ + path: 'dashboard', + component: DashboardComponent, + title: 'Dashboard', + children: [ { path: 'app/:name', component: StatsAppComponent, @@ -84,7 +88,7 @@ const routes: Route[] = [ component: StatsDatabaseComponent, title: 'Statistiques Base de Donnée' }, - { path: '**', pathMatch: 'full', redirectTo: `/session/api` } + // { path: '**', pathMatch: 'full', redirectTo: `/session/api` } ] }, { path: '**', pathMatch: 'full', redirectTo: `/session/api` } diff --git a/src/app/views/dashboard/dashboard.component.html b/src/app/views/dashboard/dashboard.component.html new file mode 100644 index 0000000..32d42ab --- /dev/null +++ b/src/app/views/dashboard/dashboard.component.html @@ -0,0 +1,48 @@ +
+ + + + + + + + + + + + + + + + + + + + + + + +
Client {{row.instanceUser || 'N/A'}} Début + {{ row.start*1000 | date:'dd/MM/yyyy' }} +
+ {{ row.start*1000 | date:'HH:mm:ss.SSS' }} +
Durée +
{{ getElapsedTime(row.end, row.start) | number :'1.2-3'}}s
+
+
+ + info + + Aucun résultat +
+
+ + Chargement en cours... + + +
+ +
+
\ No newline at end of file diff --git a/src/app/views/dashboard/dashboard.component.scss b/src/app/views/dashboard/dashboard.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/app/views/dashboard/dashboard.component.ts b/src/app/views/dashboard/dashboard.component.ts new file mode 100644 index 0000000..f0a49ba --- /dev/null +++ b/src/app/views/dashboard/dashboard.component.ts @@ -0,0 +1,37 @@ +import { Component } from '@angular/core'; +import { MatTableDataSource } from '@angular/material/table'; +import { ActivatedRoute } from '@angular/router'; +import { TraceService } from 'src/app/shared/services/trace.service'; +import { EnvRouter } from '../session-detail/session-detail.component'; +import { combineLatest } from 'rxjs'; +import { Location } from '@angular/common'; +import { application } from 'src/environments/environment'; + +@Component({ + templateUrl: './dashboard.component.html', + styleUrls: ['./dashboard.component.scss'], + +}) +export class DashboardComponent { + + displayedColumns: string[] = ['message']; + dataSource: MatTableDataSource<{ count: number, message: string, class: string }> = new MatTableDataSource([]); + paramsSubscription: any; + env: any; + constructor(private _activatedRoute: ActivatedRoute, + private _traceService: TraceService, + private _router: EnvRouter, + private _location: Location) { + + this.paramsSubscription = combineLatest([ + this._activatedRoute.params, + this._activatedRoute.queryParams + ]).subscribe({ + next: ([params, queryParams]) => { + this.env = queryParams.env || application.default_env; + this._location.replaceState(`${this._router.url.split('?')[0]}?env=${this.env}`) + } + }); + } + +} diff --git a/src/app/views/db-request-detail/db-request-detail.component.ts b/src/app/views/db-request-detail/db-request-detail.component.ts index 690092f..5ba7b44 100644 --- a/src/app/views/db-request-detail/db-request-detail.component.ts +++ b/src/app/views/db-request-detail/db-request-detail.component.ts @@ -30,6 +30,23 @@ export class DbRequestDetailComponent implements OnDestroy { pipe = new DatePipe('fr-FR') @ViewChild('timeline') timelineContainer: ElementRef; + jdbcActionDescription: { [key: string]: string }= + { + 'CONNECTION': 'établir une connexion avec la base de données', + 'DISCONNECTION': '', + 'STATEMENT': 'Création et validation de la requête SQL', + 'EXECUTE': 'Exécution de la requête', + 'METADATA': "", + 'DATABASE': '', + 'SCHEMA': '', + 'BATCH': '', + 'COMMIT': 'This command is used to permanently save all changes made during the current transaction. Once a transaction is committed, it cannot be undone', + 'ROLLBACK': ' Used to undo transactions that have not yet been committed. It can revert the database to the last committed state', + 'FETCH': 'Parcours et récupération de résultats', + 'MORE': '', + 'SAVEPOINT':'This command allows you to set a savepoint within a transaction' + }; + constructor(private _activatedRoute: ActivatedRoute, private _traceService: TraceService, @@ -86,8 +103,10 @@ export class DbRequestDetailComponent implements OnDestroy { actions.forEach((c: DatabaseRequestStage) => { g.add(c.name); }); - let groups = Array.from(g).map((g: string) => ({ id: g, content: g })) + + let groups = Array.from(g).map((g: string) => ({ id: g, content: g, title: this.jdbcActionDescription[g] })) + let dataArray = actions.map((c: DatabaseRequestStage, i: number) => { let e: any = { group: c.name, @@ -96,10 +115,12 @@ export class DbRequestDetailComponent implements OnDestroy { end: Math.trunc(+c.end * 1000), title: `${this.pipe.transform(new Date(+c.start * 1000), 'HH:mm:ss.SSS')} - ${this.pipe.transform(new Date(+c.end * 1000), 'HH:mm:ss.SSS')}

${c.name}${c?.count ? '(' + c?.count + ')' : ''}: ${this.getElapsedTime(+c.end, +c.start).toFixed(3)}s

`, - //className : 'vis-dot', + //className : 'vis-dot', } - - e.type = e.start == e.end ? 'point' : 'range' + if(c.name == 'FETCH' && c.count){ // changed c.type to c.name + e.content = `Lignes Récupérées: ${c.count}` + } + e.type = e.end <= e.start ? 'point' : 'range'// TODO : change this to equals dh_dbt is set to timestamps(6), currently set to timestmap(3) if (c?.exception?.message || c?.exception?.type) { e.className = 'bdd-failed'; e.title += `
${c?.exception?.message}
`; // TODO : fix css on tooltip @@ -108,16 +129,22 @@ export class DbRequestDetailComponent implements OnDestroy { return e; }) - if (this.timeLine) { // destroy if exists + if (this.timeLine) { // destroy if exists this.timeLine.destroy(); } + // Create a Timeline this.timeLine = new Timeline(this.timelineContainer.nativeElement, dataArray, groups, { - //stack:false, - // min: timeline_start, - // max: timeline_end, - selectable: false, + //stack:false, + // min: timeline_start, + // max: timeline_end, + margin: { + item: { + horizontal: -1 + } + }, + selectable : false, clickToUse: true, tooltip: { followMouse: true @@ -225,4 +252,5 @@ export class DbRequestDetailComponent implements OnDestroy { -} \ No newline at end of file +} + diff --git a/src/app/views/views.module.ts b/src/app/views/views.module.ts index 6c8f60a..74455b6 100644 --- a/src/app/views/views.module.ts +++ b/src/app/views/views.module.ts @@ -23,6 +23,7 @@ import { DbRequestDetailComponent } from './db-request-detail/db-request-detail. import { RequestRestTableComponent } from './session-detail/components/request-rest-table/request-rest-table.component'; import { RequestDatabaseTableComponent } from './session-detail/components/request-database-table/request-database-table.component'; import { RequestTimelineComponent } from './session-detail/components/request-timeline/request-timeline.component'; +import { DashboardComponent } from './dashboard/dashboard.component'; @NgModule({ imports: [ @@ -52,7 +53,8 @@ import { RequestTimelineComponent } from './session-detail/components/request-ti DependenciesTableComponent, ExceptionTableComponent, SessionTableComponent, - DbRequestDetailComponent + DbRequestDetailComponent, + DashboardComponent ] }) export class ViewsModule { } From d6afb87b63adadcbc13f117e41f4f851922741d4 Mon Sep 17 00:00:00 2001 From: u$f Date: Mon, 15 Jul 2024 18:54:47 +0200 Subject: [PATCH 033/126] github_action --- .github/workflows/main.yml | 19 +++++++++++++++++++ sonar-project.properties | 7 +++++++ 2 files changed, 26 insertions(+) create mode 100644 .github/workflows/main.yml create mode 100644 sonar-project.properties diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 0000000..8ac4e7b --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,19 @@ +name: CI/CD +on: + push: + branches: [ "main" ] + paths-ignore: [ "README.md", "doc/**" ] +jobs: + sonarcloud: + name: SonarCloud + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis + - name: SonarCloud Scan + uses: SonarSource/sonarcloud-github-action@master + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + diff --git a/sonar-project.properties b/sonar-project.properties new file mode 100644 index 0000000..798a1bd --- /dev/null +++ b/sonar-project.properties @@ -0,0 +1,7 @@ +sonar.organization= jarvis +sonar.projectKey= oneteme_inspect-app +sonar.host.url= https://sonarcloud.io + +# relative paths to source directories. More details and properties are described +# in https://sonarcloud.io/documentation/project-administration/narrowing-the-focus/ +sonar.sources=. \ No newline at end of file From 479bda90d93051fdc08e3fc1ca048e093f2f5f30 Mon Sep 17 00:00:00 2001 From: YoussefDahi Date: Mon, 15 Jul 2024 23:42:11 +0200 Subject: [PATCH 034/126] session not found visualisation fix --- .../session-detail.component.ts | 41 +++++++++++-------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/src/app/views/session-detail/session-detail.component.ts b/src/app/views/session-detail/session-detail.component.ts index 42c97ca..2c480d4 100644 --- a/src/app/views/session-detail/session-detail.component.ts +++ b/src/app/views/session-detail/session-detail.component.ts @@ -36,6 +36,7 @@ export class SessionDetailComponent implements OnDestroy { next: ([params, queryParams]) => { this.env = queryParams.env || application.default_env; this.selectedSessionType = params.type; + this.selectedSession = null; this.getSessionById(params.id); this._location.replaceState(`${this._router.url.split('?')[0]}?env=${this.env}`) } @@ -48,6 +49,10 @@ export class SessionDetailComponent implements OnDestroy { traceService .pipe( switchMap((s: InstanceMainSession | InstanceRestSession) => { + if(!s) { + return of(undefined) + } + return forkJoin({ session: of(s), instance: this._traceService.getInstance(s.instanceId), @@ -60,24 +65,27 @@ export class SessionDetailComponent implements OnDestroy { ) .subscribe({ next: (result) => { - this.selectedSession = result.session; - this.selectedSession.requests = result.requests; - this.selectedSession.queries = result.queries; - this.selectedSession.stages = result.stages; - this.instance = result.instance; - if (this.selectedSession) { - this.groupQueriesBySchema(); - // Check if parent exist - this.sessionParent = null; - if (this.selectedSessionType == "api") { - this._traceService.getSessionParentByChildId(id).subscribe({ - next: (data: { id: string, type: SessionType }) => { - this.sessionParent = data; - }, - error: err => {} - }) + if(result){ + this.selectedSession = result.session; + this.selectedSession.requests = result.requests; + this.selectedSession.queries = result.queries; + this.selectedSession.stages = result.stages; + this.instance = result.instance; + if (this.selectedSession) { // why testing here ? + this.groupQueriesBySchema(); + // Check if parent exist + this.sessionParent = null; + if (this.selectedSessionType == "api") { + this._traceService.getSessionParentByChildId(id).subscribe({ + next: (data: { id: string, type: SessionType }) => { + this.sessionParent = data; + }, + error: err => {} + }) + } } } + } }); } @@ -127,7 +135,6 @@ export class SessionDetailComponent implements OnDestroy { if (!acc[item.name]) { acc[item.name] = [] } - acc[item.name].push(item); return acc; }, []); From bd3f83e5f821e353ee3fd79daa66511055ca10cd Mon Sep 17 00:00:00 2001 From: fufuu Date: Wed, 17 Jul 2024 14:26:56 +0200 Subject: [PATCH 035/126] url server --- src/app/shared/services/trace.service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/shared/services/trace.service.ts b/src/app/shared/services/trace.service.ts index 27fd7ec..b7cd47c 100644 --- a/src/app/shared/services/trace.service.ts +++ b/src/app/shared/services/trace.service.ts @@ -36,7 +36,7 @@ export class TraceService { } getSessionParentByChildId(id: string){ - return this.http.get(`${localStorage.getItem('server')}/trace/session/rest/${id}/parent`).pipe(catchError(this.handleError)) + return this.http.get(`${localStorage.getItem('server')}/v3/trace/session/rest/${id}/parent`).pipe(catchError(this.handleError)) } getRestRequests(id: string): Observable> { From 328596a9b8eb2fd0191b34fc9f8d0d3d608ffc1a Mon Sep 17 00:00:00 2001 From: fufuu Date: Thu, 18 Jul 2024 11:06:08 +0200 Subject: [PATCH 036/126] hotfix --- src/app/app.component.ts | 2 +- src/app/shared/model/v3/trace.model.ts | 2 -- src/app/shared/services/trace.service.ts | 8 ++---- .../session-api/session-api.component.html | 2 +- .../session-api/session-api.component.ts | 2 +- .../session-detail.component.html | 6 ++--- .../session-detail.component.ts | 26 ++++--------------- .../views/stats-user/stats-user.component.ts | 10 +++---- 8 files changed, 18 insertions(+), 40 deletions(-) diff --git a/src/app/app.component.ts b/src/app/app.component.ts index d1b3f09..1bd6ec4 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -28,7 +28,7 @@ export class AppComponent implements OnInit { private _router: EnvRouter, private _service: JQueryService) { this.isLoadingEnv = true; - this.subscriptions.push(this._service.getInstance({'column.distinct': 'environement', 'order': 'environement.asc'}) + this.subscriptions.push(this._service.getInstance({'column.distinct': 'environement', 'environement.not': 'null', 'order': 'environement.asc'}) .pipe(finalize(() => this.isLoadingEnv = false)) .subscribe({ next: (res: {environement: string}[]) => { diff --git a/src/app/shared/model/v3/trace.model.ts b/src/app/shared/model/v3/trace.model.ts index 76896a8..f28976d 100644 --- a/src/app/shared/model/v3/trace.model.ts +++ b/src/app/shared/model/v3/trace.model.ts @@ -1,13 +1,11 @@ export interface InstanceRestSession extends RestSession { instanceId: string; - instanceUser: string; appName: string; mask: number; } export interface InstanceMainSession extends MainSession { instanceId: string; - instanceUser: string; appName: string; mask: number; } diff --git a/src/app/shared/services/trace.service.ts b/src/app/shared/services/trace.service.ts index b7cd47c..7b01145 100644 --- a/src/app/shared/services/trace.service.ts +++ b/src/app/shared/services/trace.service.ts @@ -35,8 +35,8 @@ export class TraceService { return this.http.get(`${localStorage.getItem('server')}/v3/trace/session/main/${id}/tree`); } - getSessionParentByChildId(id: string){ - return this.http.get(`${localStorage.getItem('server')}/v3/trace/session/rest/${id}/parent`).pipe(catchError(this.handleError)) + getSessionParentByChildId(id: string): Observable<{ id: string, type: string }> { + return this.http.get<{ id: string, type: string }>(`${localStorage.getItem('server')}/v3/trace/session/rest/${id}/parent`) } getRestRequests(id: string): Observable> { @@ -62,8 +62,4 @@ export class TraceService { getInstance(id: string): Observable { return this.http.get(`${localStorage.getItem('server')}/v3/trace/instance/${id}`); } - - private handleError( error: HttpErrorResponse){ - return throwError(()=>error) - } } \ No newline at end of file diff --git a/src/app/views/session-api/session-api.component.html b/src/app/views/session-api/session-api.component.html index ecef8a7..4744901 100644 --- a/src/app/views/session-api/session-api.component.html +++ b/src/app/views/session-api/session-api.component.html @@ -111,7 +111,7 @@ Client - {{row.instanceUser || 'N/A'}} + {{row.user || 'N/A'}} diff --git a/src/app/views/session-api/session-api.component.ts b/src/app/views/session-api/session-api.component.ts index 0cb3136..f48f096 100644 --- a/src/app/views/session-api/session-api.component.ts +++ b/src/app/views/session-api/session-api.component.ts @@ -153,7 +153,7 @@ export class SessionApiComponent implements OnInit, OnDestroy { if (key == 'filter') { isMatch = isMatch && (value == '' || (data.appName?.toLowerCase().includes(value) || data.method?.toLowerCase().includes(value) || data.query?.toLowerCase().includes(value) || - data.instanceUser?.toLowerCase().includes(value) || data.path?.toLowerCase().includes(value))); + data.user?.toLowerCase().includes(value) || data.path?.toLowerCase().includes(value))); } else if (key == 'status') { const s = data.status.toString(); isMatch = isMatch && (!value.length || (value.some((status: any) => { diff --git a/src/app/views/session-detail/session-detail.component.html b/src/app/views/session-detail/session-detail.component.html index 8699e5c..d68c883 100644 --- a/src/app/views/session-detail/session-detail.component.html +++ b/src/app/views/session-detail/session-detail.component.html @@ -55,10 +55,10 @@ person
- - {{instance?.user || "N/A"}} + {{selectedSession?.user || "N/A"}} le {{( selectedSession?.start*1000 ) | date: 'dd/MM/yyyy à HH:mm:ss.SSS': 'fr' }}
diff --git a/src/app/views/session-detail/session-detail.component.ts b/src/app/views/session-detail/session-detail.component.ts index 2c480d4..5a72ed0 100644 --- a/src/app/views/session-detail/session-detail.component.ts +++ b/src/app/views/session-detail/session-detail.component.ts @@ -1,14 +1,12 @@ import { Component, Injectable, OnDestroy } from '@angular/core'; import { ActivatedRoute, NavigationExtras, Router } from '@angular/router'; -import { Observable, combineLatest, finalize, forkJoin, map, of, switchMap } from "rxjs"; +import { Observable, catchError, combineLatest, finalize, forkJoin, map, of, switchMap } from "rxjs"; import { Utils } from 'src/app/shared/util'; import { Location } from '@angular/common'; import { TraceService } from 'src/app/shared/services/trace.service'; import { application } from 'src/environments/environment'; import { InstanceEnvironment, InstanceMainSession, InstanceRestSession } from 'src/app/shared/model/v3/trace.model'; -type SessionType = 'main' | 'rest'; - @Component({ templateUrl: './session-detail.component.html', styleUrls: ['./session-detail.component.scss'], @@ -18,7 +16,7 @@ export class SessionDetailComponent implements OnDestroy { selectedSession: InstanceMainSession | InstanceRestSession; // IncomingRequest | Mainrequest | OutcomingRequest; instance: InstanceEnvironment; selectedSessionType: string; - sessionParent: { id: string, type: SessionType }; + sessionParent: { id: string, type: string }; isLoading: boolean = false; paramsSubscription: any; queryBySchema: any[]; @@ -49,13 +47,10 @@ export class SessionDetailComponent implements OnDestroy { traceService .pipe( switchMap((s: InstanceMainSession | InstanceRestSession) => { - if(!s) { - return of(undefined) - } - return forkJoin({ session: of(s), instance: this._traceService.getInstance(s.instanceId), + parent: this._traceService.getSessionParentByChildId(id).pipe(catchError(() => of(null))), requests: this._traceService.getRestRequests(s.id), queries: this._traceService.getDatabaseRequests(s.id), stages: this._traceService.getLocalRequests(s.id) @@ -71,19 +66,8 @@ export class SessionDetailComponent implements OnDestroy { this.selectedSession.queries = result.queries; this.selectedSession.stages = result.stages; this.instance = result.instance; - if (this.selectedSession) { // why testing here ? - this.groupQueriesBySchema(); - // Check if parent exist - this.sessionParent = null; - if (this.selectedSessionType == "api") { - this._traceService.getSessionParentByChildId(id).subscribe({ - next: (data: { id: string, type: SessionType }) => { - this.sessionParent = data; - }, - error: err => {} - }) - } - } + this.sessionParent = result.parent; + this.groupQueriesBySchema(); } } diff --git a/src/app/views/stats-user/stats-user.component.ts b/src/app/views/stats-user/stats-user.component.ts index be942f5..9a90812 100644 --- a/src/app/views/stats-user/stats-user.component.ts +++ b/src/app/views/stats-user/stats-user.component.ts @@ -120,17 +120,17 @@ export class StatsUserComponent implements OnInit, OnDestroy { let now = new Date(); var groupedBy = periodManagement(start, end); return { - repartitionTimeAndTypeResponse: { observable: this._statsService.getRestSession({ 'column': "count_slowest:elapsedTimeSlowest,count_slow:elapsedTimeSlow,count_medium:elapsedTimeMedium,count_fast:elapsedTimeFast,count_fastest:elapsedTimeFastest,count_succes:countSucces,count_error_server:countErrorServer,count_error_client:countErrorClient", 'rest_session.instance_env': 'instance.id', 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'instance.environement': env, 'instance.user': name, ...advancedParams }) }, + repartitionTimeAndTypeResponse: { observable: this._statsService.getRestSession({ 'column': "count_slowest:elapsedTimeSlowest,count_slow:elapsedTimeSlow,count_medium:elapsedTimeMedium,count_fast:elapsedTimeFast,count_fastest:elapsedTimeFastest,count_succes:countSucces,count_error_server:countErrorServer,count_error_client:countErrorClient", 'rest_session.instance_env': 'instance.id', 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'instance.environement': env, 'rest_session.user': name, ...advancedParams }) }, repartitionTimeAndTypeResponseByPeriod: { - observable: this._statsService.getRestSession({ 'column': `count_succes:countSucces,count_error_client:countErrorClient,count_error_server:countErrorServer,count_slowest:elapsedTimeSlowest,count_slow:elapsedTimeSlow,count_medium:elapsedTimeMedium,count_fast:elapsedTimeFast,count_fastest:elapsedTimeFastest,elapsedtime.avg:avg,elapsedtime.max:max,start.${groupedBy}:date,start.year:year`, 'rest_session.instance_env': 'instance.id', 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'instance.user': name, 'instance.environement': env, 'order': `start.year.asc,start.${groupedBy}.asc`, ...advancedParams }).pipe(map(((r: any[]) => { + observable: this._statsService.getRestSession({ 'column': `count_succes:countSucces,count_error_client:countErrorClient,count_error_server:countErrorServer,count_slowest:elapsedTimeSlowest,count_slow:elapsedTimeSlow,count_medium:elapsedTimeMedium,count_fast:elapsedTimeFast,count_fastest:elapsedTimeFastest,elapsedtime.avg:avg,elapsedtime.max:max,start.${groupedBy}:date,start.year:year`, 'rest_session.instance_env': 'instance.id', 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'rest_session.user': name, 'instance.environement': env, 'order': `start.year.asc,start.${groupedBy}.asc`, ...advancedParams }).pipe(map(((r: any[]) => { formatters[groupedBy](r, this._datePipe); return r; }))) }, - repartitionRequestByPeriodLine: { observable: this._statsService.getRestSession({ 'column': "count:count,count_error_server:countErrorServer,count_slowest:countSlowest,start.date:date", 'rest_session.instance_env': 'instance.id', 'start.ge': new Date(now.getFullYear(), now.getMonth(), now.getDate() - 6).toISOString(), 'start.lt': now.toISOString(), 'instance.environement': env, 'instance.user': name, 'order': 'start.date.asc', ...advancedParams }) }, - repartitionApiBar: { observable: this._statsService.getRestSession({ 'column': "count_succes:countSucces,count_error_client:countErrorClient,count_error_server:countErrorServer,api_name", 'rest_session.instance_env': 'instance.id', 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'instance.environement': env, 'instance.user': name, 'api_name.not': 'null', 'order': 'count.desc', ...advancedParams }).pipe(map((d: any) => d.slice(0, 5))) }, + repartitionRequestByPeriodLine: { observable: this._statsService.getRestSession({ 'column': "count:count,count_error_server:countErrorServer,count_slowest:countSlowest,start.date:date", 'rest_session.instance_env': 'instance.id', 'start.ge': new Date(now.getFullYear(), now.getMonth(), now.getDate() - 6).toISOString(), 'start.lt': now.toISOString(), 'instance.environement': env, 'rest_session.user': name, 'order': 'start.date.asc', ...advancedParams }) }, + repartitionApiBar: { observable: this._statsService.getRestSession({ 'column': "count_succes:countSucces,count_error_client:countErrorClient,count_error_server:countErrorServer,api_name", 'rest_session.instance_env': 'instance.id', 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'instance.environement': env, 'rest_session.user': name, 'api_name.not': 'null', 'order': 'count.desc', ...advancedParams }).pipe(map((d: any) => d.slice(0, 5))) }, // exceptionsTable: { observable: this._statsService.getException({ 'column': 'count,err_type,err_msg', 'err.group': '', "status.ge": 500, "environement": env, 'user': name, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'order': 'count.desc', ...advancedParams })}, - sessionTable: { observable: this._statsService.getMainSession({ 'column': "name,start:date,elapsedtime,location,instance.app_name", 'main_session.instance_env': 'instance.id', 'instance.user': name, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'instance.environement': env, 'order': 'start.date.desc' }) } + sessionTable: { observable: this._statsService.getMainSession({ 'column': "name,start:date,elapsedtime,location,instance.app_name", 'main_session.instance_env': 'instance.id', 'user': name, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'instance.environement': env, 'type': 'VIEW', 'order': 'start.date.desc' }) } }; } From 13445e3dc645ef8ca305e1227f8988d3f0fb36ef Mon Sep 17 00:00:00 2001 From: fufuu Date: Thu, 18 Jul 2024 11:57:17 +0200 Subject: [PATCH 037/126] hotfix --- src/app/views/session-main/session-main.component.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/app/views/session-main/session-main.component.html b/src/app/views/session-main/session-main.component.html index 43aa8e8..3b9a3e5 100644 --- a/src/app/views/session-main/session-main.component.html +++ b/src/app/views/session-main/session-main.component.html @@ -14,8 +14,9 @@ Type de Session Aucun - WEBAPP + VIEW BATCH + STARTUP From f03896f168541008abb9c1509de0fa7a71e383d8 Mon Sep 17 00:00:00 2001 From: fufuu Date: Thu, 18 Jul 2024 14:19:57 +0200 Subject: [PATCH 038/126] hotfix tree --- src/app/shared/services/trace.service.ts | 9 +++------ src/app/views/session-detail/session-detail.component.ts | 2 +- src/app/views/tree/tree.component.ts | 2 +- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/app/shared/services/trace.service.ts b/src/app/shared/services/trace.service.ts index 7b01145..e4d6c0d 100644 --- a/src/app/shared/services/trace.service.ts +++ b/src/app/shared/services/trace.service.ts @@ -27,12 +27,9 @@ export class TraceService { return this.http.get(`${localStorage.getItem('server')}/v3/trace/session/main/${id}`); } - getTreeRequest(id: string) { - return this.http.get(`${localStorage.getItem('server')}/v3/trace/session/rest/${id}/tree`); - } - - getTreeMain(id: string) { - return this.http.get(`${localStorage.getItem('server')}/v3/trace/session/main/${id}/tree`); + getTree(id: string, type: string) { + return type == "api" ? this.http.get(`${localStorage.getItem('server')}/v3/trace/session/rest/${id}/tree`) : + this.http.get(`${localStorage.getItem('server')}/v3/trace/session/main/${id}/tree`); } getSessionParentByChildId(id: string): Observable<{ id: string, type: string }> { diff --git a/src/app/views/session-detail/session-detail.component.ts b/src/app/views/session-detail/session-detail.component.ts index 5a72ed0..e45fc5c 100644 --- a/src/app/views/session-detail/session-detail.component.ts +++ b/src/app/views/session-detail/session-detail.component.ts @@ -139,7 +139,7 @@ export class SessionDetailComponent implements OnDestroy { params.push('dashboard', 'app', this.selectedSession.appName) break; case "tree": - params.push('session/api', this.selectedSession.id, 'tree') + params.push('session', this.selectedSessionType, this.selectedSession.id, 'tree') break; case "parent": params.push('session', this.sessionParent.type, this.sessionParent.id) diff --git a/src/app/views/tree/tree.component.ts b/src/app/views/tree/tree.component.ts index 5e0822c..b9c68b9 100644 --- a/src/app/views/tree/tree.component.ts +++ b/src/app/views/tree/tree.component.ts @@ -53,7 +53,7 @@ export class TreeComponent implements OnDestroy { this.env = v.queryParams.env || application.default_env; this._location.replaceState(`${this._router.url.split('?')[0]}?env=${this.env}`) this.isLoading = true; - this._traceService.getTreeRequest(this.id).pipe(finalize(() => this.isLoading = false)).subscribe(d => { + this._traceService.getTree(this.id, v.paramsList.params['type']).pipe(finalize(() => this.isLoading = false)).subscribe(d => { this.exchange = {}; this.exchange['remoteTrace'] = d; From a80ef9476c0119cb495b51f7318faf0ee8121b20 Mon Sep 17 00:00:00 2001 From: YoussefDahi Date: Thu, 18 Jul 2024 15:02:56 +0200 Subject: [PATCH 039/126] fixed db-request timeline visualisation, addded min/max cap, group title --- src/app/shared/model/v3/trace.model.ts | 1 + .../db-request-detail.component.html | 37 ++------------ .../db-request-detail.component.ts | 49 +++++++++++-------- .../request-timeline.component.ts | 6 +-- 4 files changed, 36 insertions(+), 57 deletions(-) diff --git a/src/app/shared/model/v3/trace.model.ts b/src/app/shared/model/v3/trace.model.ts index f28976d..5c78874 100644 --- a/src/app/shared/model/v3/trace.model.ts +++ b/src/app/shared/model/v3/trace.model.ts @@ -11,6 +11,7 @@ export interface InstanceMainSession extends MainSession { } export interface RestSession extends RestRequest { + type: string; name: string; requests: Array; queries: Array; diff --git a/src/app/views/db-request-detail/db-request-detail.component.html b/src/app/views/db-request-detail/db-request-detail.component.html index b2980b0..4d10423 100644 --- a/src/app/views/db-request-detail/db-request-detail.component.html +++ b/src/app/views/db-request-detail/db-request-detail.component.html @@ -16,20 +16,6 @@
-
-

- {{selectedQuery?.location}} -

-
- - -
Database - {{selectedQuery?.database}} + {{selectedQuery?.name}}
- -
-
- Database -
-
- - {{ item.key }} - -
{{ item.value[0].databaseName }} v.{{ - item.value[0].databaseVersion}}
-
-
- -
{{selectedQuery?.host}} {{ ':'+ selectedQuery?.port || '' }}
- {{selectedQuery?.databaseName}} + {{selectedQuery?.productName}} - {{selectedQuery?.databaseVersion}} + {{selectedQuery?.productVersion}}
diff --git a/src/app/views/db-request-detail/db-request-detail.component.ts b/src/app/views/db-request-detail/db-request-detail.component.ts index 690092f..d9d6cbe 100644 --- a/src/app/views/db-request-detail/db-request-detail.component.ts +++ b/src/app/views/db-request-detail/db-request-detail.component.ts @@ -30,6 +30,23 @@ export class DbRequestDetailComponent implements OnDestroy { pipe = new DatePipe('fr-FR') @ViewChild('timeline') timelineContainer: ElementRef; + jdbcActionDescription: { [key: string]: string }= + { + 'CONNECTION': 'établir une connexion avec la base de données', + 'DISCONNECTION': '', + 'STATEMENT': 'Création et validation de la requête SQL', + 'EXECUTE': 'Exécution de la requête', + 'METADATA': "", + 'DATABASE': '', + 'SCHEMA': '', + 'BATCH': '', + 'COMMIT': 'This command is used to permanently save all changes made during the current transaction. Once a transaction is committed, it cannot be undone', + 'ROLLBACK': ' Used to undo transactions that have not yet been committed. It can revert the database to the last committed state', + 'FETCH': 'Parcours et récupération de résultats', + 'MORE': '', + 'SAVEPOINT':'This command allows you to set a savepoint within a transaction' + }; + constructor(private _activatedRoute: ActivatedRoute, private _traceService: TraceService, @@ -78,19 +95,16 @@ export class DbRequestDetailComponent implements OnDestroy { } visjs() { - let timeline_end = +this.selectedQuery.end * 1000; - let timeline_start = +this.selectedQuery.start * 1000; + let timeline_end = Math.round(+this.selectedQuery.end)* 1000; + let timeline_start = Math.trunc(+this.selectedQuery.start)* 1000 ; let actions = this.selectedQuery.actions; this.sortInnerArrayByDate(actions) - let g = new Set(); - actions.forEach((c: DatabaseRequestStage) => { - g.add(c.name); - }); - let groups = Array.from(g).map((g: string) => ({ id: g, content: g })) + let groups = actions.map((g: DatabaseRequestStage,i:number ) => ({ id: i, content: g?.name, title: this.jdbcActionDescription[g?.name] })) + groups let dataArray = actions.map((c: DatabaseRequestStage, i: number) => { let e: any = { - group: c.name, + group: groups[i].id, // content: "c.type", start: Math.trunc(+c.start * 1000), end: Math.trunc(+c.end * 1000), @@ -99,32 +113,31 @@ export class DbRequestDetailComponent implements OnDestroy { //className : 'vis-dot', } + if((c.name == 'FETCH' || c.name =='BATCH' ||c.name == 'EXECUTE') && c.count){ // changed c.type to c.name + e.content = c.count.toString(); + } e.type = e.start == e.end ? 'point' : 'range' if (c?.exception?.message || c?.exception?.type) { e.className = 'bdd-failed'; e.title += `
${c?.exception?.message}
`; // TODO : fix css on tooltip } + return e; }) - if (this.timeLine) { // destroy if exists this.timeLine.destroy(); } // Create a Timeline this.timeLine = new Timeline(this.timelineContainer.nativeElement, dataArray, groups, { - //stack:false, - // min: timeline_start, - // max: timeline_end, + min: timeline_start, + max: timeline_end, selectable: false, clickToUse: true, tooltip: { followMouse: true }, - //order: (a, b) => { - // return b.start - a.start // inverser l'ordre - // } }); } @@ -191,11 +204,7 @@ export class DbRequestDetailComponent implements OnDestroy { sortInnerArrayByDate(innerArray: any[]): any[] { return innerArray.sort((a, b) => { - if (a.start > b.start) - return 1; - - if (a.start < b.start) - return -1; + return a.start - b.start }); } diff --git a/src/app/views/session-detail/components/request-timeline/request-timeline.component.ts b/src/app/views/session-detail/components/request-timeline/request-timeline.component.ts index 64f47fc..d6e8e9b 100644 --- a/src/app/views/session-detail/components/request-timeline/request-timeline.component.ts +++ b/src/app/views/session-detail/components/request-timeline/request-timeline.component.ts @@ -2,7 +2,7 @@ import { DatePipe } from "@angular/common"; import { Component, ElementRef, Input, OnChanges, OnInit, SimpleChanges, ViewChild, inject } from "@angular/core"; import { Timeline } from "vis-timeline"; import { EnvRouter } from "../../session-detail.component"; -import { DatabaseRequest, LocalRequest, RestRequest } from "src/app/shared/model/v3/trace.model"; +import { DatabaseRequest, InstanceEnvironment, InstanceMainSession, InstanceRestSession, LocalRequest, RestRequest } from "src/app/shared/model/v3/trace.model"; @Component({ selector: 'request-timeline-table', @@ -17,8 +17,8 @@ export class RequestTimelineComponent implements OnChanges { @ViewChild('timeline', {static: true}) timelineElement: ElementRef; - @Input() instance:any; - @Input() request:any; + @Input() instance:InstanceEnvironment; + @Input() request:InstanceMainSession | InstanceRestSession; ngOnChanges(changes: SimpleChanges): void { if( changes.instance || changes.request){ From 29093a444de633c4e42586e688d3c51c8f6066a6 Mon Sep 17 00:00:00 2001 From: fufuu Date: Fri, 19 Jul 2024 10:34:54 +0200 Subject: [PATCH 040/126] type main dropdown --- src/app/views/session-main/session-main.component.html | 2 +- src/app/views/session-main/session-main.component.ts | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/app/views/session-main/session-main.component.html b/src/app/views/session-main/session-main.component.html index 3b9a3e5..1432879 100644 --- a/src/app/views/session-main/session-main.component.html +++ b/src/app/views/session-main/session-main.component.html @@ -13,7 +13,7 @@ Type de Session - Aucun + Aucun VIEW BATCH STARTUP diff --git a/src/app/views/session-main/session-main.component.ts b/src/app/views/session-main/session-main.component.ts index f8a932e..1c94c14 100644 --- a/src/app/views/session-main/session-main.component.ts +++ b/src/app/views/session-main/session-main.component.ts @@ -117,6 +117,7 @@ export class SessionMainComponent implements OnInit, OnDestroy { search() { if (this.serverFilterForm.valid) { let name = this.serverFilterForm.getRawValue().launchmode; + console.log(name) let start = this.serverFilterForm.getRawValue().dateRangePicker.start; let end = this.serverFilterForm.getRawValue().dateRangePicker.end let excludedEnd = new Date(end.getFullYear(), end.getMonth(), end.getDate() + 1) From 6e3230424ae89bef6e5caea7f4c8792c36f6dc4b Mon Sep 17 00:00:00 2001 From: fufuu Date: Mon, 29 Jul 2024 15:06:43 +0200 Subject: [PATCH 041/126] refacto --- src/app/app.component.html | 17 ++- src/app/app.component.ts | 23 +-- src/app/app.module.ts | 122 +++++++++------- src/app/{shared => }/model/chart.model.ts | 0 src/app/{shared => }/model/conf.model.ts | 0 .../{shared/model/v3 => model}/trace.model.ts | 19 +-- .../services => service}/filter.service.ts | 0 .../services => service}/jquery.service.ts | 0 src/app/service/router.service.ts | 48 ++++++ src/app/service/trace.service.ts | 108 ++++++++++++++ .../advanced-filter-modal.component.html | 0 .../advanced-filter-modal.component.scss | 0 .../advanced-filter-modal.component.ts | 4 +- .../advanced-filter-recap.component.html | 0 .../advanced-filter-recap.component.scss | 0 .../advanced-filter-recap.component.ts | 0 .../advanced-filter-trigger.component.html | 0 .../advanced-filter-trigger.component.scss | 0 .../advanced-filter-trigger.component.ts | 2 +- .../header-page/header-page.component.html | 0 .../header-page/header-page.component.scss | 0 .../header-page/header-page.component.ts | 0 .../material/material.module.ts} | 0 src/app/shared/model/trace.model.ts | 89 ------------ src/app/shared/services/trace.service.ts | 62 -------- src/app/shared/shared.module.ts | 11 +- src/app/shared/util.ts | 4 +- .../views/dashboard/dashboard.component.ts | 4 +- .../database/database.component.html} | 0 .../database/database.component.scss} | 0 .../database/database.component.ts} | 19 ++- .../database-table.component.html} | 2 +- .../database-table.component.scss} | 0 .../database-table.component.ts} | 9 +- .../rest-table/rest-table.component.html} | 0 .../rest-table/rest-table.component.scss} | 0 .../rest-table/rest-table.component.ts} | 8 +- .../timeline/timeline.component.html} | 0 .../timeline/timeline.component.scss} | 0 .../timeline/timeline.component.ts} | 10 +- .../detail/session/main/main.component.html | 121 ++++++++++++++++ .../detail/session/main/main.component.scss | 73 ++++++++++ .../detail/session/main/main.component.ts | 133 +++++++++++++++++ .../detail/session/rest/rest.component.html | 129 +++++++++++++++++ .../detail/session/rest/rest.component.scss | 73 ++++++++++ .../detail/session/rest/rest.component.ts | 137 ++++++++++++++++++ .../session/session.component.html} | 0 .../session/session.component.scss} | 0 .../session/session.component.ts} | 57 +------- .../main/main.component.html} | 20 --- .../main/main.component.scss} | 0 .../main/main.component.ts} | 71 ++++----- .../rest/rest.component.html} | 0 .../rest/rest.component.scss} | 0 .../rest/rest.component.ts} | 22 +-- .../dependencies-table.component.html | 0 .../dependencies-table.component.scss | 0 .../dependencies-table.component.ts | 0 .../dependents-table.component.html | 0 .../dependents-table.component.scss | 0 .../dependents-table.component.ts | 0 .../exception-table.component.html | 0 .../exception-table.component.scss | 0 .../exception-table.component.ts | 0 .../application/application.component.html} | 0 .../application/application.component.scss} | 0 .../application/application.component.ts} | 18 +-- .../database/database.component.html} | 0 .../database/database.component.scss} | 0 .../database/database.component.ts} | 10 +- .../rest/rest.component.html} | 0 .../rest/rest.component.scss} | 0 .../rest/rest.component.ts} | 18 +-- .../session-table.component.html | 0 .../session-table.component.scss | 0 .../session-table/session-table.component.ts | 0 .../user/user.component.html} | 0 .../user/user.component.scss} | 0 .../user/user.component.ts} | 14 +- src/app/views/tree/tree.component.ts | 26 ++-- src/app/views/views.module.ts | 76 +++++----- src/environments/environment.prod.ts | 2 +- src/environments/environment.ts | 2 +- 83 files changed, 1085 insertions(+), 478 deletions(-) rename src/app/{shared => }/model/chart.model.ts (100%) rename src/app/{shared => }/model/conf.model.ts (100%) rename src/app/{shared/model/v3 => model}/trace.model.ts (94%) rename src/app/{shared/services => service}/filter.service.ts (100%) rename src/app/{shared/services => service}/jquery.service.ts (100%) create mode 100644 src/app/service/router.service.ts create mode 100644 src/app/service/trace.service.ts rename src/app/shared/{components/stats => _component}/advanced-filter/advanced-filter-modal/advanced-filter-modal.component.html (100%) rename src/app/shared/{components/stats => _component}/advanced-filter/advanced-filter-modal/advanced-filter-modal.component.scss (100%) rename src/app/shared/{components/stats => _component}/advanced-filter/advanced-filter-modal/advanced-filter-modal.component.ts (97%) rename src/app/shared/{components/stats => _component}/advanced-filter/advanced-filter-recap/advanced-filter-recap.component.html (100%) rename src/app/shared/{components/stats => _component}/advanced-filter/advanced-filter-recap/advanced-filter-recap.component.scss (100%) rename src/app/shared/{components/stats => _component}/advanced-filter/advanced-filter-recap/advanced-filter-recap.component.ts (100%) rename src/app/shared/{components/stats => _component}/advanced-filter/advanced-filter-trigger/advanced-filter-trigger.component.html (100%) rename src/app/shared/{components/stats => _component}/advanced-filter/advanced-filter-trigger/advanced-filter-trigger.component.scss (100%) rename src/app/shared/{components/stats => _component}/advanced-filter/advanced-filter-trigger/advanced-filter-trigger.component.ts (98%) rename src/app/shared/{components => _component}/header-page/header-page.component.html (100%) rename src/app/shared/{components => _component}/header-page/header-page.component.scss (100%) rename src/app/shared/{components => _component}/header-page/header-page.component.ts (100%) rename src/app/{app.material.module.ts => shared/material/material.module.ts} (100%) delete mode 100644 src/app/shared/model/trace.model.ts delete mode 100644 src/app/shared/services/trace.service.ts rename src/app/views/{db-request-detail/db-request-detail.component.html => detail/database/database.component.html} (100%) rename src/app/views/{db-request-detail/db-request-detail.component.scss => detail/database/database.component.scss} (100%) rename src/app/views/{db-request-detail/db-request-detail.component.ts => detail/database/database.component.ts} (92%) rename src/app/views/{session-detail/components/request-database-table/request-database-table.component.html => detail/session/_component/database-table/database-table.component.html} (97%) rename src/app/views/{session-detail/components/request-database-table/request-database-table.component.scss => detail/session/_component/database-table/database-table.component.scss} (100%) rename src/app/views/{session-detail/components/request-database-table/request-database-table.component.ts => detail/session/_component/database-table/database-table.component.ts} (88%) rename src/app/views/{session-detail/components/request-rest-table/request-rest-table.component.html => detail/session/_component/rest-table/rest-table.component.html} (100%) rename src/app/views/{session-detail/components/request-rest-table/request-rest-table.component.scss => detail/session/_component/rest-table/rest-table.component.scss} (100%) rename src/app/views/{session-detail/components/request-rest-table/request-rest-table.component.ts => detail/session/_component/rest-table/rest-table.component.ts} (93%) rename src/app/views/{session-detail/components/request-timeline/request-timeline.component.html => detail/session/_component/timeline/timeline.component.html} (100%) rename src/app/views/{session-detail/components/request-timeline/request-timeline.component.scss => detail/session/_component/timeline/timeline.component.scss} (100%) rename src/app/views/{session-detail/components/request-timeline/request-timeline.component.ts => detail/session/_component/timeline/timeline.component.ts} (94%) create mode 100644 src/app/views/detail/session/main/main.component.html create mode 100644 src/app/views/detail/session/main/main.component.scss create mode 100644 src/app/views/detail/session/main/main.component.ts create mode 100644 src/app/views/detail/session/rest/rest.component.html create mode 100644 src/app/views/detail/session/rest/rest.component.scss create mode 100644 src/app/views/detail/session/rest/rest.component.ts rename src/app/views/{session-detail/session-detail.component.html => detail/session/session.component.html} (100%) rename src/app/views/{session-detail/session-detail.component.scss => detail/session/session.component.scss} (100%) rename src/app/views/{session-detail/session-detail.component.ts => detail/session/session.component.ts} (81%) rename src/app/views/{session-main/session-main.component.html => search/main/main.component.html} (87%) rename src/app/views/{session-main/session-main.component.scss => search/main/main.component.scss} (100%) rename src/app/views/{session-main/session-main.component.ts => search/main/main.component.ts} (71%) rename src/app/views/{session-api/session-api.component.html => search/rest/rest.component.html} (100%) rename src/app/views/{session-api/session-api.component.scss => search/rest/rest.component.scss} (100%) rename src/app/views/{session-api/session-api.component.ts => search/rest/rest.component.ts} (93%) rename src/app/{shared/components/stats => views/statistic/_component}/dependencies-table/dependencies-table.component.html (100%) rename src/app/{shared/components/stats => views/statistic/_component}/dependencies-table/dependencies-table.component.scss (100%) rename src/app/{shared/components/stats => views/statistic/_component}/dependencies-table/dependencies-table.component.ts (100%) rename src/app/{shared/components/stats => views/statistic/_component}/dependents-table/dependents-table.component.html (100%) rename src/app/{shared/components/stats => views/statistic/_component}/dependents-table/dependents-table.component.scss (100%) rename src/app/{shared/components/stats => views/statistic/_component}/dependents-table/dependents-table.component.ts (100%) rename src/app/{shared/components/stats => views/statistic/_component}/exception-table/exception-table.component.html (100%) rename src/app/{shared/components/stats => views/statistic/_component}/exception-table/exception-table.component.scss (100%) rename src/app/{shared/components/stats => views/statistic/_component}/exception-table/exception-table.component.ts (100%) rename src/app/views/{stats-app/stats-app.component.html => statistic/application/application.component.html} (100%) rename src/app/views/{stats-app/stats-app.component.scss => statistic/application/application.component.scss} (100%) rename src/app/views/{stats-app/stats-app.component.ts => statistic/application/application.component.ts} (96%) rename src/app/views/{stats-database/stats-database.component.html => statistic/database/database.component.html} (100%) rename src/app/views/{stats-database/stats-database.component.scss => statistic/database/database.component.scss} (100%) rename src/app/views/{stats-database/stats-database.component.ts => statistic/database/database.component.ts} (97%) rename src/app/views/{stats-api/stats-api.component.html => statistic/rest/rest.component.html} (100%) rename src/app/views/{stats-api/stats-api.component.scss => statistic/rest/rest.component.scss} (100%) rename src/app/views/{stats-api/stats-api.component.ts => statistic/rest/rest.component.ts} (95%) rename src/app/{shared/components/stats => views/statistic/user/_component}/session-table/session-table.component.html (100%) rename src/app/{shared/components/stats => views/statistic/user/_component}/session-table/session-table.component.scss (100%) rename src/app/{shared/components/stats => views/statistic/user/_component}/session-table/session-table.component.ts (100%) rename src/app/views/{stats-user/stats-user.component.html => statistic/user/user.component.html} (100%) rename src/app/views/{stats-user/stats-user.component.scss => statistic/user/user.component.scss} (100%) rename src/app/views/{stats-user/stats-user.component.ts => statistic/user/user.component.ts} (96%) diff --git a/src/app/app.component.html b/src/app/app.component.html index 9361431..4f4bbeb 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -2,15 +2,22 @@ Trace Api - - + - - + + + + + + + - diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 1bd6ec4..c3e1f7d 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -1,22 +1,19 @@ -import { Component, OnInit, ViewChild } from '@angular/core'; -import { FormControl } from '@angular/forms'; -import { ActivatedRoute, NavigationEnd, NavigationStart, Router } from '@angular/router'; -import { Subscription, distinctUntilChanged, filter, finalize, skip } from 'rxjs'; -import { application, environment } from 'src/environments/environment'; -import { EnvRouter } from './views/session-detail/session-detail.component'; -import { MatDrawer } from '@angular/material/sidenav'; -import { JQueryService } from './shared/services/jquery.service'; -import { FilterService } from './shared/services/filter.service'; +import {Component, OnDestroy, OnInit} from '@angular/core'; +import {FormControl} from '@angular/forms'; +import {ActivatedRoute} from '@angular/router'; +import {distinctUntilChanged, finalize, Subscription} from 'rxjs'; +import {application, environment} from 'src/environments/environment'; +import {JQueryService} from './service/jquery.service'; +import {EnvRouter} from "./service/router.service"; @Component({ selector: 'app-root', templateUrl: 'app.component.html', styleUrls: ['app.component.scss'] - }) -export class AppComponent implements OnInit { +export class AppComponent implements OnInit, OnDestroy { envs: any[]; env: FormControl = new FormControl(); isLoadingEnv = false; @@ -70,10 +67,6 @@ export class AppComponent implements OnInit { } } - ngAfterViewInit() { - - } - ngOnDestroy(): void { this.unsubscribe(); } diff --git a/src/app/app.module.ts b/src/app/app.module.ts index f581833..ccc98ba 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -1,97 +1,114 @@ -import { BrowserModule } from '@angular/platform-browser'; -import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; -import { NgModule, LOCALE_ID } from '@angular/core'; -import { FormsModule, ReactiveFormsModule } from '@angular/forms'; -import { RouterModule, Route, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router'; -import { AppComponent } from './app.component'; +import {BrowserModule} from '@angular/platform-browser'; +import {BrowserAnimationsModule} from '@angular/platform-browser/animations'; +import {LOCALE_ID, NgModule} from '@angular/core'; +import {FormsModule, ReactiveFormsModule} from '@angular/forms'; +import {ActivatedRouteSnapshot, Route, RouterModule, RouterStateSnapshot} from '@angular/router'; +import {AppComponent} from './app.component'; -import { ViewsModule } from './views/views.module'; -import { SharedModule } from './shared/shared.module'; +import {ViewsModule} from './views/views.module'; +import {SharedModule} from './shared/shared.module'; // main layout -import { HttpClientModule } from '@angular/common/http'; +import {HttpClientModule} from '@angular/common/http'; -import { MaterialModule } from './app.material.module'; - -import { SessionApiComponent } from './views/session-api/session-api.component'; -import { SessionDetailComponent, EnvRouter } from './views/session-detail/session-detail.component'; -import { DatePipe, DecimalPipe, registerLocaleData } from '@angular/common'; +import {DatePipe, DecimalPipe, registerLocaleData} from '@angular/common'; import localeFr from '@angular/common/locales/fr'; -import { SessionMainComponent } from './views/session-main/session-main.component'; -import { TreeComponent } from './views/tree/tree.component'; -import { StatsDatabaseComponent } from './views/stats-database/stats-database.component'; -import { StatsAppComponent } from './views/stats-app/stats-app.component'; -import { StatsApiComponent } from './views/stats-api/stats-api.component'; -import { StatsUserComponent } from './views/stats-user/stats-user.component'; -import { DbRequestDetailComponent } from './views/db-request-detail/db-request-detail.component'; -import { DashboardComponent } from './views/dashboard/dashboard.component'; +import {TreeComponent} from './views/tree/tree.component'; +import {ApplicationComponent as StatisticApplicationComponent} from './views/statistic/application/application.component'; +import {UserComponent as StatisticUserComponent} from './views/statistic/user/user.component'; +import {DatabaseComponent as DetailDatabaseComponent} from './views/detail/database/database.component'; +import {DatabaseComponent as StatisticDatabaseComponent} from './views/statistic/database/database.component'; +import {DashboardComponent} from './views/dashboard/dashboard.component'; +import {RestComponent as SearchRestComponent} from "./views/search/rest/rest.component"; +import {RestComponent as StatisticRestComponent} from "./views/statistic/rest/rest.component"; +import {RestComponent as DetailSessionRestComponent} from "./views/detail/session/rest/rest.component"; +import {MainComponent as SearchMainComponent} from './views/search/main/main.component'; +import {MainComponent as DetailSessionMainComponent} from "./views/detail/session/main/main.component"; +import {EnvRouter} from "./service/router.service"; registerLocaleData(localeFr, 'fr-FR'); const routes: Route[] = [ { path: 'session', children: [ { - path: 'api', - component: SessionApiComponent, - title: 'Liste des API' + path: 'rest', + component: SearchRestComponent, + title: 'Appels REST', }, { - path: ':type/:id/tree', - component: TreeComponent, - title: 'Arbre d\'appels de la Session' + path: 'rest/:id_session', + component: DetailSessionRestComponent, + title: 'Detail de l\'appel REST' }, { - path: 'main', - component: SessionMainComponent, - title: 'Liste des Sessions' - }, - { - path: ':type/:id/database/:dbid', - component: DbRequestDetailComponent, - title: 'Detail de la requête SQL' + path: 'main/:type_main', + component: SearchMainComponent, + title: (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => { + if (route.paramMap.get('type_main') == 'batch') { + return 'Liste BATCH'; + } else if(route.paramMap.get('type_main') == 'startup') { + return 'Liste Lancement Serveur'; + } + return 'Liste Interaction Web'; + }, }, { - path: ':type/:id', - component: SessionDetailComponent, + path: 'main/:type_main/:id_session', + component: DetailSessionMainComponent, title: (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => { - if (route.paramMap.get('type') == 'main') { - return 'Detail de la Session'; + if (route.paramMap.get('type_main') == 'batch') { + return 'Detail Lancement BATCH'; + } else if (route.paramMap.get('type_main') == 'startup') { + return 'Detail Lancement Serveur'; } - return 'Detail de l\'API'; + return 'Detail Interaction Web'; }, }, - { path: '**', pathMatch: 'full', redirectTo: `/session/api` } + { + path: ':type_session/:id_session/tree', + component: TreeComponent, + title: 'Arbre d\'appels' + }, + { + path: ':type_session/:id_session/database/:id_database', + component: DetailDatabaseComponent, + title: 'Detail de la requête SQL' + }, + { path: '**', pathMatch: 'full', redirectTo: `/session/rest` } ] }, { - path: 'dashboard', - component: DashboardComponent, - title: 'Dashboard', + path: 'statistic', children: [ { path: 'app/:name', - component: StatsAppComponent, + component: StatisticApplicationComponent, title: 'Statistiques Serveur' }, { - path: 'api/:name', - component: StatsApiComponent, + path: 'rest/:name', + component: StatisticRestComponent, title: 'Statistiques API' }, { path: 'user/:name', - component: StatsUserComponent, + component: StatisticUserComponent, title: 'Statistiques Utilisateur' }, { path: 'database/:name', - component: StatsDatabaseComponent, + component: StatisticDatabaseComponent, title: 'Statistiques Base de Donnée' }, - // { path: '**', pathMatch: 'full', redirectTo: `/session/api` } + { path: '**', pathMatch: 'full', redirectTo: `/session/rest` } ] }, - { path: '**', pathMatch: 'full', redirectTo: `/session/api` } + { + path: 'dashboard', + component: DashboardComponent, + title: 'Dashboard' + }, + { path: '**', pathMatch: 'full', redirectTo: `/session/rest` } ]; @NgModule({ @@ -103,7 +120,6 @@ const routes: Route[] = [ HttpClientModule, ReactiveFormsModule, SharedModule, - MaterialModule, ViewsModule ], declarations: [ diff --git a/src/app/shared/model/chart.model.ts b/src/app/model/chart.model.ts similarity index 100% rename from src/app/shared/model/chart.model.ts rename to src/app/model/chart.model.ts diff --git a/src/app/shared/model/conf.model.ts b/src/app/model/conf.model.ts similarity index 100% rename from src/app/shared/model/conf.model.ts rename to src/app/model/conf.model.ts diff --git a/src/app/shared/model/v3/trace.model.ts b/src/app/model/trace.model.ts similarity index 94% rename from src/app/shared/model/v3/trace.model.ts rename to src/app/model/trace.model.ts index 5c78874..2710ca2 100644 --- a/src/app/shared/model/v3/trace.model.ts +++ b/src/app/model/trace.model.ts @@ -25,7 +25,7 @@ export interface RestSession extends RestRequest { export interface MainSession extends LocalRequest { id: string; type: string; - requests: Array; + requests: Array; queries: Array; stages: Array; ftpRequests: Array; @@ -62,7 +62,7 @@ export interface DatabaseRequest extends SessionStage { actions: Array; commands: Array; - idRequest: number; + id: number; completed: boolean; } @@ -122,23 +122,18 @@ export interface Mail { export interface RequestStage { name: string; - start: Date; - end: Date; + start: number; + end: number; exception: ExceptionInfo; } export interface SessionStage { user: string; - start: Date; - end: Date; + start: number; + end: number; threadName: string; } -export interface Session { - id: string; - -} - export interface ExceptionInfo { type: string; message: string; @@ -153,6 +148,6 @@ export interface InstanceEnvironment { re: string; user: string; type: string; - instant: Date; + instant: number; collector: string; } \ No newline at end of file diff --git a/src/app/shared/services/filter.service.ts b/src/app/service/filter.service.ts similarity index 100% rename from src/app/shared/services/filter.service.ts rename to src/app/service/filter.service.ts diff --git a/src/app/shared/services/jquery.service.ts b/src/app/service/jquery.service.ts similarity index 100% rename from src/app/shared/services/jquery.service.ts rename to src/app/service/jquery.service.ts diff --git a/src/app/service/router.service.ts b/src/app/service/router.service.ts new file mode 100644 index 0000000..766568c --- /dev/null +++ b/src/app/service/router.service.ts @@ -0,0 +1,48 @@ +import {Injectable} from "@angular/core"; +import {NavigationExtras, Router} from "@angular/router"; +import {Observable} from "rxjs"; + +@Injectable() +export class EnvRouter { + + private _env: string; + + constructor(private router: Router) { } + + set env(env: string) { + this._env = env + } + + get events(): Observable { + return this.router.events; + }; + + get url(): string { + return this.router.url; + } + + + navigate(commands: any[], extras?: NavigationExtras): Promise { + if (!extras?.queryParams?.env) { + if (this._env) { + if (!extras) { + extras = {} + } + if (!extras.queryParams) { + extras.queryParams = {} + } + extras.queryParams.env = this._env; + } + } + else { + this.env = extras.queryParams.env; + } + return this.router.navigate(commands, extras); + // return Promise.resolve(true); + } + + open(url?: string | URL, target?: string, features?: string): WindowProxy | null { + return window.open(url, target, features); + } + +} \ No newline at end of file diff --git a/src/app/service/trace.service.ts b/src/app/service/trace.service.ts new file mode 100644 index 0000000..a900977 --- /dev/null +++ b/src/app/service/trace.service.ts @@ -0,0 +1,108 @@ +import { HttpClient, HttpErrorResponse } from "@angular/common/http"; +import { Injectable } from "@angular/core"; +import { Observable, catchError, throwError } from "rxjs"; +import { + DatabaseRequest, + DatabaseRequestStage, + FtpRequest, + InstanceEnvironment, + InstanceMainSession, + InstanceRestSession, + LocalRequest, MailRequest, MailRequestStage, NamingRequest, NamingRequestStage, + RestRequest, + RestSession +} from "../model/trace.model"; + +@Injectable({ providedIn: 'root' }) +export class TraceService { + + server = `${localStorage.getItem('server')}/v3/trace`; + + constructor(private http: HttpClient) { + } + + getRestSessions(params: any): Observable> { + return this.http.get>(`${this.server}/session/rest`, { params: params }); + } + + getRestSession(id: string): Observable { + return this.http.get(`${this.server}/session/rest/${id}`); + } + + getMainSessions(params: any): Observable> { + return this.http.get>(`${this.server}/session/main`, { params: params }); + } + + getMainSession(id: string): Observable { + return this.http.get(`${this.server}/session/main/${id}`); + } + + getTree(id: string, type: string) { + return type == "api" ? this.http.get(`${this.server}/session/rest/${id}/tree`) : + this.http.get(`${this.server}/session/main/${id}/tree`); + } + + getSessionParent(id: string): Observable<{ id: string, type: string }> { + return this.http.get<{ id: string, type: string }>(`${this.server}/session/rest/${id}/parent`) + } + + getRestRequests(id: string): Observable> { + return this.http.get>(`${this.server}/session/${id}/request/rest`); + } + + getDatabaseRequests(idSession: string): Observable>; + getDatabaseRequests(idSession: string, idDatabase: number): Observable; + getDatabaseRequests(idSession: string, idDatabase?: number): Observable { + if(idDatabase) + return this.http.get(`${this.server}/session/${idSession}/request/database/${idDatabase}`); + return this.http.get(`${this.server}/session/${idSession}/request/database`); + } + + getDatabaseRequestStages(idSession: string, idDatabase: number): Observable> { + return this.http.get>(`${this.server}/session/${idSession}/request/database/${idDatabase}/stage`); + }; + + getFtpRequests(idSession: string): Observable>; + getFtpRequests(idSession: string, idFtp: number): Observable; + getFtpRequests(idSession: string, idFtp?: number): Observable { + if(idFtp) + return this.http.get(`${this.server}/session/${idSession}/request/ftp/${idFtp}`); + return this.http.get(`${this.server}/session/${idSession}/request/ftp`); + } + + getFtpRequestStages(idSession: string, idFtp: number): Observable> { + return this.http.get>(`${this.server}/session/${idSession}/request/ftp/${idFtp}/stage`); + }; + + getSmtpRequests(idSession: string): Observable>; + getSmtpRequests(idSession: string, idSmtp: number): Observable; + getSmtpRequests(idSession: string, idSmtp?: number): Observable { + if(idSmtp) + return this.http.get(`${this.server}/session/${idSession}/request/smtp/${idSmtp}`); + return this.http.get(`${this.server}/session/${idSession}/request/smtp`); + } + + getSmtpRequestStages(idSession: string, idSmtp: number): Observable> { + return this.http.get>(`${this.server}/session/${idSession}/request/smtp/${idSmtp}/stage`); + }; + + getLdapRequests(idSession: string): Observable>; + getLdapRequests(idSession: string, idLdap: number): Observable; + getLdapRequests(idSession: string, idLdap?: number): Observable { + if(idLdap) + return this.http.get(`${this.server}/session/${idSession}/request/smtp/${idLdap}`); + return this.http.get(`${this.server}/session/${idSession}/request/smtp`); + } + + getLdapRequestStages(idSession: string, idLdap: number): Observable> { + return this.http.get>(`${this.server}/session/${idSession}/request/smtp/${idLdap}/stage`); + }; + + getLocalRequests(id: string): Observable> { + return this.http.get>(`${this.server}/session/${id}/request/local`); + } + + getInstance(id: string): Observable { + return this.http.get(`${this.server}/instance/${id}`); + } +} \ No newline at end of file diff --git a/src/app/shared/components/stats/advanced-filter/advanced-filter-modal/advanced-filter-modal.component.html b/src/app/shared/_component/advanced-filter/advanced-filter-modal/advanced-filter-modal.component.html similarity index 100% rename from src/app/shared/components/stats/advanced-filter/advanced-filter-modal/advanced-filter-modal.component.html rename to src/app/shared/_component/advanced-filter/advanced-filter-modal/advanced-filter-modal.component.html diff --git a/src/app/shared/components/stats/advanced-filter/advanced-filter-modal/advanced-filter-modal.component.scss b/src/app/shared/_component/advanced-filter/advanced-filter-modal/advanced-filter-modal.component.scss similarity index 100% rename from src/app/shared/components/stats/advanced-filter/advanced-filter-modal/advanced-filter-modal.component.scss rename to src/app/shared/_component/advanced-filter/advanced-filter-modal/advanced-filter-modal.component.scss diff --git a/src/app/shared/components/stats/advanced-filter/advanced-filter-modal/advanced-filter-modal.component.ts b/src/app/shared/_component/advanced-filter/advanced-filter-modal/advanced-filter-modal.component.ts similarity index 97% rename from src/app/shared/components/stats/advanced-filter/advanced-filter-modal/advanced-filter-modal.component.ts rename to src/app/shared/_component/advanced-filter/advanced-filter-modal/advanced-filter-modal.component.ts index 9e74ae1..a1443a3 100644 --- a/src/app/shared/components/stats/advanced-filter/advanced-filter-modal/advanced-filter-modal.component.ts +++ b/src/app/shared/_component/advanced-filter/advanced-filter-modal/advanced-filter-modal.component.ts @@ -5,9 +5,9 @@ import { MAT_DIALOG_DATA, MatDialogRef } from "@angular/material/dialog"; import { Filter, FilterMap, FilterPreset } from "src/app/views/constants"; import { COMMA, ENTER } from '@angular/cdk/keycodes'; import { Subscription, catchError, finalize, of } from "rxjs"; -import { JQueryService } from "src/app/shared/services/jquery.service"; +import { JQueryService } from "src/app/service/jquery.service"; import { MatAutocompleteSelectedEvent } from "@angular/material/autocomplete"; -import { FilterService } from "src/app/shared/services/filter.service"; +import { FilterService } from "src/app/service/filter.service"; @Component({ templateUrl: './advanced-filter-modal.component.html', diff --git a/src/app/shared/components/stats/advanced-filter/advanced-filter-recap/advanced-filter-recap.component.html b/src/app/shared/_component/advanced-filter/advanced-filter-recap/advanced-filter-recap.component.html similarity index 100% rename from src/app/shared/components/stats/advanced-filter/advanced-filter-recap/advanced-filter-recap.component.html rename to src/app/shared/_component/advanced-filter/advanced-filter-recap/advanced-filter-recap.component.html diff --git a/src/app/shared/components/stats/advanced-filter/advanced-filter-recap/advanced-filter-recap.component.scss b/src/app/shared/_component/advanced-filter/advanced-filter-recap/advanced-filter-recap.component.scss similarity index 100% rename from src/app/shared/components/stats/advanced-filter/advanced-filter-recap/advanced-filter-recap.component.scss rename to src/app/shared/_component/advanced-filter/advanced-filter-recap/advanced-filter-recap.component.scss diff --git a/src/app/shared/components/stats/advanced-filter/advanced-filter-recap/advanced-filter-recap.component.ts b/src/app/shared/_component/advanced-filter/advanced-filter-recap/advanced-filter-recap.component.ts similarity index 100% rename from src/app/shared/components/stats/advanced-filter/advanced-filter-recap/advanced-filter-recap.component.ts rename to src/app/shared/_component/advanced-filter/advanced-filter-recap/advanced-filter-recap.component.ts diff --git a/src/app/shared/components/stats/advanced-filter/advanced-filter-trigger/advanced-filter-trigger.component.html b/src/app/shared/_component/advanced-filter/advanced-filter-trigger/advanced-filter-trigger.component.html similarity index 100% rename from src/app/shared/components/stats/advanced-filter/advanced-filter-trigger/advanced-filter-trigger.component.html rename to src/app/shared/_component/advanced-filter/advanced-filter-trigger/advanced-filter-trigger.component.html diff --git a/src/app/shared/components/stats/advanced-filter/advanced-filter-trigger/advanced-filter-trigger.component.scss b/src/app/shared/_component/advanced-filter/advanced-filter-trigger/advanced-filter-trigger.component.scss similarity index 100% rename from src/app/shared/components/stats/advanced-filter/advanced-filter-trigger/advanced-filter-trigger.component.scss rename to src/app/shared/_component/advanced-filter/advanced-filter-trigger/advanced-filter-trigger.component.scss diff --git a/src/app/shared/components/stats/advanced-filter/advanced-filter-trigger/advanced-filter-trigger.component.ts b/src/app/shared/_component/advanced-filter/advanced-filter-trigger/advanced-filter-trigger.component.ts similarity index 98% rename from src/app/shared/components/stats/advanced-filter/advanced-filter-trigger/advanced-filter-trigger.component.ts rename to src/app/shared/_component/advanced-filter/advanced-filter-trigger/advanced-filter-trigger.component.ts index 81776d1..a4d164b 100644 --- a/src/app/shared/components/stats/advanced-filter/advanced-filter-trigger/advanced-filter-trigger.component.ts +++ b/src/app/shared/_component/advanced-filter/advanced-filter-trigger/advanced-filter-trigger.component.ts @@ -2,7 +2,7 @@ import { Component, EventEmitter, Input, OnInit, Output, ViewChild, inject } fro import { Filter, FilterConstants, FilterPreset, FilterMap } from "src/app/views/constants"; import { AdvancedFilterComponent } from "../advanced-filter-modal/advanced-filter-modal.component"; import { MatDialog } from "@angular/material/dialog"; -import { FilterService } from "src/app/shared/services/filter.service"; +import { FilterService } from "src/app/service/filter.service"; import { MatMenuTrigger } from "@angular/material/menu"; import { Subscription, finalize, firstValueFrom, throwError } from "rxjs"; import { error } from "console"; diff --git a/src/app/shared/components/header-page/header-page.component.html b/src/app/shared/_component/header-page/header-page.component.html similarity index 100% rename from src/app/shared/components/header-page/header-page.component.html rename to src/app/shared/_component/header-page/header-page.component.html diff --git a/src/app/shared/components/header-page/header-page.component.scss b/src/app/shared/_component/header-page/header-page.component.scss similarity index 100% rename from src/app/shared/components/header-page/header-page.component.scss rename to src/app/shared/_component/header-page/header-page.component.scss diff --git a/src/app/shared/components/header-page/header-page.component.ts b/src/app/shared/_component/header-page/header-page.component.ts similarity index 100% rename from src/app/shared/components/header-page/header-page.component.ts rename to src/app/shared/_component/header-page/header-page.component.ts diff --git a/src/app/app.material.module.ts b/src/app/shared/material/material.module.ts similarity index 100% rename from src/app/app.material.module.ts rename to src/app/shared/material/material.module.ts diff --git a/src/app/shared/model/trace.model.ts b/src/app/shared/model/trace.model.ts deleted file mode 100644 index 9c365f5..0000000 --- a/src/app/shared/model/trace.model.ts +++ /dev/null @@ -1,89 +0,0 @@ -export interface Request { - id: string; - user: string; - start: number; - end: number; - threadName: string; - application: ApplicationInfo; - exception: ExceptionInfo; - requests: OutcomingRequest[]; - queries: OutcomingQuery[]; - stages: RunnableStage[]; -} - -export interface RestRequest extends Request{ - method: string; - protocol: string; - host: string; - port: number; - path: string; - query: string; - contentType: string; - authScheme: string; - status: number; - inDataSize: number; - outDataSize: number; -} - -export interface MainRequest extends Request { - name: string; - launchMode: string; - location: string; -} - -export interface IncomingRequest extends RestRequest { - name: string; -} - -export interface OutcomingRequest extends RestRequest { - -} - -export interface ApplicationInfo { - name: string; - version: string; - address: string; - env: string; - os: string; - re: string; -} - -export interface OutcomingQuery { - host: string; - port: number; - scheme: string; - start: Date; - end: Date; - user: string; - threadName: string; - driverVersion: string; - databaseName: string; - databaseVersion: string; - completed: boolean; - actions: DatabaseAction[] -} - -export interface DatabaseAction { - type: string; - start: Date; - end: Date; - exception: ExceptionInfo; - count: number; -} - -export interface ExceptionInfo { - classname: string; - message: string; -} - -export interface RunnableStage { - name: string; - location: string; - start: number; - end: number; - user: string; - threadName: string; - exception: ExceptionInfo; -} - - diff --git a/src/app/shared/services/trace.service.ts b/src/app/shared/services/trace.service.ts deleted file mode 100644 index e4d6c0d..0000000 --- a/src/app/shared/services/trace.service.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { HttpClient, HttpErrorResponse } from "@angular/common/http"; -import { Injectable } from "@angular/core"; -import { Observable, catchError, throwError } from "rxjs"; -import { DatabaseRequest, DatabaseRequestStage, InstanceEnvironment, InstanceMainSession, InstanceRestSession, LocalRequest, RestRequest, RestSession } from "../model/v3/trace.model"; - -@Injectable({ providedIn: 'root' }) -export class TraceService { - readonly INCOMING_REQUEST_URL = `${localStorage.getItem('server')}/v3/trace/session/rest`; - readonly MAIN_REQUEST_URL = `${localStorage.getItem('server')}/v3/trace/session/main`; - - constructor(private http: HttpClient) { - } - - getRestSessions(params: any): Observable> { - return this.http.get>(`${localStorage.getItem('server')}/v3/trace/session/rest`, { params: params }); - } - - getRestSession(id: string) { - return this.http.get(`${localStorage.getItem('server')}/v3/trace/session/rest/${id}`); - } - - getMainSessions(params: any): Observable> { - return this.http.get>(`${localStorage.getItem('server')}/v3/trace/session/main`, { params: params }); - } - - getMainSession(id: string) { - return this.http.get(`${localStorage.getItem('server')}/v3/trace/session/main/${id}`); - } - - getTree(id: string, type: string) { - return type == "api" ? this.http.get(`${localStorage.getItem('server')}/v3/trace/session/rest/${id}/tree`) : - this.http.get(`${localStorage.getItem('server')}/v3/trace/session/main/${id}/tree`); - } - - getSessionParentByChildId(id: string): Observable<{ id: string, type: string }> { - return this.http.get<{ id: string, type: string }>(`${localStorage.getItem('server')}/v3/trace/session/rest/${id}/parent`) - } - - getRestRequests(id: string): Observable> { - return this.http.get>(`${localStorage.getItem('server')}/v3/trace/session/${id}/request/rest`); - } - - getDatabaseRequests(idSession: string): Observable>; - getDatabaseRequests(idSession: string, idDatabase: number): Observable; - getDatabaseRequests(idSession: string, idDatabase?: number): Observable { - if(idDatabase) - return this.http.get(`${localStorage.getItem('server')}/v3/trace/session/${idSession}/request/database/${idDatabase}`); - return this.http.get(`${localStorage.getItem('server')}/v3/trace/session/${idSession}/request/database`); - } - - getDatabaseRequestStages(idSession: string, idDatabase: number): Observable> { - return this.http.get>(`${localStorage.getItem('server')}/v3/trace/session/${idSession}/request/database/${idDatabase}/stage`); - }; - - getLocalRequests(id: string): Observable> { - return this.http.get>(`${localStorage.getItem('server')}/v3/trace/session/${id}/request/local`); - } - - getInstance(id: string): Observable { - return this.http.get(`${localStorage.getItem('server')}/v3/trace/instance/${id}`); - } -} \ No newline at end of file diff --git a/src/app/shared/shared.module.ts b/src/app/shared/shared.module.ts index edc2afd..dcae002 100644 --- a/src/app/shared/shared.module.ts +++ b/src/app/shared/shared.module.ts @@ -1,11 +1,11 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; -import { HeaderPageComponent } from './components/header-page/header-page.component'; -import { MaterialModule } from '../app.material.module'; +import { HeaderPageComponent } from './_component/header-page/header-page.component'; +import { MaterialModule } from './material/material.module'; import { FilterRowPipe } from './pipe/filter-row.pipe'; -import { AdvancedFilterTriggerComponent } from './components/stats/advanced-filter/advanced-filter-trigger/advanced-filter-trigger.component'; -import { AdvancedFilterRecapComponent } from './components/stats/advanced-filter/advanced-filter-recap/advanced-filter-recap.component'; -import { AdvancedFilterComponent } from './components/stats/advanced-filter/advanced-filter-modal/advanced-filter-modal.component'; +import { AdvancedFilterTriggerComponent } from './_component/advanced-filter/advanced-filter-trigger/advanced-filter-trigger.component'; +import { AdvancedFilterRecapComponent } from './_component/advanced-filter/advanced-filter-recap/advanced-filter-recap.component'; +import { AdvancedFilterComponent } from './_component/advanced-filter/advanced-filter-modal/advanced-filter-modal.component'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { DurationPipe } from './pipe/duration.pipe'; import { SizePipe } from './pipe/size.pipe'; @@ -27,6 +27,7 @@ import { SizePipe } from './pipe/size.pipe'; SizePipe ], exports: [ + MaterialModule, HeaderPageComponent, AdvancedFilterComponent, AdvancedFilterRecapComponent, diff --git a/src/app/shared/util.ts b/src/app/shared/util.ts index 94990b4..267b74f 100644 --- a/src/app/shared/util.ts +++ b/src/app/shared/util.ts @@ -1,7 +1,7 @@ import { DatePipe } from "@angular/common"; -import { ChartGroup } from "./model/chart.model"; +import { ChartGroup } from "../model/chart.model"; import { Filter, FilterMap, Operation } from "../views/constants"; -import { InstanceRestSession } from "./model/v3/trace.model"; +import { InstanceRestSession } from "../model/trace.model"; export class Utils { diff --git a/src/app/views/dashboard/dashboard.component.ts b/src/app/views/dashboard/dashboard.component.ts index f0a49ba..4d0c9be 100644 --- a/src/app/views/dashboard/dashboard.component.ts +++ b/src/app/views/dashboard/dashboard.component.ts @@ -1,11 +1,11 @@ import { Component } from '@angular/core'; import { MatTableDataSource } from '@angular/material/table'; import { ActivatedRoute } from '@angular/router'; -import { TraceService } from 'src/app/shared/services/trace.service'; -import { EnvRouter } from '../session-detail/session-detail.component'; +import { TraceService } from 'src/app/service/trace.service'; import { combineLatest } from 'rxjs'; import { Location } from '@angular/common'; import { application } from 'src/environments/environment'; +import {EnvRouter} from "../../service/router.service"; @Component({ templateUrl: './dashboard.component.html', diff --git a/src/app/views/db-request-detail/db-request-detail.component.html b/src/app/views/detail/database/database.component.html similarity index 100% rename from src/app/views/db-request-detail/db-request-detail.component.html rename to src/app/views/detail/database/database.component.html diff --git a/src/app/views/db-request-detail/db-request-detail.component.scss b/src/app/views/detail/database/database.component.scss similarity index 100% rename from src/app/views/db-request-detail/db-request-detail.component.scss rename to src/app/views/detail/database/database.component.scss diff --git a/src/app/views/db-request-detail/db-request-detail.component.ts b/src/app/views/detail/database/database.component.ts similarity index 92% rename from src/app/views/db-request-detail/db-request-detail.component.ts rename to src/app/views/detail/database/database.component.ts index 68e3d76..3e4a035 100644 --- a/src/app/views/db-request-detail/db-request-detail.component.ts +++ b/src/app/views/detail/database/database.component.ts @@ -3,20 +3,19 @@ import { Component, ElementRef, NgZone, OnDestroy, ViewChild } from '@angular/co import { ActivatedRoute } from '@angular/router'; import { combineLatest, forkJoin } from "rxjs"; import { Timeline } from 'vis-timeline'; -import { DatabaseAction } from 'src/app/shared/model/trace.model'; import { Utils } from 'src/app/shared/util'; import { DatePipe, Location } from '@angular/common'; -import { TraceService } from 'src/app/shared/services/trace.service'; +import { TraceService } from 'src/app/service/trace.service'; import { application } from 'src/environments/environment'; -import { EnvRouter } from '../session-detail/session-detail.component'; -import { DatabaseRequest, DatabaseRequestStage } from 'src/app/shared/model/v3/trace.model'; +import { DatabaseRequest, DatabaseRequestStage } from 'src/app/model/trace.model'; +import {EnvRouter} from "../../../service/router.service"; @Component({ - templateUrl: './db-request-detail.component.html', - styleUrls: ['./db-request-detail.component.scss'], + templateUrl: './database.component.html', + styleUrls: ['./database.component.scss'], }) -export class DbRequestDetailComponent implements OnDestroy { +export class DatabaseComponent implements OnDestroy { utils: Utils = new Utils; selectedQuery: DatabaseRequest; dbQueryId: number; @@ -57,9 +56,9 @@ export class DbRequestDetailComponent implements OnDestroy { this._activatedRoute.queryParams ]).subscribe({ next: ([params, queryParams]) => { - this.dbQueryId = params.dbid; - this.dbQueryParentId = params.id; - this.dbQueryParentType = params.type; + this.dbQueryId = params.id_database; + this.dbQueryParentId = params.id_session; + this.dbQueryParentType = params.type_session; this.env = queryParams.env || application.default_env; this._location.replaceState(`${this._router.url.split('?')[0]}?env=${this.env}`) this.getDbRequestById(); diff --git a/src/app/views/session-detail/components/request-database-table/request-database-table.component.html b/src/app/views/detail/session/_component/database-table/database-table.component.html similarity index 97% rename from src/app/views/session-detail/components/request-database-table/request-database-table.component.html rename to src/app/views/detail/session/_component/database-table/database-table.component.html index 5a5761c..e751ec4 100644 --- a/src/app/views/session-detail/components/request-database-table/request-database-table.component.html +++ b/src/app/views/detail/session/_component/database-table/database-table.component.html @@ -48,7 +48,7 @@ + (click)="selectedQuery($event, row.id)"> = new MatTableDataSource(); @@ -45,6 +45,7 @@ export class RequestDatabaseTableComponent implements OnInit { } selectedQuery(event: MouseEvent, row: number) { + console.log(row) this.onClickRow.emit({event: event, row: row}); } diff --git a/src/app/views/session-detail/components/request-rest-table/request-rest-table.component.html b/src/app/views/detail/session/_component/rest-table/rest-table.component.html similarity index 100% rename from src/app/views/session-detail/components/request-rest-table/request-rest-table.component.html rename to src/app/views/detail/session/_component/rest-table/rest-table.component.html diff --git a/src/app/views/session-detail/components/request-rest-table/request-rest-table.component.scss b/src/app/views/detail/session/_component/rest-table/rest-table.component.scss similarity index 100% rename from src/app/views/session-detail/components/request-rest-table/request-rest-table.component.scss rename to src/app/views/detail/session/_component/rest-table/rest-table.component.scss diff --git a/src/app/views/session-detail/components/request-rest-table/request-rest-table.component.ts b/src/app/views/detail/session/_component/rest-table/rest-table.component.ts similarity index 93% rename from src/app/views/session-detail/components/request-rest-table/request-rest-table.component.ts rename to src/app/views/detail/session/_component/rest-table/rest-table.component.ts index ca09448..18eada0 100644 --- a/src/app/views/session-detail/components/request-rest-table/request-rest-table.component.ts +++ b/src/app/views/detail/session/_component/rest-table/rest-table.component.ts @@ -2,15 +2,15 @@ import { Component, EventEmitter, Input, OnInit, Output, ViewChild, inject } fro import { MatPaginator } from "@angular/material/paginator"; import { MatSort } from "@angular/material/sort"; import { MatTableDataSource } from "@angular/material/table"; -import { RestRequest } from "src/app/shared/model/v3/trace.model"; +import { RestRequest } from "src/app/model/trace.model"; import { Utils } from "src/app/shared/util"; @Component({ selector: 'request-rest-table', - templateUrl: './request-rest-table.component.html', - styleUrls: ['./request-rest-table.component.scss'] + templateUrl: './rest-table.component.html', + styleUrls: ['./rest-table.component.scss'] }) -export class RequestRestTableComponent implements OnInit { +export class RestTableComponent implements OnInit { displayedColumns: string[] = ['status', 'host', 'path', 'start', 'duree']; dataSource: MatTableDataSource = new MatTableDataSource(); filterTable = new Map(); diff --git a/src/app/views/session-detail/components/request-timeline/request-timeline.component.html b/src/app/views/detail/session/_component/timeline/timeline.component.html similarity index 100% rename from src/app/views/session-detail/components/request-timeline/request-timeline.component.html rename to src/app/views/detail/session/_component/timeline/timeline.component.html diff --git a/src/app/views/session-detail/components/request-timeline/request-timeline.component.scss b/src/app/views/detail/session/_component/timeline/timeline.component.scss similarity index 100% rename from src/app/views/session-detail/components/request-timeline/request-timeline.component.scss rename to src/app/views/detail/session/_component/timeline/timeline.component.scss diff --git a/src/app/views/session-detail/components/request-timeline/request-timeline.component.ts b/src/app/views/detail/session/_component/timeline/timeline.component.ts similarity index 94% rename from src/app/views/session-detail/components/request-timeline/request-timeline.component.ts rename to src/app/views/detail/session/_component/timeline/timeline.component.ts index d6e8e9b..398401b 100644 --- a/src/app/views/session-detail/components/request-timeline/request-timeline.component.ts +++ b/src/app/views/detail/session/_component/timeline/timeline.component.ts @@ -1,15 +1,15 @@ import { DatePipe } from "@angular/common"; import { Component, ElementRef, Input, OnChanges, OnInit, SimpleChanges, ViewChild, inject } from "@angular/core"; import { Timeline } from "vis-timeline"; -import { EnvRouter } from "../../session-detail.component"; -import { DatabaseRequest, InstanceEnvironment, InstanceMainSession, InstanceRestSession, LocalRequest, RestRequest } from "src/app/shared/model/v3/trace.model"; +import { DatabaseRequest, InstanceEnvironment, InstanceMainSession, InstanceRestSession, LocalRequest, RestRequest } from "src/app/model/trace.model"; +import {EnvRouter} from "../../../../../service/router.service"; @Component({ selector: 'request-timeline-table', - templateUrl: './request-timeline.component.html', - styleUrls: ['./request-timeline.component.scss'] + templateUrl: './timeline.component.html', + styleUrls: ['./timeline.component.scss'] }) -export class RequestTimelineComponent implements OnChanges { +export class TimelineComponent implements OnChanges { private _router: EnvRouter = inject(EnvRouter); timeline: any; diff --git a/src/app/views/detail/session/main/main.component.html b/src/app/views/detail/session/main/main.component.html new file mode 100644 index 0000000..8834c0e --- /dev/null +++ b/src/app/views/detail/session/main/main.component.html @@ -0,0 +1,121 @@ +
+
+ + + + settings_suggest + {{ '[' + session.type + '] ' + session.name || 'N/A' }} + +
+ + +
+
+ + + + {{ session.location }} + + + + + person +
+ + {{ session.user || "N/A" }} + + le {{ (session.start * 1000) | date: 'dd/MM/yyyy à HH:mm:ss.SSS': 'fr' }} +
+
+
+ + + + storage + {{instance.name}} + +
+ +
+
+ +
+
+ Database +
+
+ + {{ item.key }} + +
+ {{ item.value[0].productName }} v.{{ item.value[0].productVersion }} +
+
+
+
+ +
+ {{instance.address}} en {{instance.env}} +
+ + {{instance.os}} + + + {{instance.re}} + +
+
+
+
+
+ +
+ west +
REST
+
+ +
+ +
+
+
+ +
+ Database +
Base de + donnée
+
+ +
+ +
+
+
+ +
+ view_timeline + Chronologie +
+ +
+ +
+
\ No newline at end of file diff --git a/src/app/views/detail/session/main/main.component.scss b/src/app/views/detail/session/main/main.component.scss new file mode 100644 index 0000000..434f184 --- /dev/null +++ b/src/app/views/detail/session/main/main.component.scss @@ -0,0 +1,73 @@ +.header-card { + display: flex; + flex-direction: row; + gap: 0.5em; + margin-bottom: 2em; +} + +a { + color: inherit; + text-decoration: none; +} + +mat-card-title { + display: flex; + align-items: center; + padding: 0 16px; + height: 48px; + .right { + margin-left: auto; + } +} + +mat-card-content { + height: 100%; padding: 0 16px 16px; +} + +mat-card-footer { + padding: 0 16px; + border: 1px solid rgba(0,0,0,.05); + display: flex; + align-items: center; + gap: 0.5em; + font-style: italic; + font-size: 14px; + .right { + margin-left: auto; + display: flex; + align-items: center; + } +} + + +table { + table-layout: auto; +} +.dbfailed { + background-color: red !important; +} + +.mat-mdc-row .mat-mdc-cell { + cursor: pointer; +} + +.mat-mdc-row:hover .mat-mdc-cell { + background-color: rgb(206, 206, 206); +} + +.mat-mdc-table .mdc-data-table__header-row { + background-color: #d1d1d1; +} + +.url { + color: blue; + text-decoration: solid; +} + +.badge { + color: white; + padding: 0px 10px; + text-align: center; + border-radius: 12px; + font-size: 0.8em; +} \ No newline at end of file diff --git a/src/app/views/detail/session/main/main.component.ts b/src/app/views/detail/session/main/main.component.ts new file mode 100644 index 0000000..a9e8fa7 --- /dev/null +++ b/src/app/views/detail/session/main/main.component.ts @@ -0,0 +1,133 @@ +import {Component, inject, OnDestroy, OnInit} from "@angular/core"; +import {InstanceEnvironment, InstanceMainSession, InstanceRestSession} from "../../../../model/trace.model"; +import {ActivatedRoute} from "@angular/router"; +import {TraceService} from "../../../../service/trace.service"; +import {EnvRouter} from "../../../../service/router.service"; +import {Location} from "@angular/common"; +import {catchError, combineLatest, finalize, forkJoin, of, Subscription, switchMap} from "rxjs"; +import {application} from "../../../../../environments/environment"; + +@Component({ + templateUrl: './main.component.html', + styleUrls: ['./main.component.scss'], +}) +export class MainComponent implements OnInit, OnDestroy { + private _activatedRoute: ActivatedRoute = inject(ActivatedRoute); + private _traceService: TraceService = inject(TraceService); + private _router: EnvRouter = inject(EnvRouter); + private _location: Location = inject(Location); + + session: InstanceMainSession; + instance: InstanceEnvironment; + sessionParent: { id: string, type: string }; + isLoading: boolean = false; + subscriptions: Array = []; + queryBySchema: any[]; + env: string; + + ngOnInit() { + this.subscriptions.push(combineLatest([ + this._activatedRoute.params, + this._activatedRoute.queryParams + ]).subscribe({ + next: ([params, queryParams]) => { + this.env = queryParams.env || application.default_env; + this.getSession(params.id_session); + this._location.replaceState(`${this._router.url.split('?')[0]}?env=${this.env}`) + } + })); + } + + getSession(id: string) { + this.isLoading = true; + this.session = null; + this._traceService.getMainSession(id).pipe( + switchMap(s => { + return forkJoin({ + session: of(s), + instance: this._traceService.getInstance(s.instanceId), + parent: this._traceService.getSessionParent(id).pipe(catchError(() => of(null))), + requests: this._traceService.getRestRequests(s.id), + queries: this._traceService.getDatabaseRequests(s.id), + stages: this._traceService.getLocalRequests(s.id) + }); + }), + finalize(() => this.isLoading = false) + ) + .subscribe({ + next: (result) => { + if(result){ + this.session = result.session; + this.session.requests = result.requests; + this.session.queries = result.queries; + this.session.stages = result.stages; + this.instance = result.instance; + this.sessionParent = result.parent; + this.groupQueriesBySchema(); + } + } + }); + } + + groupQueriesBySchema() { + if (this.session.queries) { + this.queryBySchema = this.session.queries.reduce((acc: any, item) => { + if (!acc[item.name]) { + acc[item.name] = [] + } + acc[item.name].push(item); + return acc; + }, []); + } + } + + selectedRequest(event: { event: MouseEvent, row: any }) { + if (event.row) { + if (event.event.ctrlKey) { + this._router.open(`#/session/rest/${event.row}`, '_blank',) + } else { + this._router.navigate(['/session', 'rest', event.row], { queryParams: { env: this.env } }); // TODO remove env FIX BUG + } + } + } + + selectedQuery(event: { event: MouseEvent, row: any }) { // TODO finish this + if (event.row) { + if (event.event.ctrlKey) { + this._router.open(`#/session/main/${this.session.id}/database/${event.row}`, '_blank',) + } else { + this._router.navigate(['/session/main', this.session.id, 'database', event.row], { + queryParams: { env: this.instance.env } + }); + } + } + } + + navigate(event: MouseEvent, targetType: string, extraParam?: string) { + let params: any[] = []; + switch (targetType) { + case "rest": + params.push('statistic', 'rest', this.session.name); + break; + case "app": + params.push('statistic', 'app', this.session.appName) + break; + case "tree": + params.push('session', 'main', this.session.id, 'tree') + break; + case "parent": + params.push('session', this.sessionParent.type, this.sessionParent.id) + } + if (event.ctrlKey) { + this._router.open(`#/${params.join('/')}`, '_blank') + } else { + this._router.navigate(params, { + queryParams: { env: this.instance.env } + }); + } + } + + ngOnDestroy() { + this.subscriptions.forEach(s => s.unsubscribe()); + } +} \ No newline at end of file diff --git a/src/app/views/detail/session/rest/rest.component.html b/src/app/views/detail/session/rest/rest.component.html new file mode 100644 index 0000000..57b8685 --- /dev/null +++ b/src/app/views/detail/session/rest/rest.component.html @@ -0,0 +1,129 @@ +
+
+ + + + settings_suggest + {{ session.name|| 'N/A' }} + +
+ + +
+
+ + + +
+ warning + {{ session.exception?.message || session.exception?.type }} +
+
+ + person +
+ + {{ session.user || "N/A" }} + + le {{ (session.start * 1000) | date: 'dd/MM/yyyy à HH:mm:ss.SSS': 'fr' }} +
+
+ {{ session.inDataSize || 0 }}o + swap_vert + {{ session.outDataSize }}o en {{ session.end - session.start | number :'1.2-3' }}s +
+ {{session.status}} + +
+
+ + + + storage + {{instance.name}} + +
+ +
+
+ +
+
+ Database +
+
+ + {{ item.key }} + +
+ {{ item.value[0].productName }} v.{{ item.value[0].productVersion }} +
+
+
+
+ +
+ {{instance.address}} en {{instance.env}} +
+ + {{instance.os}} + + + {{instance.re}} + +
+
+
+
+
+ +
+ west +
REST
+
+ +
+ +
+
+
+ +
+ Database +
Base de donnée
+
+ +
+ + +
+
\ No newline at end of file diff --git a/src/app/views/detail/session/rest/rest.component.scss b/src/app/views/detail/session/rest/rest.component.scss new file mode 100644 index 0000000..434f184 --- /dev/null +++ b/src/app/views/detail/session/rest/rest.component.scss @@ -0,0 +1,73 @@ +.header-card { + display: flex; + flex-direction: row; + gap: 0.5em; + margin-bottom: 2em; +} + +a { + color: inherit; + text-decoration: none; +} + +mat-card-title { + display: flex; + align-items: center; + padding: 0 16px; + height: 48px; + .right { + margin-left: auto; + } +} + +mat-card-content { + height: 100%; padding: 0 16px 16px; +} + +mat-card-footer { + padding: 0 16px; + border: 1px solid rgba(0,0,0,.05); + display: flex; + align-items: center; + gap: 0.5em; + font-style: italic; + font-size: 14px; + .right { + margin-left: auto; + display: flex; + align-items: center; + } +} + + +table { + table-layout: auto; +} +.dbfailed { + background-color: red !important; +} + +.mat-mdc-row .mat-mdc-cell { + cursor: pointer; +} + +.mat-mdc-row:hover .mat-mdc-cell { + background-color: rgb(206, 206, 206); +} + +.mat-mdc-table .mdc-data-table__header-row { + background-color: #d1d1d1; +} + +.url { + color: blue; + text-decoration: solid; +} + +.badge { + color: white; + padding: 0px 10px; + text-align: center; + border-radius: 12px; + font-size: 0.8em; +} \ No newline at end of file diff --git a/src/app/views/detail/session/rest/rest.component.ts b/src/app/views/detail/session/rest/rest.component.ts new file mode 100644 index 0000000..faec0e4 --- /dev/null +++ b/src/app/views/detail/session/rest/rest.component.ts @@ -0,0 +1,137 @@ +import {Component, inject, OnDestroy, OnInit} from "@angular/core"; +import {InstanceEnvironment, InstanceRestSession} from "../../../../model/trace.model"; +import {ActivatedRoute} from "@angular/router"; +import {TraceService} from "../../../../service/trace.service"; +import {Location} from "@angular/common"; +import {catchError, combineLatest, finalize, forkJoin, of, Subscription, switchMap} from "rxjs"; +import {application} from "../../../../../environments/environment"; +import {Utils} from "../../../../shared/util"; +import {EnvRouter} from "../../../../service/router.service"; + +@Component({ + templateUrl: './rest.component.html', + styleUrls: ['./rest.component.scss'], +}) +export class RestComponent implements OnInit, OnDestroy { + private _activatedRoute: ActivatedRoute = inject(ActivatedRoute); + private _traceService: TraceService = inject(TraceService); + private _router: EnvRouter = inject(EnvRouter); + private _location: Location = inject(Location); + + session: InstanceRestSession; + instance: InstanceEnvironment; + sessionParent: { id: string, type: string }; + isLoading: boolean = false; + subscriptions: Array = []; + queryBySchema: any[]; + env: string; + + ngOnInit() { + this.subscriptions.push(combineLatest([ + this._activatedRoute.params, + this._activatedRoute.queryParams + ]).subscribe({ + next: ([params, queryParams]) => { + this.env = queryParams.env || application.default_env; + this.getSession(params.id_session); + this._location.replaceState(`${this._router.url.split('?')[0]}?env=${this.env}`) + } + })); + } + + getSession(id: string) { + this.isLoading = true; + this.session = null; + this._traceService.getRestSession(id) + .pipe( + switchMap(s => { + return forkJoin({ + session: of(s), + instance: this._traceService.getInstance(s.instanceId), + parent: this._traceService.getSessionParent(id).pipe(catchError(() => of(null))), + requests: this._traceService.getRestRequests(s.id), + queries: this._traceService.getDatabaseRequests(s.id), + stages: this._traceService.getLocalRequests(s.id) + }); + }), + finalize(() => this.isLoading = false) + ) + .subscribe({ + next: result => { + this.session = result.session; + this.session.requests = result.requests; + this.session.queries = result.queries; + this.session.stages = result.stages; + this.instance = result.instance; + this.sessionParent = result.parent; + this.groupQueriesBySchema(); + } + }); + } + + selectedRequest(event: { event: MouseEvent, row: any }) { + if (event.row) { + if (event.event.ctrlKey) { + this._router.open(`#/session/rest/${event.row}`, '_blank',) + } else { + this._router.navigate(['/session', 'rest', event.row], { queryParams: { env: this.env } }); // TODO remove env FIX BUG + } + } + } + + selectedQuery(event: { event: MouseEvent, row: any }) { // TODO finish this + if (event.row) { + if (event.event.ctrlKey) { + this._router.open(`#/session/rest/${this.session.id}/database/${event.row}`, '_blank',) + } else { + this._router.navigate(['/session/rest', this.session.id, 'database', event.row], { + queryParams: { env: this.instance.env } + }); + } + } + } + + groupQueriesBySchema() { + if (this.session.queries) { + this.queryBySchema = this.session.queries.reduce((acc: any, item) => { + if (!acc[item.name]) { + acc[item.name] = [] + } + acc[item.name].push(item); + return acc; + }, []); + } + } + + getSessionUrl() { + return Utils.getSessionUrl(this.session); + } + + navigate(event: MouseEvent, targetType: string, extraParam?: string) { + let params: any[] = []; + switch (targetType) { + case "rest": + params.push('statistic', 'rest', this.session.name); + break; + case "app": + params.push('statistic', 'app', this.session.appName) + break; + case "tree": + params.push('session/rest', this.session.id, 'tree') + break; + case "parent": + params.push('session', this.sessionParent.type, this.sessionParent.id) + } + if (event.ctrlKey) { + this._router.open(`#/${params.join('/')}`, '_blank') + } else { + this._router.navigate(params, { + queryParams: { env: this.instance.env } + }); + } + } + + ngOnDestroy() { + this.subscriptions.forEach(s => s.unsubscribe()); + } +} \ No newline at end of file diff --git a/src/app/views/session-detail/session-detail.component.html b/src/app/views/detail/session/session.component.html similarity index 100% rename from src/app/views/session-detail/session-detail.component.html rename to src/app/views/detail/session/session.component.html diff --git a/src/app/views/session-detail/session-detail.component.scss b/src/app/views/detail/session/session.component.scss similarity index 100% rename from src/app/views/session-detail/session-detail.component.scss rename to src/app/views/detail/session/session.component.scss diff --git a/src/app/views/session-detail/session-detail.component.ts b/src/app/views/detail/session/session.component.ts similarity index 81% rename from src/app/views/session-detail/session-detail.component.ts rename to src/app/views/detail/session/session.component.ts index e45fc5c..6a68270 100644 --- a/src/app/views/session-detail/session-detail.component.ts +++ b/src/app/views/detail/session/session.component.ts @@ -3,16 +3,16 @@ import { ActivatedRoute, NavigationExtras, Router } from '@angular/router'; import { Observable, catchError, combineLatest, finalize, forkJoin, map, of, switchMap } from "rxjs"; import { Utils } from 'src/app/shared/util'; import { Location } from '@angular/common'; -import { TraceService } from 'src/app/shared/services/trace.service'; +import { TraceService } from 'src/app/service/trace.service'; import { application } from 'src/environments/environment'; -import { InstanceEnvironment, InstanceMainSession, InstanceRestSession } from 'src/app/shared/model/v3/trace.model'; +import { InstanceEnvironment, InstanceMainSession, InstanceRestSession } from 'src/app/model/trace.model'; @Component({ - templateUrl: './session-detail.component.html', - styleUrls: ['./session-detail.component.scss'], + templateUrl: './session.component.html', + styleUrls: ['./session.component.scss'], }) -export class SessionDetailComponent implements OnDestroy { +export class SessionComponent implements OnDestroy { selectedSession: InstanceMainSession | InstanceRestSession; // IncomingRequest | Mainrequest | OutcomingRequest; instance: InstanceEnvironment; selectedSessionType: string; @@ -50,7 +50,7 @@ export class SessionDetailComponent implements OnDestroy { return forkJoin({ session: of(s), instance: this._traceService.getInstance(s.instanceId), - parent: this._traceService.getSessionParentByChildId(id).pipe(catchError(() => of(null))), + parent: this._traceService.getSessionParent(id).pipe(catchError(() => of(null))), requests: this._traceService.getRestRequests(s.id), queries: this._traceService.getDatabaseRequests(s.id), stages: this._traceService.getLocalRequests(s.id) @@ -158,49 +158,4 @@ export class SessionDetailComponent implements OnDestroy { this.paramsSubscription.unsubscribe(); } } -} - -@Injectable() -export class EnvRouter { - - private _env: string; - - constructor(private router: Router) { } - - set env(env: string) { - this._env = env - } - - get events(): Observable { - return this.router.events; - }; - - get url(): string { - return this.router.url; - } - - - navigate(commands: any[], extras?: NavigationExtras): Promise { - if (!extras?.queryParams?.env) { - if (this._env) { - if (!extras) { - extras = {} - } - if (!extras.queryParams) { - extras.queryParams = {} - } - extras.queryParams.env = this._env; - } - } - else { - this.env = extras.queryParams.env; - } - return this.router.navigate(commands, extras); - // return Promise.resolve(true); - } - - open(url?: string | URL, target?: string, features?: string): WindowProxy | null { - return window.open(url, target, features); - } - } \ No newline at end of file diff --git a/src/app/views/session-main/session-main.component.html b/src/app/views/search/main/main.component.html similarity index 87% rename from src/app/views/session-main/session-main.component.html rename to src/app/views/search/main/main.component.html index 1432879..bb7cd50 100644 --- a/src/app/views/session-main/session-main.component.html +++ b/src/app/views/search/main/main.component.html @@ -10,16 +10,6 @@
- - Type de Session - - Aucun - VIEW - BATCH - STARTUP - - - @@ -49,16 +39,6 @@ - - - Type - -
- {{row.type || 'N/A'}} -
- -
- Nom diff --git a/src/app/views/session-main/session-main.component.scss b/src/app/views/search/main/main.component.scss similarity index 100% rename from src/app/views/session-main/session-main.component.scss rename to src/app/views/search/main/main.component.scss diff --git a/src/app/views/session-main/session-main.component.ts b/src/app/views/search/main/main.component.ts similarity index 71% rename from src/app/views/session-main/session-main.component.ts rename to src/app/views/search/main/main.component.ts index 1c94c14..db159ef 100644 --- a/src/app/views/session-main/session-main.component.ts +++ b/src/app/views/search/main/main.component.ts @@ -4,29 +4,27 @@ import { MatPaginator } from '@angular/material/paginator'; import { MatSort } from '@angular/material/sort'; import { MatTableDataSource } from '@angular/material/table'; import { ActivatedRoute, Params, Router } from '@angular/router'; -import { BehaviorSubject, Subscription } from 'rxjs'; +import {BehaviorSubject, combineLatest, Subscription} from 'rxjs'; import { Location } from '@angular/common'; import { Utils } from 'src/app/shared/util'; -import { TraceService } from 'src/app/shared/services/trace.service'; -import { EnvRouter } from '../session-detail/session-detail.component'; +import { TraceService } from 'src/app/service/trace.service'; import { application, makePeriod } from 'src/environments/environment'; -import { FilterConstants, FilterMap, FilterPreset } from '../constants'; -import { FilterService } from 'src/app/shared/services/filter.service'; -import { InstanceMainSession } from 'src/app/shared/model/v3/trace.model'; +import { FilterConstants, FilterMap, FilterPreset } from '../../constants'; +import { FilterService } from 'src/app/service/filter.service'; +import { InstanceMainSession } from 'src/app/model/trace.model'; +import {EnvRouter} from "../../../service/router.service"; @Component({ - templateUrl: './session-main.component.html', - styleUrls: ['./session-main.component.scss'], + templateUrl: './main.component.html', + styleUrls: ['./main.component.scss'], }) -export class SessionMainComponent implements OnInit, OnDestroy { +export class MainComponent implements OnInit, OnDestroy { filterConstants = FilterConstants; utils: Utils = new Utils(); - displayedColumns: string[] = ['status', 'app_name', 'type', 'name', 'location', 'start', 'durée', 'user']; + displayedColumns: string[] = ['status', 'app_name', 'name', 'location', 'start', 'durée', 'user']; dataSource: MatTableDataSource = new MatTableDataSource(); - mainRequestList: InstanceMainSession[]; serverFilterForm = new FormGroup({ - launchmode: new FormControl(""), dateRangePicker: new FormGroup({ start: new FormControl(null, [Validators.required]), end: new FormControl(null, [Validators.required]), @@ -38,7 +36,7 @@ export class SessionMainComponent implements OnInit, OnDestroy { focusFieldName: any filter: string = ''; - params: Partial<{ env: string, start: Date, end: Date, launchMode: string }> = {}; + params: Partial<{ env: string, start: Date, end: Date, type: string }> = {}; @ViewChild(MatPaginator) paginator: MatPaginator; @ViewChild(MatSort) sort: MatSort; @@ -49,25 +47,26 @@ export class SessionMainComponent implements OnInit, OnDestroy { private _location: Location, private _filter: FilterService) { - this._activatedRoute.queryParams - .subscribe({ - next: (params: Params) => { - this.params.env = params['env'] || application.default_env; + combineLatest([ + this._activatedRoute.params, + this._activatedRoute.queryParams + ]).subscribe({ + next: ([params, queryParams]) => { + this.params.env = queryParams['env'] || application.default_env; - this.params.launchMode = params['name'] || ''; - this.patchLaunchValue(this.params.launchMode); - this.params.start = params['start'] ? new Date(params['start']) : (application.session.main.default_period || makePeriod(0, 1)).start; - this.params.end = params['end'] ? new Date(params['end']) : (application.session.main.default_period || makePeriod(0, 1)).end; + this.params.type = params['type_main']; + this.params.start = queryParams['start'] ? new Date(queryParams['start']) : (application.session.main.default_period || makePeriod(0, 1)).start; + this.params.end = queryParams['end'] ? new Date(queryParams['end']) : (application.session.main.default_period || makePeriod(0, 1)).end; this.patchDateValue(this.params.start, new Date(this.params.end.getFullYear(), this.params.end.getMonth(), this.params.end.getDate() - 1)); this.getMainRequests(); - this._location.replaceState(`${this._router.url.split('?')[0]}?env=${this.params.env}&start=${this.params.start.toISOString()}&end=${this.params.end.toISOString()}${this.params.launchMode !== '' ? '&name=' + this.params.launchMode : ''}`) + this._location.replaceState(`${this._router.url.split('?')[0]}?env=${this.params.env}&start=${this.params.start.toISOString()}&end=${this.params.end.toISOString()}`) } }); } ngOnInit(): void { - this._filter.registerGetallFilters(this.filtersSupplier.bind(this)); + } ngOnDestroy(): void { @@ -77,7 +76,7 @@ export class SessionMainComponent implements OnInit, OnDestroy { getMainRequests() { let params = { 'env': this.params.env, - 'launchmode': this.params.launchMode, + 'launchmode': this.params.type, 'start': this.params.start.toISOString(), 'end': this.params.end.toISOString(), 'lazy': false @@ -95,7 +94,6 @@ export class SessionMainComponent implements OnInit, OnDestroy { this.dataSource.sort = this.sort this.dataSource.sortingDataAccessor = (row: any, columnName: string) => { if (columnName == "app_name") return row["application"]["name"] as string; - if (columnName == "type") return row["type"] as string; if (columnName == "name") return row["name"] as string; if (columnName == "location") return row['location'] as string; if (columnName == "start") return row['start'] as string; @@ -116,18 +114,15 @@ export class SessionMainComponent implements OnInit, OnDestroy { search() { if (this.serverFilterForm.valid) { - let name = this.serverFilterForm.getRawValue().launchmode; - console.log(name) let start = this.serverFilterForm.getRawValue().dateRangePicker.start; let end = this.serverFilterForm.getRawValue().dateRangePicker.end let excludedEnd = new Date(end.getFullYear(), end.getMonth(), end.getDate() + 1) if (this.params.start.toISOString() != start.toISOString() - || this.params.end.toISOString() != excludedEnd.toISOString() - || this.params.launchMode != name) { + || this.params.end.toISOString() != excludedEnd.toISOString()) { this._router.navigate([], { relativeTo: this._activatedRoute, queryParamsHandling: 'merge', - queryParams: { ...(name !== undefined && { name }), start: start.toISOString(), end: excludedEnd.toISOString() } + queryParams: { start: start.toISOString(), end: excludedEnd.toISOString() } }) } else { this.getMainRequests(); @@ -144,18 +139,11 @@ export class SessionMainComponent implements OnInit, OnDestroy { }, { emitEvent: false }); } - patchLaunchValue(launchMode: string) { - this.serverFilterForm.patchValue({ - launchmode: launchMode - }) - } - - selectedRequest(event: MouseEvent, row: any) { if (event.ctrlKey) { - this._router.open(`#/session/main/${row}`, '_blank') + this._router.open(`#/session/main/${row.type}/${row}`, '_blank') } else { - this._router.navigate(['/session/main', row], { + this._router.navigate(['/session/main', row.type, row], { queryParams: { 'env': this.params.env } }); } @@ -180,15 +168,10 @@ export class SessionMainComponent implements OnInit, OnDestroy { } resetFilters(){ this.patchDateValue((application.session.api.default_period || makePeriod(0)).start,(application.session.api.default_period || makePeriod(0, 1)).end); - this.patchLaunchValue(""); this.advancedParams = {}; this._filter.setFilterMap({}) } - filtersSupplier(): BehaviorSubject { //change - return new BehaviorSubject({ 'launchmode': this.serverFilterForm.getRawValue().launchmode }); - } - handlePresetSelection(filterPreset: FilterPreset) { const formControlNamelist = Object.keys(this.serverFilterForm.controls); Object.entries(filterPreset.values).reduce((accumulator: any, [key, value]) => { diff --git a/src/app/views/session-api/session-api.component.html b/src/app/views/search/rest/rest.component.html similarity index 100% rename from src/app/views/session-api/session-api.component.html rename to src/app/views/search/rest/rest.component.html diff --git a/src/app/views/session-api/session-api.component.scss b/src/app/views/search/rest/rest.component.scss similarity index 100% rename from src/app/views/session-api/session-api.component.scss rename to src/app/views/search/rest/rest.component.scss diff --git a/src/app/views/session-api/session-api.component.ts b/src/app/views/search/rest/rest.component.ts similarity index 93% rename from src/app/views/session-api/session-api.component.ts rename to src/app/views/search/rest/rest.component.ts index f48f096..f1f17b5 100644 --- a/src/app/views/session-api/session-api.component.ts +++ b/src/app/views/search/rest/rest.component.ts @@ -7,20 +7,20 @@ import { Location } from '@angular/common'; import { ActivatedRoute, Params } from '@angular/router'; import { BehaviorSubject, Observable, Subscription, finalize } from 'rxjs'; import { Utils } from 'src/app/shared/util'; -import { JQueryService } from 'src/app/shared/services/jquery.service'; -import { TraceService } from 'src/app/shared/services/trace.service'; -import { EnvRouter } from '../session-detail/session-detail.component'; +import { JQueryService } from 'src/app/service/jquery.service'; +import { TraceService } from 'src/app/service/trace.service'; import { application, makePeriod } from 'src/environments/environment'; -import { FilterConstants, FilterPreset, FilterMap } from '../constants'; -import { FilterService } from 'src/app/shared/services/filter.service'; -import { InstanceMainSession, InstanceRestSession, RestSession } from 'src/app/shared/model/v3/trace.model'; +import { FilterConstants, FilterPreset, FilterMap } from '../../constants'; +import { FilterService } from 'src/app/service/filter.service'; +import { InstanceMainSession, InstanceRestSession, RestSession } from 'src/app/model/trace.model'; +import {EnvRouter} from "../../../service/router.service"; @Component({ - templateUrl: './session-api.component.html', - styleUrls: ['./session-api.component.scss'], + templateUrl: './rest.component.html', + styleUrls: ['./rest.component.scss'], }) -export class SessionApiComponent implements OnInit, OnDestroy { +export class RestComponent implements OnInit, OnDestroy { filterConstants = FilterConstants; nameDataList: any[]; displayedColumns: string[] = ['status', 'app_name', 'method/path', 'query', 'start', 'durée', 'user']; @@ -191,9 +191,9 @@ export class SessionApiComponent implements OnInit, OnDestroy { selectedRequest(event: MouseEvent, row: any) { if (event.ctrlKey) { - this._router.open(`#/session/api/${row}`, '_blank') + this._router.open(`#/session/rest/${row}`, '_blank') } else { - this._router.navigate(['/session/api', row], { + this._router.navigate(['/session/rest', row], { queryParams: { 'env': this.params.env } }); } diff --git a/src/app/shared/components/stats/dependencies-table/dependencies-table.component.html b/src/app/views/statistic/_component/dependencies-table/dependencies-table.component.html similarity index 100% rename from src/app/shared/components/stats/dependencies-table/dependencies-table.component.html rename to src/app/views/statistic/_component/dependencies-table/dependencies-table.component.html diff --git a/src/app/shared/components/stats/dependencies-table/dependencies-table.component.scss b/src/app/views/statistic/_component/dependencies-table/dependencies-table.component.scss similarity index 100% rename from src/app/shared/components/stats/dependencies-table/dependencies-table.component.scss rename to src/app/views/statistic/_component/dependencies-table/dependencies-table.component.scss diff --git a/src/app/shared/components/stats/dependencies-table/dependencies-table.component.ts b/src/app/views/statistic/_component/dependencies-table/dependencies-table.component.ts similarity index 100% rename from src/app/shared/components/stats/dependencies-table/dependencies-table.component.ts rename to src/app/views/statistic/_component/dependencies-table/dependencies-table.component.ts diff --git a/src/app/shared/components/stats/dependents-table/dependents-table.component.html b/src/app/views/statistic/_component/dependents-table/dependents-table.component.html similarity index 100% rename from src/app/shared/components/stats/dependents-table/dependents-table.component.html rename to src/app/views/statistic/_component/dependents-table/dependents-table.component.html diff --git a/src/app/shared/components/stats/dependents-table/dependents-table.component.scss b/src/app/views/statistic/_component/dependents-table/dependents-table.component.scss similarity index 100% rename from src/app/shared/components/stats/dependents-table/dependents-table.component.scss rename to src/app/views/statistic/_component/dependents-table/dependents-table.component.scss diff --git a/src/app/shared/components/stats/dependents-table/dependents-table.component.ts b/src/app/views/statistic/_component/dependents-table/dependents-table.component.ts similarity index 100% rename from src/app/shared/components/stats/dependents-table/dependents-table.component.ts rename to src/app/views/statistic/_component/dependents-table/dependents-table.component.ts diff --git a/src/app/shared/components/stats/exception-table/exception-table.component.html b/src/app/views/statistic/_component/exception-table/exception-table.component.html similarity index 100% rename from src/app/shared/components/stats/exception-table/exception-table.component.html rename to src/app/views/statistic/_component/exception-table/exception-table.component.html diff --git a/src/app/shared/components/stats/exception-table/exception-table.component.scss b/src/app/views/statistic/_component/exception-table/exception-table.component.scss similarity index 100% rename from src/app/shared/components/stats/exception-table/exception-table.component.scss rename to src/app/views/statistic/_component/exception-table/exception-table.component.scss diff --git a/src/app/shared/components/stats/exception-table/exception-table.component.ts b/src/app/views/statistic/_component/exception-table/exception-table.component.ts similarity index 100% rename from src/app/shared/components/stats/exception-table/exception-table.component.ts rename to src/app/views/statistic/_component/exception-table/exception-table.component.ts diff --git a/src/app/views/stats-app/stats-app.component.html b/src/app/views/statistic/application/application.component.html similarity index 100% rename from src/app/views/stats-app/stats-app.component.html rename to src/app/views/statistic/application/application.component.html diff --git a/src/app/views/stats-app/stats-app.component.scss b/src/app/views/statistic/application/application.component.scss similarity index 100% rename from src/app/views/stats-app/stats-app.component.scss rename to src/app/views/statistic/application/application.component.scss diff --git a/src/app/views/stats-app/stats-app.component.ts b/src/app/views/statistic/application/application.component.ts similarity index 96% rename from src/app/views/stats-app/stats-app.component.ts rename to src/app/views/statistic/application/application.component.ts index aae90f4..f71e6fa 100644 --- a/src/app/views/stats-app/stats-app.component.ts +++ b/src/app/views/statistic/application/application.component.ts @@ -1,20 +1,20 @@ import { Component, OnDestroy, OnInit, inject } from "@angular/core"; -import { EnvRouter } from "../session-detail/session-detail.component"; import { DatePipe, Location } from '@angular/common'; -import { JQueryService } from "src/app/shared/services/jquery.service"; +import { JQueryService } from "src/app/service/jquery.service"; import { ActivatedRoute, Params } from "@angular/router"; import { FormControl, FormGroup, Validators } from "@angular/forms"; import { BehaviorSubject, Observable, Subscription, combineLatest, finalize, map } from "rxjs"; -import { Constants, FilterConstants, FilterMap, FilterPreset } from "../constants"; +import { Constants, FilterConstants, FilterMap, FilterPreset } from "../../constants"; import { mapParams, formatters, groupingBy, periodManagement } from "src/app/shared/util"; import { application, makePeriod } from "src/environments/environment"; -import { FilterService } from "src/app/shared/services/filter.service"; +import { FilterService } from "src/app/service/filter.service"; +import {EnvRouter} from "../../../service/router.service"; @Component({ - templateUrl: './stats-app.component.html', - styleUrls: ['./stats-app.component.scss'] + templateUrl: './application.component.html', + styleUrls: ['./application.component.scss'] }) -export class StatsAppComponent implements OnInit, OnDestroy { +export class ApplicationComponent implements OnInit, OnDestroy { constants = Constants filterConstants = FilterConstants; private _activatedRoute = inject(ActivatedRoute); @@ -118,9 +118,9 @@ export class StatsAppComponent implements OnInit, OnDestroy { onClickRow(event: MouseEvent, row: any) { if (event.ctrlKey) { - this._router.open(`#/dashboard/app/${row.name}?env=${this.env}&start=${this.start.toISOString()}&end=${this.end.toISOString()}`, '_blank') + this._router.open(`#/statistic/app/${row.name}?env=${this.env}&start=${this.start.toISOString()}&end=${this.end.toISOString()}`, '_blank') } else { - this._router.navigate(['/dashboard/app', row.name], { + this._router.navigate(['/statistic/app', row.name], { queryParamsHandling: 'preserve' }); } diff --git a/src/app/views/stats-database/stats-database.component.html b/src/app/views/statistic/database/database.component.html similarity index 100% rename from src/app/views/stats-database/stats-database.component.html rename to src/app/views/statistic/database/database.component.html diff --git a/src/app/views/stats-database/stats-database.component.scss b/src/app/views/statistic/database/database.component.scss similarity index 100% rename from src/app/views/stats-database/stats-database.component.scss rename to src/app/views/statistic/database/database.component.scss diff --git a/src/app/views/stats-database/stats-database.component.ts b/src/app/views/statistic/database/database.component.ts similarity index 97% rename from src/app/views/stats-database/stats-database.component.ts rename to src/app/views/statistic/database/database.component.ts index 2808983..6a88e6c 100644 --- a/src/app/views/stats-database/stats-database.component.ts +++ b/src/app/views/statistic/database/database.component.ts @@ -3,18 +3,18 @@ import { ActivatedRoute, Params, Router } from '@angular/router'; import { Observable, Subscription, catchError, combineLatest, finalize, map, of } from 'rxjs'; import { DatePipe, Location } from '@angular/common'; import { FormControl, FormGroup, Validators } from '@angular/forms'; -import { JQueryService } from 'src/app/shared/services/jquery.service'; +import { JQueryService } from 'src/app/service/jquery.service'; import { MatTableDataSource } from '@angular/material/table'; -import { Constants } from '../constants'; +import { Constants } from '../../constants'; import { application, makePeriod } from 'src/environments/environment'; import { formatters, periodManagement } from 'src/app/shared/util'; import { ChartProvider, field } from '@oneteme/jquery-core'; @Component({ - templateUrl: './stats-database.component.html', - styleUrls: ['./stats-database.component.scss'] + templateUrl: './database.component.html', + styleUrls: ['./database.component.scss'] }) -export class StatsDatabaseComponent implements OnInit { +export class DatabaseComponent implements OnInit { private _activatedRoute = inject(ActivatedRoute); private _router = inject(Router); private _datePipe = inject(DatePipe); diff --git a/src/app/views/stats-api/stats-api.component.html b/src/app/views/statistic/rest/rest.component.html similarity index 100% rename from src/app/views/stats-api/stats-api.component.html rename to src/app/views/statistic/rest/rest.component.html diff --git a/src/app/views/stats-api/stats-api.component.scss b/src/app/views/statistic/rest/rest.component.scss similarity index 100% rename from src/app/views/stats-api/stats-api.component.scss rename to src/app/views/statistic/rest/rest.component.scss diff --git a/src/app/views/stats-api/stats-api.component.ts b/src/app/views/statistic/rest/rest.component.ts similarity index 95% rename from src/app/views/stats-api/stats-api.component.ts rename to src/app/views/statistic/rest/rest.component.ts index 3d7cbcb..4ce8910 100644 --- a/src/app/views/stats-api/stats-api.component.ts +++ b/src/app/views/statistic/rest/rest.component.ts @@ -1,20 +1,20 @@ import { Component, OnDestroy, OnInit, inject } from "@angular/core"; -import { EnvRouter } from "../session-detail/session-detail.component"; -import { JQueryService } from "src/app/shared/services/jquery.service"; +import { JQueryService } from "src/app/service/jquery.service"; import { DatePipe, Location } from '@angular/common'; import { ActivatedRoute, Params } from "@angular/router"; import { FormControl, FormGroup, Validators } from "@angular/forms"; import { BehaviorSubject, Observable, Subscription, combineLatest, filter, finalize, map } from "rxjs"; -import { Constants, FilterConstants, FilterMap, FilterPreset } from "../constants"; +import { Constants, FilterConstants, FilterMap, FilterPreset } from "../../constants"; import { Utils, formatters, groupingBy, periodManagement, mapParams, } from "src/app/shared/util"; import { application, makePeriod } from "src/environments/environment"; -import { FilterService } from "src/app/shared/services/filter.service"; +import { FilterService } from "src/app/service/filter.service"; +import {EnvRouter} from "../../../service/router.service"; @Component({ - templateUrl: './stats-api.component.html', - styleUrls: ['./stats-api.component.scss'] + templateUrl: './rest.component.html', + styleUrls: ['./rest.component.scss'] }) -export class StatsApiComponent implements OnInit, OnDestroy { +export class RestComponent implements OnInit, OnDestroy { constants = Constants; filterConstants = FilterConstants; private _activatedRoute = inject(ActivatedRoute); @@ -120,9 +120,9 @@ export class StatsApiComponent implements OnInit, OnDestroy { onClickRow(event: MouseEvent, row: any) { if (event.ctrlKey) { - this._router.open(`#/dashboard/api/${row.name}?env=${this.env}&start=${this.start.toISOString()}&end=${this.end.toISOString()}`, '_blank') + this._router.open(`#/statistic/rest/${row.name}?env=${this.env}&start=${this.start.toISOString()}&end=${this.end.toISOString()}`, '_blank') } else { - this._router.navigate(['/dashboard/api', row.name], { + this._router.navigate(['/statistic/rest', row.name], { queryParamsHandling: 'preserve' }); } diff --git a/src/app/shared/components/stats/session-table/session-table.component.html b/src/app/views/statistic/user/_component/session-table/session-table.component.html similarity index 100% rename from src/app/shared/components/stats/session-table/session-table.component.html rename to src/app/views/statistic/user/_component/session-table/session-table.component.html diff --git a/src/app/shared/components/stats/session-table/session-table.component.scss b/src/app/views/statistic/user/_component/session-table/session-table.component.scss similarity index 100% rename from src/app/shared/components/stats/session-table/session-table.component.scss rename to src/app/views/statistic/user/_component/session-table/session-table.component.scss diff --git a/src/app/shared/components/stats/session-table/session-table.component.ts b/src/app/views/statistic/user/_component/session-table/session-table.component.ts similarity index 100% rename from src/app/shared/components/stats/session-table/session-table.component.ts rename to src/app/views/statistic/user/_component/session-table/session-table.component.ts diff --git a/src/app/views/stats-user/stats-user.component.html b/src/app/views/statistic/user/user.component.html similarity index 100% rename from src/app/views/stats-user/stats-user.component.html rename to src/app/views/statistic/user/user.component.html diff --git a/src/app/views/stats-user/stats-user.component.scss b/src/app/views/statistic/user/user.component.scss similarity index 100% rename from src/app/views/stats-user/stats-user.component.scss rename to src/app/views/statistic/user/user.component.scss diff --git a/src/app/views/stats-user/stats-user.component.ts b/src/app/views/statistic/user/user.component.ts similarity index 96% rename from src/app/views/stats-user/stats-user.component.ts rename to src/app/views/statistic/user/user.component.ts index 9a90812..18d3a68 100644 --- a/src/app/views/stats-user/stats-user.component.ts +++ b/src/app/views/statistic/user/user.component.ts @@ -1,20 +1,20 @@ import { Component, OnDestroy, OnInit, inject } from "@angular/core"; -import { EnvRouter } from "../session-detail/session-detail.component"; -import { JQueryService } from "src/app/shared/services/jquery.service"; +import { JQueryService } from "src/app/service/jquery.service"; import { ActivatedRoute, Params } from "@angular/router"; import { DatePipe, Location } from '@angular/common'; import { FormControl, FormGroup, Validators } from "@angular/forms"; import { BehaviorSubject, Observable, Subscription, combineLatest, finalize, map } from "rxjs"; -import { Constants, FilterConstants, FilterMap, FilterPreset } from "../constants"; +import { Constants, FilterConstants, FilterMap, FilterPreset } from "../../constants"; import { application, makePeriod } from "src/environments/environment"; -import { FilterService } from "src/app/shared/services/filter.service"; +import { FilterService } from "src/app/service/filter.service"; import { mapParams, formatters, periodManagement } from "src/app/shared/util"; +import {EnvRouter} from "../../../service/router.service"; @Component({ - templateUrl: './stats-user.component.html', - styleUrls: ['./stats-user.component.scss'] + templateUrl: './user.component.html', + styleUrls: ['./user.component.scss'] }) -export class StatsUserComponent implements OnInit, OnDestroy { +export class UserComponent implements OnInit, OnDestroy { constants = Constants; filterConstants = FilterConstants; diff --git a/src/app/views/tree/tree.component.ts b/src/app/views/tree/tree.component.ts index b9c68b9..6042bfe 100644 --- a/src/app/views/tree/tree.component.ts +++ b/src/app/views/tree/tree.component.ts @@ -4,9 +4,9 @@ import { combineLatest, finalize, fromEvent } from 'rxjs'; import { Location } from '@angular/common'; import mx from '../../../mxgraph'; import { Utils } from 'src/app/shared/util'; -import { TraceService } from 'src/app/shared/services/trace.service'; -import { EnvRouter } from '../session-detail/session-detail.component'; +import { TraceService } from 'src/app/service/trace.service'; import { application } from 'src/environments/environment'; +import {EnvRouter} from "../../service/router.service"; @Component({ @@ -49,11 +49,11 @@ export class TreeComponent implements OnDestroy { queryParams: this._activatedRoute.queryParams }).subscribe({ next: (v: { paramsList: Params, queryParams: Params }) => { - this.id = v.paramsList.params['id']; + this.id = v.paramsList.params['id_session']; this.env = v.queryParams.env || application.default_env; this._location.replaceState(`${this._router.url.split('?')[0]}?env=${this.env}`) this.isLoading = true; - this._traceService.getTree(this.id, v.paramsList.params['type']).pipe(finalize(() => this.isLoading = false)).subscribe(d => { + this._traceService.getTree(this.id, v.paramsList.params['type_session']).pipe(finalize(() => this.isLoading = false)).subscribe(d => { this.exchange = {}; this.exchange['remoteTrace'] = d; @@ -688,23 +688,29 @@ export class TreeComponent implements OnDestroy { if (cell.isEdge() && cell.target.value.data.length == 1) { let callType = ""; + let mainType = ""; let target = cell.target.value.data[0]; let targetId = ""; if (!target.hasOwnProperty('name')) { - if (target.remoteTrace['@type'] == "api") { - callType = "request"; + if (target.remoteTrace['@type'] == "rest") { + callType = "rest"; } else if (target.remoteTrace['@type'] == 'main') { callType = "main"; + mainType = target.remoteTrace.type; } targetId = target.remoteTrace.id } else { - callType = "request" + callType = "rest" targetId = cell.source.value.data[0].remoteTrace.id } menu.addItem('Détails de l\'appel ', 'editors/images/image.gif', function () { - self._router.navigate(['/session', callType, targetId]); + if(mainType != "") { + self._router.navigate(['/session', callType, mainType, targetId]); + } else { + self._router.navigate(['/session', callType, targetId]); + } }); @@ -713,9 +719,9 @@ export class TreeComponent implements OnDestroy { if (cell.isVertex()) { let target = cell.value.data[0]; if (target.remoteTrace.hasOwnProperty('@type')) { - if (target.remoteTrace['@type'] == "api") { + if (target.remoteTrace['@type'] == "rest") { menu.addItem('Statistique ', '../src/images/warning.gif', function () { - self._router.navigate(['/dashboard', 'api', target.appName]); + self._router.navigate(['/statistic', 'rest', target.appName]); }); } } diff --git a/src/app/views/views.module.ts b/src/app/views/views.module.ts index 74455b6..612137e 100644 --- a/src/app/views/views.module.ts +++ b/src/app/views/views.module.ts @@ -1,33 +1,32 @@ -import { NO_ERRORS_SCHEMA, NgModule } from '@angular/core'; -import { CommonModule } from '@angular/common'; -import { RouterModule } from '@angular/router'; -import { FormsModule, ReactiveFormsModule } from '@angular/forms'; -import { BrowserModule } from '@angular/platform-browser'; -import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; -import { SharedModule } from '../shared/shared.module'; -import { MaterialModule } from '../app.material.module'; -import { SessionApiComponent } from './session-api/session-api.component'; -import { SessionMainComponent } from './session-main/session-main.component'; -import { TreeComponent } from './tree/tree.component'; -import { DependenciesTableComponent } from '../shared/components/stats/dependencies-table/dependencies-table.component'; -import { DependentsTableComponent } from '../shared/components/stats/dependents-table/dependents-table.component'; -import { SessionDetailComponent } from './session-detail/session-detail.component'; -import { StatsDatabaseComponent } from './stats-database/stats-database.component'; -import { SessionTableComponent } from '../shared/components/stats/session-table/session-table.component'; -import { StatsAppComponent } from './stats-app/stats-app.component'; -import { StatsApiComponent } from './stats-api/stats-api.component'; -import { StatsUserComponent } from './stats-user/stats-user.component'; -import { ExceptionTableComponent } from '../shared/components/stats/exception-table/exception-table.component'; -import { ChartComponent } from '@oneteme/jquery-apexcharts'; -import { DbRequestDetailComponent } from './db-request-detail/db-request-detail.component'; -import { RequestRestTableComponent } from './session-detail/components/request-rest-table/request-rest-table.component'; -import { RequestDatabaseTableComponent } from './session-detail/components/request-database-table/request-database-table.component'; -import { RequestTimelineComponent } from './session-detail/components/request-timeline/request-timeline.component'; -import { DashboardComponent } from './dashboard/dashboard.component'; +import {NgModule} from '@angular/core'; +import {CommonModule} from '@angular/common'; +import {RouterModule} from '@angular/router'; +import {FormsModule, ReactiveFormsModule} from '@angular/forms'; +import {BrowserModule} from '@angular/platform-browser'; +import {BrowserAnimationsModule} from '@angular/platform-browser/animations'; +import {SharedModule} from '../shared/shared.module'; +import {MainComponent as SearchMainComponent} from './search/main/main.component'; +import {MainComponent as DetailSessionMainComponent} from './detail/session/main/main.component'; +import {TreeComponent} from './tree/tree.component'; +import {DependenciesTableComponent} from './statistic/_component/dependencies-table/dependencies-table.component'; +import {DependentsTableComponent} from './statistic/_component/dependents-table/dependents-table.component'; +import {SessionTableComponent} from './statistic/user/_component/session-table/session-table.component'; +import {ApplicationComponent} from './statistic/application/application.component'; +import {RestComponent as SearchRestComponent} from './search/rest/rest.component'; +import {RestComponent as StatisticRestComponent} from './statistic/rest/rest.component'; +import {RestComponent as DetailSessionRestComponent} from './detail/session/rest/rest.component'; +import {UserComponent} from './statistic/user/user.component'; +import {ExceptionTableComponent} from './statistic/_component/exception-table/exception-table.component'; +import {ChartComponent} from '@oneteme/jquery-apexcharts'; +import {DatabaseComponent as StatisticDatabaseComponent} from './statistic/database/database.component'; +import {DatabaseComponent as DetailDatabaseComponent} from './detail/database/database.component'; +import {RestTableComponent} from './detail/session/_component/rest-table/rest-table.component'; +import {DatabaseTableComponent} from './detail/session/_component/database-table/database-table.component'; +import {TimelineComponent} from './detail/session/_component/timeline/timeline.component'; +import {DashboardComponent} from './dashboard/dashboard.component'; @NgModule({ imports: [ - MaterialModule, FormsModule, ReactiveFormsModule, CommonModule, @@ -38,22 +37,23 @@ import { DashboardComponent } from './dashboard/dashboard.component'; ChartComponent ], declarations: [ - SessionApiComponent, - SessionDetailComponent, - RequestRestTableComponent, - RequestDatabaseTableComponent, - RequestTimelineComponent, - SessionMainComponent, - StatsAppComponent, - StatsApiComponent, - StatsUserComponent, + SearchRestComponent, + SearchMainComponent, + StatisticRestComponent, + StatisticDatabaseComponent, + DetailSessionRestComponent, + DetailSessionMainComponent, + DetailDatabaseComponent, + RestTableComponent, + DatabaseTableComponent, + TimelineComponent, + ApplicationComponent, + UserComponent, TreeComponent, - StatsDatabaseComponent, DependentsTableComponent, DependenciesTableComponent, ExceptionTableComponent, SessionTableComponent, - DbRequestDetailComponent, DashboardComponent ] }) diff --git a/src/environments/environment.prod.ts b/src/environments/environment.prod.ts index 35a4cb4..9904eda 100644 --- a/src/environments/environment.prod.ts +++ b/src/environments/environment.prod.ts @@ -1,5 +1,5 @@ -import { Application } from "src/app/shared/model/conf.model"; +import { Application } from "src/app/model/conf.model"; export const environment = { production: false, diff --git a/src/environments/environment.ts b/src/environments/environment.ts index 4184e72..a571b51 100644 --- a/src/environments/environment.ts +++ b/src/environments/environment.ts @@ -2,7 +2,7 @@ // `ng build --prod` replaces `environment.ts` with `environment.prod.ts`. // The list of file replacements can be found in `angular.json`. -import { Application } from "src/app/shared/model/conf.model"; +import { Application } from "src/app/model/conf.model"; export const environment = { production: false, From 36f74fbb02e84d0a975bdd89c6f4735313ab5105 Mon Sep 17 00:00:00 2001 From: fufuu Date: Wed, 31 Jul 2024 17:02:47 +0200 Subject: [PATCH 042/126] refacto et hotfix --- src/app/app.component.html | 12 +- src/app/app.module.ts | 114 ++++++++++----- src/app/model/trace.model.ts | 1 + src/app/service/trace.service.ts | 2 +- .../detail/database/database.component.html | 6 +- .../detail/database/database.component.ts | 134 +++++++++--------- .../database-table.component.html | 4 +- .../rest-table/rest-table.component.html | 5 +- .../rest-table/rest-table.component.ts | 1 + .../timeline/timeline.component.html | 2 +- .../_component/timeline/timeline.component.ts | 24 ++-- .../detail/session/main/main.component.html | 25 ++-- .../detail/session/main/main.component.ts | 7 +- .../detail/session/rest/rest.component.html | 32 ++++- .../detail/session/rest/rest.component.ts | 9 +- src/app/views/search/main/main.component.html | 8 +- src/app/views/search/main/main.component.ts | 12 +- src/app/views/search/rest/rest.component.html | 2 +- .../application/application.component.ts | 8 +- .../views/statistic/rest/rest.component.html | 8 +- .../views/statistic/rest/rest.component.ts | 9 +- src/app/views/tree/tree.component.html | 4 +- src/app/views/tree/tree.component.scss | 2 +- src/app/views/tree/tree.component.ts | 21 +-- 24 files changed, 268 insertions(+), 184 deletions(-) diff --git a/src/app/app.component.html b/src/app/app.component.html index 4f4bbeb..7a9ef5a 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -6,17 +6,17 @@ [queryParams]="{env: env.value}"> - - + - - + - - + diff --git a/src/app/app.module.ts b/src/app/app.module.ts index ccc98ba..e8adf77 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -32,47 +32,85 @@ const routes: Route[] = [ path: 'session', children: [ { path: 'rest', - component: SearchRestComponent, - title: 'Appels REST', - }, - { - path: 'rest/:id_session', - component: DetailSessionRestComponent, - title: 'Detail de l\'appel REST' + children: [ + { + path: '', + component: SearchRestComponent, + title: 'Recherche Appels REST', + }, + { + path: ':id_session', + children: [ + { + path: '', + component: DetailSessionRestComponent, + title: 'Detail Appel REST' + }, + { + path: 'database/:id_database', + data: { type: 'rest' }, + component: DetailDatabaseComponent, + title: 'Detail Base de donnée' + }, + { + path: 'tree', + data: { type: 'rest' }, + component: TreeComponent, + title: 'Arbre d\'Appels' + }, + { path: '**', pathMatch: 'full', redirectTo: `/session/rest/:id_session` } + ] + }, + { path: '**', pathMatch: 'full', redirectTo: `/session/rest` } + ] }, { path: 'main/:type_main', - component: SearchMainComponent, - title: (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => { - if (route.paramMap.get('type_main') == 'batch') { - return 'Liste BATCH'; - } else if(route.paramMap.get('type_main') == 'startup') { - return 'Liste Lancement Serveur'; - } - return 'Liste Interaction Web'; - }, - }, - { - path: 'main/:type_main/:id_session', - component: DetailSessionMainComponent, - title: (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => { - if (route.paramMap.get('type_main') == 'batch') { - return 'Detail Lancement BATCH'; - } else if (route.paramMap.get('type_main') == 'startup') { - return 'Detail Lancement Serveur'; - } - return 'Detail Interaction Web'; - }, - }, - { - path: ':type_session/:id_session/tree', - component: TreeComponent, - title: 'Arbre d\'appels' - }, - { - path: ':type_session/:id_session/database/:id_database', - component: DetailDatabaseComponent, - title: 'Detail de la requête SQL' + children: [ + { + path: '', + component: SearchMainComponent, + title: (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => { + if (route.paramMap.get('type_main') == 'batch') { + return 'Recherche BATCHs'; + } else if(route.paramMap.get('type_main') == 'startup') { + return 'Recherche Serveurs'; + } + return 'Recherche Vues'; + }, + }, + { + path: ':id_session', + children: [ + { + path: '', + component: DetailSessionMainComponent, + title: (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => { + if (route.paramMap.get('type_main') == 'batch') { + return 'Detail BATCH'; + } else if (route.paramMap.get('type_main') == 'startup') { + return 'Detail Serveur'; + } + return 'Detail Vue'; + }, + }, + { + path: 'database/:id_database', + component: DetailDatabaseComponent, + data: { type: 'main' }, + title: 'Detail Base de donnée' + }, + { + path: 'tree', + data: { type: 'main' }, + component: TreeComponent, + title: 'Arbre d\'appels' + }, + { path: '**', pathMatch: 'full', redirectTo: `/main/:type_main/:id_session` } + ] + }, + { path: '**', pathMatch: 'full', redirectTo: `/main/:type_main` } + ] }, { path: '**', pathMatch: 'full', redirectTo: `/session/rest` } ] diff --git a/src/app/model/trace.model.ts b/src/app/model/trace.model.ts index 2710ca2..f830ebb 100644 --- a/src/app/model/trace.model.ts +++ b/src/app/model/trace.model.ts @@ -97,6 +97,7 @@ export interface NamingRequest extends SessionStage { export interface DatabaseRequestStage extends RequestStage { count?: Array; + order?: number; } export interface FtpRequestStage extends RequestStage { diff --git a/src/app/service/trace.service.ts b/src/app/service/trace.service.ts index a900977..5101a53 100644 --- a/src/app/service/trace.service.ts +++ b/src/app/service/trace.service.ts @@ -38,7 +38,7 @@ export class TraceService { } getTree(id: string, type: string) { - return type == "api" ? this.http.get(`${this.server}/session/rest/${id}/tree`) : + return type == "rest" ? this.http.get(`${this.server}/session/rest/${id}/tree`) : this.http.get(`${this.server}/session/main/${id}/tree`); } diff --git a/src/app/views/detail/database/database.component.html b/src/app/views/detail/database/database.component.html index 4d10423..0ef017b 100644 --- a/src/app/views/detail/database/database.component.html +++ b/src/app/views/detail/database/database.component.html @@ -73,16 +73,16 @@
-
+

Aucun détail disponible ..
- Vérifiez que TraceAPI est bien configuré sur {{ - selectedSession?.host}} + Vérifiez que TraceAPI est bien configuré sur {{ + selectedQuery?.host}}

diff --git a/src/app/views/detail/database/database.component.ts b/src/app/views/detail/database/database.component.ts index 3e4a035..5ce1174 100644 --- a/src/app/views/detail/database/database.component.ts +++ b/src/app/views/detail/database/database.component.ts @@ -1,13 +1,13 @@ -import { Component, ElementRef, NgZone, OnDestroy, ViewChild } from '@angular/core'; - -import { ActivatedRoute } from '@angular/router'; -import { combineLatest, forkJoin } from "rxjs"; -import { Timeline } from 'vis-timeline'; -import { Utils } from 'src/app/shared/util'; -import { DatePipe, Location } from '@angular/common'; -import { TraceService } from 'src/app/service/trace.service'; -import { application } from 'src/environments/environment'; -import { DatabaseRequest, DatabaseRequestStage } from 'src/app/model/trace.model'; +import {Component, ElementRef, NgZone, OnDestroy, ViewChild} from '@angular/core'; + +import {ActivatedRoute} from '@angular/router'; +import {combineLatest, forkJoin} from "rxjs"; +import {DataItem, Timeline} from 'vis-timeline'; +import {Utils} from 'src/app/shared/util'; +import {DatePipe, Location} from '@angular/common'; +import {TraceService} from 'src/app/service/trace.service'; +import {application} from 'src/environments/environment'; +import {DatabaseRequest, DatabaseRequestStage} from 'src/app/model/trace.model'; import {EnvRouter} from "../../../service/router.service"; @Component({ @@ -21,44 +21,47 @@ export class DatabaseComponent implements OnDestroy { dbQueryId: number; dbQueryParentId: string; dbQueryParentType: string; + mainType: string; isComplete: boolean = true; isLoading: boolean = false; paramsSubscription: any; - timeLine: any; + timeLine: Timeline; env: any; pipe = new DatePipe('fr-FR') @ViewChild('timeline') timelineContainer: ElementRef; - jdbcActionDescription: { [key: string]: string }= - { - 'CONNECTION': 'établir une connexion avec la base de données', - 'DISCONNECTION': '', - 'STATEMENT': 'Création et validation de la requête SQL', - 'EXECUTE': 'Exécution de la requête', - 'METADATA': "", - 'DATABASE': '', - 'SCHEMA': '', - 'BATCH': '', - 'COMMIT': 'This command is used to permanently save all changes made during the current transaction. Once a transaction is committed, it cannot be undone', - 'ROLLBACK': ' Used to undo transactions that have not yet been committed. It can revert the database to the last committed state', - 'FETCH': 'Parcours et récupération de résultats', - 'MORE': '', - 'SAVEPOINT':'This command allows you to set a savepoint within a transaction' - }; + jdbcActionDescription: { [key: string]: string } = + { + 'CONNECTION': 'Etablir une connexion avec la base de données', + 'DISCONNECTION': '', + 'STATEMENT': 'Création et validation de la requête SQL', + 'EXECUTE': 'Exécution de la requête', + 'METADATA': "", + 'DATABASE': '', + 'SCHEMA': '', + 'BATCH': '', + 'COMMIT': 'This command is used to permanently save all changes made during the current transaction. Once a transaction is committed, it cannot be undone', + 'ROLLBACK': ' Used to undo transactions that have not yet been committed. It can revert the database to the last committed state', + 'FETCH': 'Parcours et récupération de résultats', + 'MORE': '', + 'SAVEPOINT': 'This command allows you to set a savepoint within a transaction' + }; constructor(private _activatedRoute: ActivatedRoute, - private _traceService: TraceService, - private _router: EnvRouter, - private _location: Location) { + private _traceService: TraceService, + private _router: EnvRouter, + private _location: Location) { this.paramsSubscription = combineLatest([ this._activatedRoute.params, + this._activatedRoute.data, this._activatedRoute.queryParams ]).subscribe({ - next: ([params, queryParams]) => { + next: ([params, data, queryParams]) => { this.dbQueryId = params.id_database; this.dbQueryParentId = params.id_session; - this.dbQueryParentType = params.type_session; + this.dbQueryParentType = data.type; + this.mainType = params.type_main; this.env = queryParams.env || application.default_env; this._location.replaceState(`${this._router.url.split('?')[0]}?env=${this.env}`) this.getDbRequestById(); @@ -76,8 +79,6 @@ export class DatabaseComponent implements OnDestroy { if (res) { this.selectedQuery = res.query; this.selectedQuery.actions = res.stages; - //this.groupQueriesBySchema(); - // this.configDbactions(this.selectedQuery) this.visjs(); this.isLoading = false; this.isComplete = true; @@ -94,30 +95,27 @@ export class DatabaseComponent implements OnDestroy { } visjs() { - let timeline_end = Math.round(+this.selectedQuery.end)* 1000; - let timeline_start = Math.trunc(+this.selectedQuery.start)* 1000 ; + if (this.timeLine) { // destroy if exists + this.timeLine.destroy(); + } + let timeline_end = Math.ceil(this.selectedQuery.end * 1000) ; + let timeline_start = Math.trunc(this.selectedQuery.start * 1000); let actions = this.selectedQuery.actions; this.sortInnerArrayByDate(actions) - let g = new Set(); - actions.forEach((c: DatabaseRequestStage) => { - g.add(c.name); - }); - - let groups = Array.from(g).map((g: string) => ({ id: g, content: g, title: this.jdbcActionDescription[g] })) - + let groups = actions.map((g: DatabaseRequestStage,i:number ) => ({ id: i, content: g?.name, title: this.jdbcActionDescription[g?.name] })) + let dataArray = actions.map((c: DatabaseRequestStage, i: number) => { let e: any = { group: groups[i].id, - // content: "c.type", - start: Math.trunc(+c.start * 1000), - end: Math.trunc(+c.end * 1000), - title: `${this.pipe.transform(new Date(+c.start * 1000), 'HH:mm:ss.SSS')} - ${this.pipe.transform(new Date(+c.end * 1000), 'HH:mm:ss.SSS')}
-

${c.name}${c?.count ? '(' + c?.count + ')' : ''}: ${this.getElapsedTime(+c.end, +c.start).toFixed(3)}s

`, + start: Math.trunc(c.start * 1000), + end: Math.trunc(c.end * 1000), + title: `${this.pipe.transform(new Date(c.start * 1000), 'HH:mm:ss.SSS')} - ${this.pipe.transform(new Date(c.end * 1000), 'HH:mm:ss.SSS')}
+

${c.name}${c?.count ? '(' + c?.count + ')' : ''}: ${this.getElapsedTime(c.end, c.start).toFixed(3)}s

`, //className : 'vis-dot', } - if(c.name == 'FETCH' && c.count){ // changed c.type to c.name - e.content = `Lignes Récupérées: ${c.count}` + if((c.name == 'FETCH' || c.name == 'BATCH' ||c.name == 'EXECUTE') && c.count){ // changed c.type to c.name + e.content = c.count.toString(); } e.type = e.end <= e.start ? 'point' : 'range'// TODO : change this to equals dh_dbt is set to timestamps(6), currently set to timestmap(3) if (c?.exception?.message || c?.exception?.type) { @@ -128,27 +126,24 @@ export class DatabaseComponent implements OnDestroy { return e; }) + console.log(this.selectedQuery, dataArray, groups, timeline_start, timeline_end) - if (this.timeLine) { // destroy if exists - this.timeLine.destroy(); - } // Create a Timeline this.timeLine = new Timeline(this.timelineContainer.nativeElement, dataArray, groups, { - //stack:false, - // min: timeline_start, - // max: timeline_end, + min: timeline_start, + max: timeline_end, margin: { - item: { - horizontal: -1 - } - }, + item: { + horizontal: -1 + } + }, selectable : false, clickToUse: true, tooltip: { followMouse: true - }, + } }); } @@ -186,7 +181,12 @@ export class DatabaseComponent implements OnDestroy { let diffElapsed = new Date(db.end * 1000).getTime() - new Date(+query.actions[i + 1].start * 1000).getTime(); if (diffElapsed != 0) { - query.actions.splice(i + 1, 0, { 'name': ' ', 'exception': { 'type': null, 'message': null }, 'start': db.end, 'end': query.actions[i + 1].start }) + query.actions.splice(i + 1, 0, { + 'name': ' ', + 'exception': {'type': null, 'message': null}, + 'start': db.end, + 'end': query.actions[i + 1].start + }) } } }); @@ -201,21 +201,22 @@ export class DatabaseComponent implements OnDestroy { let params: any[] = []; switch (targetType) { case "parent": - params.push('session', this.dbQueryParentType, this.dbQueryParentId) + if(this.mainType) params.push('session', this.dbQueryParentType, this.mainType, this.dbQueryParentId) + else params.push('session', this.dbQueryParentType, this.dbQueryParentId) } if (event.ctrlKey) { this._router.open(`#/${params.join('/')}`, '_blank') } else { this._router.navigate(params, { - queryParams: { env: this.env } + queryParams: {env: this.env} }); } } - sortInnerArrayByDate(innerArray: any[]): any[] { + sortInnerArrayByDate(innerArray: DatabaseRequestStage[]): any[] { return innerArray.sort((a, b) => { - return a.start - b.start + return a.order - b.order }); } @@ -244,6 +245,5 @@ export class DatabaseComponent implements OnDestroy { } - } diff --git a/src/app/views/detail/session/_component/database-table/database-table.component.html b/src/app/views/detail/session/_component/database-table/database-table.component.html index e751ec4..034fba2 100644 --- a/src/app/views/detail/session/_component/database-table/database-table.component.html +++ b/src/app/views/detail/session/_component/database-table/database-table.component.html @@ -4,8 +4,8 @@ - diff --git a/src/app/views/detail/session/_component/rest-table/rest-table.component.html b/src/app/views/detail/session/_component/rest-table/rest-table.component.html index 04936cf..d7278d2 100644 --- a/src/app/views/detail/session/_component/rest-table/rest-table.component.html +++ b/src/app/views/detail/session/_component/rest-table/rest-table.component.html @@ -32,8 +32,9 @@ - + diff --git a/src/app/views/detail/session/_component/rest-table/rest-table.component.ts b/src/app/views/detail/session/_component/rest-table/rest-table.component.ts index 18eada0..c8d632c 100644 --- a/src/app/views/detail/session/_component/rest-table/rest-table.component.ts +++ b/src/app/views/detail/session/_component/rest-table/rest-table.component.ts @@ -47,6 +47,7 @@ export class RestTableComponent implements OnInit { } selectedRequest(event: MouseEvent, row: any) { + console.log(row) this.onClickRow.emit({event: event, row: row}); } diff --git a/src/app/views/detail/session/_component/timeline/timeline.component.html b/src/app/views/detail/session/_component/timeline/timeline.component.html index e6c749d..1e8fe3f 100644 --- a/src/app/views/detail/session/_component/timeline/timeline.component.html +++ b/src/app/views/detail/session/_component/timeline/timeline.component.html @@ -1 +1 @@ -
+
diff --git a/src/app/views/detail/session/_component/timeline/timeline.component.ts b/src/app/views/detail/session/_component/timeline/timeline.component.ts index 398401b..f83619d 100644 --- a/src/app/views/detail/session/_component/timeline/timeline.component.ts +++ b/src/app/views/detail/session/_component/timeline/timeline.component.ts @@ -12,7 +12,7 @@ import {EnvRouter} from "../../../../../service/router.service"; export class TimelineComponent implements OnChanges { private _router: EnvRouter = inject(EnvRouter); - timeline: any; + timeline: Timeline; pipe = new DatePipe('fr-FR'); @ViewChild('timeline', {static: true}) timelineElement: ElementRef; @@ -21,7 +21,7 @@ export class TimelineComponent implements OnChanges { @Input() request:InstanceMainSession | InstanceRestSession; ngOnChanges(changes: SimpleChanges): void { - if( changes.instance || changes.request){ + if(changes.instance || changes.request){ if(this.instance && this.request){ let timeline_end = +this.request.end * 1000 let timeline_start = +this.request.start * 1000 @@ -49,7 +49,7 @@ export class TimelineComponent implements OnChanges { } data = dataArray.map((c: any, i: number) => { let o = { - id: c.hasOwnProperty('schema') ? -i : c.id, + id: c.id ?? -1, group: isWebapp ? 0 : c.threadName, content: c.hasOwnProperty('isStage') ? '' : (c.schema || c.host || 'N/A'), start: c.start * 1000, @@ -65,7 +65,7 @@ export class TimelineComponent implements OnChanges { return o; }) - + console.log(data, dataArray) if (this.timeline) { // destroy if exists this.timeline.destroy(); } @@ -73,7 +73,7 @@ export class TimelineComponent implements OnChanges { this.timeline = new Timeline(this.timelineElement.nativeElement, data, groups, { min: timeline_start, max: timeline_end, - clickToUse: true, + clickToUse: false, selectable : false, tooltip: { followMouse: true @@ -89,16 +89,20 @@ export class TimelineComponent implements OnChanges { }); let that = this; - this.timeline.on('select', function (props: any) { - let id = props.items[0]; - if (isNaN(+id)) { - that._router.navigate(['/session', 'rest', id]); + this.timeline.on('click', function (props: any) { + let id = props.item; + console.log('test', props) + if (isNaN(id)) { + that._router.navigate(['session', 'rest', id]); + } else { + if(id != -1) + that._router.navigate(['session', 'rest', that.request.id, 'database', id]); } }); if (timeline_end != +this.request.end * 1000) { this.timeline.addCustomTime(+this.request.end * 1000, "async"); - this.timeline.setCustomTimeMarker("async", "async"); + } } } diff --git a/src/app/views/detail/session/main/main.component.html b/src/app/views/detail/session/main/main.component.html index 8834c0e..ddf47ad 100644 --- a/src/app/views/detail/session/main/main.component.html +++ b/src/app/views/detail/session/main/main.component.html @@ -1,20 +1,13 @@
- + - + settings_suggest {{ '[' + session.type + '] ' + session.name || 'N/A' }}
- @@ -107,7 +100,7 @@
-
+
@@ -118,4 +111,14 @@
+
+ +
+

+ Aucun détail disponible ..
+

+
+ +
+ Chargement en cours...
\ No newline at end of file diff --git a/src/app/views/detail/session/main/main.component.ts b/src/app/views/detail/session/main/main.component.ts index a9e8fa7..7f2797a 100644 --- a/src/app/views/detail/session/main/main.component.ts +++ b/src/app/views/detail/session/main/main.component.ts @@ -82,6 +82,7 @@ export class MainComponent implements OnInit, OnDestroy { } selectedRequest(event: { event: MouseEvent, row: any }) { + console.log(event) if (event.row) { if (event.event.ctrlKey) { this._router.open(`#/session/rest/${event.row}`, '_blank',) @@ -94,9 +95,9 @@ export class MainComponent implements OnInit, OnDestroy { selectedQuery(event: { event: MouseEvent, row: any }) { // TODO finish this if (event.row) { if (event.event.ctrlKey) { - this._router.open(`#/session/main/${this.session.id}/database/${event.row}`, '_blank',) + this._router.open(`#/session/main/${this.session.type}/${this.session.id}/database/${event.row}`, '_blank',) } else { - this._router.navigate(['/session/main', this.session.id, 'database', event.row], { + this._router.navigate(['/session/main', this.session.type, this.session.id, 'database', event.row], { queryParams: { env: this.instance.env } }); } @@ -113,7 +114,7 @@ export class MainComponent implements OnInit, OnDestroy { params.push('statistic', 'app', this.session.appName) break; case "tree": - params.push('session', 'main', this.session.id, 'tree') + params.push('session', 'main', this.session.type, this.session.id, 'tree') break; case "parent": params.push('session', this.sessionParent.type, this.sessionParent.id) diff --git a/src/app/views/detail/session/rest/rest.component.html b/src/app/views/detail/session/rest/rest.component.html index 57b8685..ac1ccc4 100644 --- a/src/app/views/detail/session/rest/rest.component.html +++ b/src/app/views/detail/session/rest/rest.component.html @@ -1,9 +1,8 @@
+ [ngStyle]="{'border-left': session.status >= 200 && session.status < 300 ? '4px solid green' : + session.status >= 300 && session.status < 500 ? '4px solid orange' : '4px solid red'}"> swap_vert {{ session.outDataSize }}o en {{ session.end - session.start | number :'1.2-3' }}s
- {{session.status}} + + {{session.status}} @@ -126,4 +125,25 @@ (onClickRow)="selectedQuery($event)">
+
+
+ +
+ view_timeline + Chronologie +
+ +
+ +
+
+ +
+

+ Aucun détail disponible ..
+

+
+ +
+ Chargement en cours...
\ No newline at end of file diff --git a/src/app/views/detail/session/rest/rest.component.ts b/src/app/views/detail/session/rest/rest.component.ts index faec0e4..a6e0670 100644 --- a/src/app/views/detail/session/rest/rest.component.ts +++ b/src/app/views/detail/session/rest/rest.component.ts @@ -70,6 +70,7 @@ export class RestComponent implements OnInit, OnDestroy { } selectedRequest(event: { event: MouseEvent, row: any }) { + console.log(event) if (event.row) { if (event.event.ctrlKey) { this._router.open(`#/session/rest/${event.row}`, '_blank',) @@ -117,10 +118,14 @@ export class RestComponent implements OnInit, OnDestroy { params.push('statistic', 'app', this.session.appName) break; case "tree": - params.push('session/rest', this.session.id, 'tree') + params.push('session', 'rest', this.session.id, 'tree') break; case "parent": - params.push('session', this.sessionParent.type, this.sessionParent.id) + if(this.sessionParent.type == 'rest') { + params.push('session', 'rest', this.sessionParent.id) + } else { + params.push('session', 'main', this.sessionParent.type.toLowerCase(), this.sessionParent.id) + } } if (event.ctrlKey) { this._router.open(`#/${params.join('/')}`, '_blank') diff --git a/src/app/views/search/main/main.component.html b/src/app/views/search/main/main.component.html index bb7cd50..6d9318b 100644 --- a/src/app/views/search/main/main.component.html +++ b/src/app/views/search/main/main.component.html @@ -1,4 +1,4 @@ - +
@@ -27,8 +27,8 @@ - + @@ -91,7 +91,7 @@ - +
diff --git a/src/app/views/search/main/main.component.ts b/src/app/views/search/main/main.component.ts index db159ef..d326fcf 100644 --- a/src/app/views/search/main/main.component.ts +++ b/src/app/views/search/main/main.component.ts @@ -38,6 +38,11 @@ export class MainComponent implements OnInit, OnDestroy { filter: string = ''; params: Partial<{ env: string, start: Date, end: Date, type: string }> = {}; + mappingType = { + batch: 'BATCH', + startup: 'Serveur', + view: 'Vue' + } @ViewChild(MatPaginator) paginator: MatPaginator; @ViewChild(MatSort) sort: MatSort; @@ -76,7 +81,7 @@ export class MainComponent implements OnInit, OnDestroy { getMainRequests() { let params = { 'env': this.params.env, - 'launchmode': this.params.type, + 'launchmode': this.params.type.toUpperCase(), 'start': this.params.start.toISOString(), 'end': this.params.end.toISOString(), 'lazy': false @@ -140,10 +145,11 @@ export class MainComponent implements OnInit, OnDestroy { } selectedRequest(event: MouseEvent, row: any) { + console.log(row) if (event.ctrlKey) { - this._router.open(`#/session/main/${row.type}/${row}`, '_blank') + this._router.open(`#/session/main/${row.type.toLowerCase()}/${row.id}`, '_blank') } else { - this._router.navigate(['/session/main', row.type, row], { + this._router.navigate(['/session/main', row.type.toLowerCase(), row.id], { queryParams: { 'env': this.params.env } }); } diff --git a/src/app/views/search/rest/rest.component.html b/src/app/views/search/rest/rest.component.html index 4744901..50d9ec8 100644 --- a/src/app/views/search/rest/rest.component.html +++ b/src/app/views/search/rest/rest.component.html @@ -1,4 +1,4 @@ - + diff --git a/src/app/views/statistic/application/application.component.ts b/src/app/views/statistic/application/application.component.ts index f71e6fa..948b5ed 100644 --- a/src/app/views/statistic/application/application.component.ts +++ b/src/app/views/statistic/application/application.component.ts @@ -138,9 +138,9 @@ export class ApplicationComponent implements OnInit, OnDestroy { }))) }, repartitionRequestByPeriodLine: { observable: this._statsService.getRestSession({ 'column': "count:count,count_error_server:countErrorServer,count_slowest:countSlowest,rest_session.start.date:date", 'rest_session.instance_env': 'instance.id', 'instance.app_name': name, 'rest_session.start.ge': new Date(now.getFullYear(), now.getMonth(), now.getDate() - 6).toISOString(), 'rest_session.start.lt': now.toISOString(), 'instance.environement': env, 'order': 'rest_session.start.date.asc', ...advancedParams }) }, - repartitionUserPolar: { observable: this._statsService.getRestSession({ 'column': "count:count,instance.user:user", 'rest_session.instance_env': 'instance.id', 'instance.app_name': name, 'rest_session.start.ge': start.toISOString(), 'rest_session.start.lt': end.toISOString(), 'instance.environement': env, 'instance.user.not': 'null', 'order': 'count.desc', ...advancedParams }).pipe(map((r: any[]) => r.slice(0, 5))) }, + repartitionUserPolar: { observable: this._statsService.getRestSession({ 'column': "count:count,user:user", 'instance_env': 'instance.id', 'instance.app_name': name, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'instance.environement': env, 'user.not': 'null', 'order': 'count.desc', ...advancedParams }).pipe(map((r: any[]) => r.slice(0, 5))) }, repartitionUserBar: { - observable: this._statsService.getRestSession({ 'column': `count:count,rest_session.start.${groupedBy}:date,rest_session.start.year:year,instance.user:user`, 'rest_session.instance_env': 'instance.id', 'instance.app_name': name, 'rest_session.start.ge': start.toISOString(), 'rest_session.start.lt': end.toISOString(), 'instance.environement': env, 'instance.user.not': 'null', 'order': `rest_session.start.year.asc,rest_session.start.${groupedBy}.asc`, ...advancedParams }).pipe(map((r: any[]) => { + observable: this._statsService.getRestSession({ 'column': `count:count,start.${groupedBy}:date,start.year:year,user:user`, 'instance_env': 'instance.id', 'instance.app_name': name, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'instance.environement': env, 'user.not': 'null', 'order': `start.year.asc,start.${groupedBy}.asc`, ...advancedParams }).pipe(map((r: any[]) => { let groupBy = groupingBy(r, 'user'); let results: { count: number, user: string, date: any, year: any }[] = Object.entries(groupBy).map((value: [string, any[]]) => { return { @@ -161,8 +161,8 @@ export class ApplicationComponent implements OnInit, OnDestroy { })) }, repartitionApiBar: { observable: this._statsService.getRestSession({ 'column': "count_succes:countSucces,count_error_client:countErrorClient,count_error_server:countErrorServer,api_name", 'rest_session.instance_env': 'instance.id', 'instance.app_name': name, 'rest_session.start.ge': start.toISOString(), 'rest_session.start.lt': end.toISOString(), 'instance.environement': env, 'api_name.not': 'null', 'order': 'count.desc', ...advancedParams }).pipe(map((d: any) => d.slice(0, 5))) }, - dependentsTable: { observable: this._statsService.getRestSession({ 'column': "count:count,count_succes:countSucces,count_error_client:countErrClient,count_error_server:countErrServer,instance.app_name:name", 'rest_session.instance_env': 'instance.id', "rest_session.id": "rest_request.parent", "rest_request.remote": "rest_session2.id", 'instance.app_name': name, 'rest_session.start.ge': start.toISOString(), 'rest_session.start.lt': end.toISOString(), 'rest_session2.start.ge': start.toISOString(), 'rest_session2.start.lt': end.toISOString(), 'instance.environement': env, 'instance.app_name.not': 'null', 'order': 'count.desc', ...advancedParams }) }, - dependenciesTable: { observable: this._statsService.getRestSession({ 'column': "count:count,count_succes:countSucces,count_error_client:countErrClient,count_error_server:countErrServer,instance.app_name:name", 'rest_session.instance_env': 'instance.id', "rest_session.id": "rest_request.parent", "rest_request.remote": "rest_session2.id", 'instance.app_name': name, 'rest_session2.start.ge': start.toISOString(), 'rest_session2.start.lt': end.toISOString(), 'rest_session.start.ge': start.toISOString(), 'rest_session.start.lt': end.toISOString(), 'instance.environement': env, 'instance.app_name.not': 'null', 'order': 'count.desc', ...advancedParams }) }, + dependenciesTable: { observable: this._statsService.getRestSession({ 'column': "count:count,count_succes:countSucces,count_error_client:countErrClient,count_error_server:countErrServer,instance.app_name:name", 'instance_env': 'instance.id', 'id': 'rest_request.parent', 'rest_request.remote': 'rest_session_join.id', 'rest_session_join.instance_env': 'instance_join.id', 'instance_join.app_name': name, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'rest_session_join.start.ge': start.toISOString(), 'rest_session_join.start.lt': end.toISOString(), 'instance_join.environement': env, 'instance_join.app_name.not': 'null', 'order': 'count.desc', ...advancedParams }) }, + dependentsTable: { observable: this._statsService.getRestSession({ 'column': "count:count,count_succes:countSucces,count_error_client:countErrClient,count_error_server:countErrServer,instance_join.app_name:name", 'instance_env': 'instance.id', 'id': 'rest_request.parent', 'rest_request.remote': 'rest_session_join.id', 'rest_session_join.instance_env': 'instance_join.id', 'instance.app_name': name, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'rest_session_join.start.ge': start.toISOString(), 'rest_session_join.start.lt': end.toISOString(), 'instance.environement': env, 'instance.app_name.not': 'null', 'order': 'count.desc', ...advancedParams }) }, exceptionsTable: { observable: this._statsService.getRestSession({ 'column': 'count,err_type,err_msg', 'err.group': '', 'rest_session.instance_env': 'instance.id', "status.ge": 500, "instance.environement": env, "instance.app_name": name, 'rest_session.start.ge': start.toISOString(), 'rest_session.start.lt': end.toISOString(), 'order': 'count.desc', ...advancedParams })} }; }; diff --git a/src/app/views/statistic/rest/rest.component.html b/src/app/views/statistic/rest/rest.component.html index 90652c8..7901b21 100644 --- a/src/app/views/statistic/rest/rest.component.html +++ b/src/app/views/statistic/rest/rest.component.html @@ -1,4 +1,4 @@ - + @@ -17,9 +17,9 @@ - + + {{requests.infos?.data[0]?.app}} +
{ let now = new Date(); - var groupedBy = periodManagement(start, end); + const groupedBy = periodManagement(start, end); return { + infos: { observable: this._statsService.getRestSession({ 'column.distinct': 'instance.app_name:app', 'instance_env': 'instance.id', 'api_name': name, "instance.environement": env, 'start.ge': start.toISOString(), 'start.lt': end.toISOString() }) }, repartitionTimeAndTypeResponse: { observable: this._statsService.getRestSession({ 'column': "count_slowest:elapsedTimeSlowest,count_slow:elapsedTimeSlow,count_medium:elapsedTimeMedium,count_fast:elapsedTimeFast,count_fastest:elapsedTimeFastest,count_succes:countSucces,count_error_server:countErrorServer,count_error_client:countErrorClient", 'rest_session.instance_env': 'instance.id', 'api_name': name, 'rest_session.start.ge': start.toISOString(), 'rest_session.start.lt': end.toISOString(), 'instance.environement': env, ...advancedParams }) }, repartitionTimeAndTypeResponseByPeriod: { observable: this._statsService.getRestSession({ 'column': `count_succes:countSucces,count_error_client:countErrorClient,count_error_server:countErrorServer,count_slowest:elapsedTimeSlowest,count_slow:elapsedTimeSlow,count_medium:elapsedTimeMedium,count_fast:elapsedTimeFast,count_fastest:elapsedTimeFastest,elapsedtime.avg:avg,elapsedtime.max:max,rest_session.start.${groupedBy}:date,rest_session.start.year:year`, 'rest_session.instance_env': 'instance.id', 'api_name': name, 'rest_session.start.ge': start.toISOString(), 'rest_session.start.lt': end.toISOString(), 'instance.environement': env, 'order': `rest_session.start.year.asc,rest_session.start.${groupedBy}.asc`, ...advancedParams }).pipe(map((r: any[]) => { @@ -162,9 +163,9 @@ export class RestComponent implements OnInit, OnDestroy { return r; })) }, - dependentsTable: { observable: this._statsService.getRestSession({ 'column': "count:count,count_succes:countSucces,count_error_client:countErrClient,count_error_server:countErrServer,rest_session2.api_name:name", 'rest_session.instance_env': 'instance.id', "rest_session.id": "rest_request.parent", "rest_request.remote": "rest_session2.id", 'rest_session.api_name': name, 'rest_session.start.ge': start.toISOString(), 'rest_session.start.lt': end.toISOString(), 'rest_session2.start.ge': start.toISOString(), 'rest_session2.start.lt': end.toISOString(), 'instance.environement': env, 'rest_session2.api_name.not': 'null', 'order': 'count.desc', ...advancedParams }) }, - dependenciesTable: { observable: this._statsService.getRestSession({ 'column': "count:count,count_succes:countSucces,count_error_client:countErrClient,count_error_server:countErrServer,rest_session.api_name:name", 'rest_session.instance_env': 'instance.id', "rest_session.id": "rest_request.parent", "rest_request.remote": "rest_session2.id", 'rest_session2.api_name': name, 'rest_session2.start.ge': start.toISOString(), 'rest_session2.start.lt': end.toISOString(), 'rest_session.start.ge': start.toISOString(), 'rest_session.start.lt': end.toISOString(), 'instance.environement': env, 'rest_session.api_name.not': 'null', 'order': 'count.desc', ...advancedParams }) }, - exceptionsTable: { observable: this._statsService.getRestSession({ 'column': 'count,err_type,err_msg', 'rest_session.instance_env': 'instance.id', 'err.group': '', "status.ge": 500, "instance.environement": env, "api_name": name, 'rest_session.start.ge': start.toISOString(), 'rest_session.start.lt': end.toISOString(), 'order': 'count.desc', ...advancedParams })} + dependenciesTable: { observable: this._statsService.getRestSession({ 'column': "count:count,count_succes:countSucces,count_error_client:countErrClient,count_error_server:countErrServer,api_name:name", 'instance_env': 'instance.id', "id": "rest_request.parent", "rest_request.remote": "rest_session_join.id", 'rest_session_join.api_name': name, 'rest_session_join.start.ge': start.toISOString(), 'rest_session_join.start.lt': end.toISOString(), 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'instance.environement': env, 'api_name.not': 'null', 'order': 'count.desc', ...advancedParams }) }, + dependentsTable: { observable: this._statsService.getRestSession({ 'column': "count:count,count_succes:countSucces,count_error_client:countErrClient,count_error_server:countErrServer,rest_session_join.api_name:name", 'instance_env': 'instance.id', "id": "rest_request.parent", "rest_request.remote": "rest_session_join.id", 'api_name': name, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'rest_session_join.start.ge': start.toISOString(), 'rest_session_join.start.lt': end.toISOString(), 'instance.environement': env, 'rest_session_join.api_name.not': 'null', 'order': 'count.desc', ...advancedParams }) }, + exceptionsTable: { observable: this._statsService.getRestSession({ 'column': 'count,err_type,err_msg', 'instance_env': 'instance.id', 'err.group': '', "status.ge": 500, "instance.environement": env, "api_name": name, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'order': 'count.desc', ...advancedParams })} }; } diff --git a/src/app/views/tree/tree.component.html b/src/app/views/tree/tree.component.html index d8d1b38..ab17daf 100644 --- a/src/app/views/tree/tree.component.html +++ b/src/app/views/tree/tree.component.html @@ -1,9 +1,9 @@ - +
-
+
diff --git a/src/app/views/tree/tree.component.scss b/src/app/views/tree/tree.component.scss index dbe2265..5a356e9 100644 --- a/src/app/views/tree/tree.component.scss +++ b/src/app/views/tree/tree.component.scss @@ -1,7 +1,7 @@ #container { - height: calc(100vh - 56px - 48px - 0.5em); + height: calc(100vh - 56px - 48px - 1em); overflow-x: hidden; display: flex; flex-direction: column; diff --git a/src/app/views/tree/tree.component.ts b/src/app/views/tree/tree.component.ts index 6042bfe..78897b3 100644 --- a/src/app/views/tree/tree.component.ts +++ b/src/app/views/tree/tree.component.ts @@ -44,16 +44,18 @@ export class TreeComponent implements OnDestroy { constructor() { const self = this; - combineLatest({ - paramsList: this._activatedRoute.paramMap, - queryParams: this._activatedRoute.queryParams - }).subscribe({ - next: (v: { paramsList: Params, queryParams: Params }) => { - this.id = v.paramsList.params['id_session']; - this.env = v.queryParams.env || application.default_env; + combineLatest([ + this._activatedRoute.params, + this._activatedRoute.data, + this._activatedRoute.queryParams + ]).subscribe({ + next: ([params, data, queryParams]) => { + console.log(params, queryParams) + this.id = params['id_session']; + this.env = queryParams.env || application.default_env; this._location.replaceState(`${this._router.url.split('?')[0]}?env=${this.env}`) this.isLoading = true; - this._traceService.getTree(this.id, v.paramsList.params['type_session']).pipe(finalize(() => this.isLoading = false)).subscribe(d => { + this._traceService.getTree(this.id, data['type']).pipe(finalize(() => this.isLoading = false)).subscribe(d => { this.exchange = {}; this.exchange['remoteTrace'] = d; @@ -550,11 +552,12 @@ export class TreeComponent implements OnDestroy { } getVertexIconType(exchange: any) { + console.log(exchange); if (exchange.hasOwnProperty('productName')) return this.vertexIcons['DATABASE'][exchange.completed]; if (exchange.remoteTrace["@type"] == "main") - return this.vertexIcons[exchange.remoteTrace.launchMode] + return this.vertexIcons[exchange.remoteTrace.type] if (exchange.remoteTrace['@type'] == "unknown") return this.vertexIcons["unknown"][exchange["status"]]; From 83602c3538204603bfa2d8d89a92a370af0d3f6e Mon Sep 17 00:00:00 2001 From: fufuu Date: Wed, 31 Jul 2024 17:29:20 +0200 Subject: [PATCH 043/126] typage --- src/app/views/search/main/main.component.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/app/views/search/main/main.component.ts b/src/app/views/search/main/main.component.ts index d326fcf..e9b3f7b 100644 --- a/src/app/views/search/main/main.component.ts +++ b/src/app/views/search/main/main.component.ts @@ -38,11 +38,12 @@ export class MainComponent implements OnInit, OnDestroy { filter: string = ''; params: Partial<{ env: string, start: Date, end: Date, type: string }> = {}; - mappingType = { + mappingType: {[key: string]: string} = { batch: 'BATCH', startup: 'Serveur', view: 'Vue' } + @ViewChild(MatPaginator) paginator: MatPaginator; @ViewChild(MatSort) sort: MatSort; From dc6a552c3607e3e79f65c82b4a919e2e12b3df48 Mon Sep 17 00:00:00 2001 From: fufuu Date: Mon, 5 Aug 2024 15:31:20 +0200 Subject: [PATCH 044/126] hotfix et evols --- src/app/app.component.html | 68 ++++--- src/app/app.component.scss | 2 +- src/app/app.component.ts | 124 +++++++------ src/app/shared/pipe/duration.pipe.ts | 6 +- src/app/shared/util.ts | 2 +- src/app/views/constants.ts | 7 + .../database-table.component.ts | 8 +- .../rest-table/rest-table.component.ts | 3 +- .../detail/session/session.component.html | 174 ------------------ .../detail/session/session.component.scss | 77 -------- .../views/detail/session/session.component.ts | 161 ---------------- src/app/views/search/main/main.component.html | 2 +- src/app/views/search/main/main.component.ts | 11 +- src/app/views/search/rest/rest.component.html | 4 +- src/app/views/search/rest/rest.component.ts | 6 +- .../exception-table.component.html | 2 +- .../application/application.component.ts | 3 +- 17 files changed, 132 insertions(+), 528 deletions(-) delete mode 100644 src/app/views/detail/session/session.component.html delete mode 100644 src/app/views/detail/session/session.component.scss delete mode 100644 src/app/views/detail/session/session.component.ts diff --git a/src/app/app.component.html b/src/app/app.component.html index 7a9ef5a..c542060 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -1,34 +1,42 @@ - - - + + + \ No newline at end of file diff --git a/src/app/app.component.scss b/src/app/app.component.scss index 040870e..a7af3cb 100644 --- a/src/app/app.component.scss +++ b/src/app/app.component.scss @@ -5,5 +5,5 @@ } .item-selected { - background: rgba(0,0,0,.2); + background-color: var(--mat-menu-item-hover-state-layer-color); } \ No newline at end of file diff --git a/src/app/app.component.ts b/src/app/app.component.ts index c3e1f7d..f01a99c 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -1,77 +1,83 @@ -import {Component, OnDestroy, OnInit} from '@angular/core'; +import {Component, inject, OnDestroy, OnInit} from '@angular/core'; import {FormControl} from '@angular/forms'; import {ActivatedRoute} from '@angular/router'; import {distinctUntilChanged, finalize, Subscription} from 'rxjs'; import {application, environment} from 'src/environments/environment'; import {JQueryService} from './service/jquery.service'; import {EnvRouter} from "./service/router.service"; +import {Constants} from "./views/constants"; @Component({ - selector: 'app-root', - templateUrl: 'app.component.html', - styleUrls: ['app.component.scss'] + selector: 'app-root', + templateUrl: 'app.component.html', + styleUrls: ['app.component.scss'] }) - export class AppComponent implements OnInit, OnDestroy { - envs: any[]; - env: FormControl = new FormControl(); - isLoadingEnv = false; - subscriptions: Subscription[] = []; - + private _activatedRoute: ActivatedRoute = inject(ActivatedRoute); + private _service: JQueryService = inject(JQueryService); + private _router: EnvRouter = inject(EnvRouter); - constructor( - private _activatedRoute: ActivatedRoute, - private _router: EnvRouter, - private _service: JQueryService) { - this.isLoadingEnv = true; - this.subscriptions.push(this._service.getInstance({'column.distinct': 'environement', 'environement.not': 'null', 'order': 'environement.asc'}) - .pipe(finalize(() => this.isLoadingEnv = false)) - .subscribe({ - next: (res: {environement: string}[]) => { - this.envs = res.map(r => r.environement); - } - })); - this.subscriptions.push(this.env.valueChanges - .pipe( - distinctUntilChanged((previous: string, current: string) => { - return previous == current; - })) - .subscribe({ - next: res => { - this._router.navigate([], { - queryParamsHandling: 'merge', - queryParams: { env: res } - }); - } - })); + MAPPING_TYPE = Constants.MAPPING_TYPE; + envs: any[]; + env: FormControl = new FormControl(); + isLoadingEnv = false; + subscriptions: Subscription[] = []; - this.subscriptions.push(this._activatedRoute.queryParams - .subscribe({ - next: res => { // TODO res.env always undefined - let r = this._activatedRoute.snapshot.queryParams['env']; - if(!r){ - r = application.default_env; - } - if (this.env.value != r) { - this.env.setValue(r, { emitEvent: false }); - } - } - })); - } - ngOnInit(): void { - this.envs = [application.default_env]; - if (!localStorage.getItem('server')) { - localStorage.setItem('server', environment.url); + constructor() { + this.isLoadingEnv = true; + this.subscriptions.push(this._service.getInstance({ + 'column.distinct': 'environement', + 'environement.not': 'null', + 'order': 'environement.asc' + }) + .pipe(finalize(() => this.isLoadingEnv = false)) + .subscribe({ + next: (res: { environement: string }[]) => { + this.envs = res.map(r => r.environement); + } + })); + this.subscriptions.push(this.env.valueChanges + .pipe( + distinctUntilChanged((previous: string, current: string) => { + return previous == current; + })) + .subscribe({ + next: res => { + this._router.navigate([], { + queryParamsHandling: 'merge', + queryParams: {env: res} + }); + } + })); + + this.subscriptions.push(this._activatedRoute.queryParams + .subscribe({ + next: res => { // TODO res.env always undefined + let r = this._activatedRoute.snapshot.queryParams['env']; + if (!r) { + r = application.default_env; + } + if (this.env.value != r) { + this.env.setValue(r, {emitEvent: false}); + } + } + })); } - } - ngOnDestroy(): void { - this.unsubscribe(); -} + ngOnInit(): void { + this.envs = [application.default_env]; + if (!localStorage.getItem('server')) { + localStorage.setItem('server', environment.url); + } + } - unsubscribe() { - this.subscriptions.forEach(s => s.unsubscribe()); - } + ngOnDestroy(): void { + this.unsubscribe(); + } + + unsubscribe() { + this.subscriptions.forEach(s => s.unsubscribe()); + } } diff --git a/src/app/shared/pipe/duration.pipe.ts b/src/app/shared/pipe/duration.pipe.ts index 514c9b1..7cbdca1 100644 --- a/src/app/shared/pipe/duration.pipe.ts +++ b/src/app/shared/pipe/duration.pipe.ts @@ -1,15 +1,17 @@ -import { Pipe, PipeTransform } from "@angular/core"; +import {inject, Pipe, PipeTransform} from "@angular/core"; +import {DecimalPipe} from "@angular/common"; @Pipe({ name:"duration" }) export class DurationPipe implements PipeTransform { + _decimalPipe = inject(DecimalPipe); transform(value: any, ...args: any[]):string { if(!value && value !== 0) return ''; - const remainingSeconds = Math.floor(value % 60); + const remainingSeconds = this._decimalPipe.transform(Math.round((value % 60) * 1000) / 1000); const minutes = Math.floor((value % 3600) / 60); const hours = Math.floor(value/3600); diff --git a/src/app/shared/util.ts b/src/app/shared/util.ts index 267b74f..e289df2 100644 --- a/src/app/shared/util.ts +++ b/src/app/shared/util.ts @@ -115,7 +115,7 @@ export class Utils { } -export function groupingBy(arr: any[], field: string): any { +export function groupingBy(arr: any[], field: string): {[key: string]: any[]} { return arr.reduce((acc, o) => { var key = o[field]; if (!acc[key]) { diff --git a/src/app/views/constants.ts b/src/app/views/constants.ts index 797681b..258d607 100644 --- a/src/app/views/constants.ts +++ b/src/app/views/constants.ts @@ -360,6 +360,13 @@ export class Constants { } } }; + + static readonly MAPPING_TYPE: {[key: string]: {title: string, icon: string}} = { + rest: {title: 'Liste des Appels REST', icon: 'swap_vert'}, + batch: {title: 'Lancement de Batch', icon: 'manufacturing'}, + startup: {title: 'Liste des Serveurs', icon: 'restart_alt'}, + view: {title: 'Navigation', icon: 'ads_click'} + } } export class Filter { diff --git a/src/app/views/detail/session/_component/database-table/database-table.component.ts b/src/app/views/detail/session/_component/database-table/database-table.component.ts index 452841b..327d2f0 100644 --- a/src/app/views/detail/session/_component/database-table/database-table.component.ts +++ b/src/app/views/detail/session/_component/database-table/database-table.component.ts @@ -48,14 +48,10 @@ export class DatabaseTableComponent implements OnInit { console.log(row) this.onClickRow.emit({event: event, row: row}); } - - statusBorder(status: any) { - return Utils.statusBorder(status); - } } const sortingDataAccessor = (row: any, columnName: string) => { + if (columnName == "start") return row['start'] as string; if (columnName == "duree") return (row["end"] - row["start"]) - var columnValue = row[columnName as keyof any] as string; - return columnValue; + return row[columnName as keyof any] as string; } \ No newline at end of file diff --git a/src/app/views/detail/session/_component/rest-table/rest-table.component.ts b/src/app/views/detail/session/_component/rest-table/rest-table.component.ts index c8d632c..b503c44 100644 --- a/src/app/views/detail/session/_component/rest-table/rest-table.component.ts +++ b/src/app/views/detail/session/_component/rest-table/rest-table.component.ts @@ -64,8 +64,7 @@ const sortingDataAccessor = (row: any, columnName: string) => { if (columnName == "host") return row["host"] + ":" + row["port"] as string; if (columnName == "start") return row['start'] as string; if (columnName == "duree") return (row["end"] - row["start"]); - var columnValue = row[columnName as keyof any] as string; - return columnValue; + return row[columnName as keyof any] as string; } const filterPredicate = (data: RestRequest, filter: string) => { diff --git a/src/app/views/detail/session/session.component.html b/src/app/views/detail/session/session.component.html deleted file mode 100644 index d68c883..0000000 --- a/src/app/views/detail/session/session.component.html +++ /dev/null @@ -1,174 +0,0 @@ -
-
- - - - - settings_suggest - {{selectedSessionType =='api' ? (selectedSession?.name|| 'N/A') - : '[' - + selectedSession?.type + '] ' + selectedSession?.name || 'N/A'}} - -
- - -
- -
- -
- - -
- warning{{selectedSession?.exception?.message - || selectedSession?.exception?.type}} -
-
- - - -
- - person -
- - {{selectedSession?.user || "N/A"}} - - le {{( selectedSession?.start*1000 ) | date: 'dd/MM/yyyy à HH:mm:ss.SSS': 'fr' }} -
-
- {{selectedSession?.inDataSize || 0}}o - swap_vert - {{selectedSession?.outDataSize}}o en {{ getElapsedTime(selectedSession?.end, selectedSession?.start) - | - number :'1.2-3'}}s -
- {{selectedSession?.status}} -
-
- - - - storage - {{instance?.name}} - -
- -
-
- - -
-
- Database -
-
- - {{ item.key }} - -
{{ item.value[0].productName }} v.{{ - item.value[0].productVersion}}
-
-
- - -
- -
- {{instance?.address}} en {{instance?.env}} -
- - {{instance?.os}} - - - {{instance?.re}} - -
-
-
-
-
- -
- west -
- Appels - sortants
-
- -
- -
-
-
- -
- Database -
Base de - donnée
-
- -
- -
-
-
- -
- view_timeline - Chronologie -
- -
- -
-
-
-

- Aucun détail disponible ..
- Vérifiez que TraceAPI est bien configuré sur {{ - selectedSession?.host}} -

-
-
- Chargement en cours... -
\ No newline at end of file diff --git a/src/app/views/detail/session/session.component.scss b/src/app/views/detail/session/session.component.scss deleted file mode 100644 index b10a13f..0000000 --- a/src/app/views/detail/session/session.component.scss +++ /dev/null @@ -1,77 +0,0 @@ -.header-card { - display: flex; - flex-direction: row; - gap: 0.5em; - margin-bottom: 2em; -} - -a { - color: inherit; - text-decoration: none; -} - -mat-card-title { - display: flex; - align-items: center; - padding: 0 16px; - height: 48px; - .right { - margin-left: auto; - } -} - -mat-card-content { - height: 100%; padding: 0 16px 16px; -} - -mat-card-footer { - padding: 0 16px; - border: 1px solid rgba(0,0,0,.05); - display: flex; - align-items: center; - gap: 0.5em; - font-style: italic; - font-size: 14px; - .right { - margin-left: auto; - display: flex; - align-items: center; - } -} - - -table { - table-layout: auto; -} -.dbfailed { - background-color: red !important; -} - -.mat-mdc-row .mat-mdc-cell { - cursor: pointer; -} - -.mat-mdc-row:hover .mat-mdc-cell { - background-color: rgb(206, 206, 206); -} - -.mat-mdc-table .mdc-data-table__header-row { - background-color: #d1d1d1; -} - -.url { - color: blue; - text-decoration: solid; -} - -.badge { - color: white; - padding: 0px 10px; - text-align: center; - border-radius: 12px; - font-size: 0.8em; -} - -.searchwidth { - flex-grow: 1; -} \ No newline at end of file diff --git a/src/app/views/detail/session/session.component.ts b/src/app/views/detail/session/session.component.ts deleted file mode 100644 index 6a68270..0000000 --- a/src/app/views/detail/session/session.component.ts +++ /dev/null @@ -1,161 +0,0 @@ -import { Component, Injectable, OnDestroy } from '@angular/core'; -import { ActivatedRoute, NavigationExtras, Router } from '@angular/router'; -import { Observable, catchError, combineLatest, finalize, forkJoin, map, of, switchMap } from "rxjs"; -import { Utils } from 'src/app/shared/util'; -import { Location } from '@angular/common'; -import { TraceService } from 'src/app/service/trace.service'; -import { application } from 'src/environments/environment'; -import { InstanceEnvironment, InstanceMainSession, InstanceRestSession } from 'src/app/model/trace.model'; - -@Component({ - templateUrl: './session.component.html', - styleUrls: ['./session.component.scss'], - -}) -export class SessionComponent implements OnDestroy { - selectedSession: InstanceMainSession | InstanceRestSession; // IncomingRequest | Mainrequest | OutcomingRequest; - instance: InstanceEnvironment; - selectedSessionType: string; - sessionParent: { id: string, type: string }; - isLoading: boolean = false; - paramsSubscription: any; - queryBySchema: any[]; - env: any; - - constructor(private _activatedRoute: ActivatedRoute, - private _traceService: TraceService, - private _router: EnvRouter, - private _location: Location) { - - this.paramsSubscription = combineLatest([ - this._activatedRoute.params, - this._activatedRoute.queryParams - ]).subscribe({ - next: ([params, queryParams]) => { - this.env = queryParams.env || application.default_env; - this.selectedSessionType = params.type; - this.selectedSession = null; - this.getSessionById(params.id); - this._location.replaceState(`${this._router.url.split('?')[0]}?env=${this.env}`) - } - }); - } - - getSessionById(id: string) { - this.isLoading = true; - var traceService = (this.selectedSessionType == "main" ? this._traceService.getMainSession(id) : this._traceService.getRestSession(id)); - traceService - .pipe( - switchMap((s: InstanceMainSession | InstanceRestSession) => { - return forkJoin({ - session: of(s), - instance: this._traceService.getInstance(s.instanceId), - parent: this._traceService.getSessionParent(id).pipe(catchError(() => of(null))), - requests: this._traceService.getRestRequests(s.id), - queries: this._traceService.getDatabaseRequests(s.id), - stages: this._traceService.getLocalRequests(s.id) - }); - }), - finalize(() => this.isLoading = false) - ) - .subscribe({ - next: (result) => { - if(result){ - this.selectedSession = result.session; - this.selectedSession.requests = result.requests; - this.selectedSession.queries = result.queries; - this.selectedSession.stages = result.stages; - this.instance = result.instance; - this.sessionParent = result.parent; - this.groupQueriesBySchema(); - } - - } - }); - } - - selectedRequest(event: { event: MouseEvent, row: any }) { - if (event.row) { - if (event.event.ctrlKey) { - this._router.open(`#/session/api/${event.row}`, '_blank',) - } else { - this._router.navigate(['/session', 'api', event.row], { queryParams: { env: this.env } }); // TODO remove env FIX BUG - } - } - } - - selectedQuery(event: { event: MouseEvent, row: any }) { // TODO finish this - console.log(event); - if (event.row) { - if (event.event.ctrlKey) { - this._router.open(`#/session/${this.selectedSessionType}/${this.selectedSession.id}/database/${event.row}`, '_blank',) - } else { - this._router.navigate(['/session', this.selectedSessionType, this.selectedSession.id, 'database', event.row], { - queryParams: { env: this.instance.env } - }); - } - } - } - - getStateColor() { - return Utils.getStateColor((this.selectedSession)?.status) - } - - getElapsedTime(end: number, start: number,) { - return end - start; - } - - getSessionDetailBorder() { - if (this.selectedSessionType == "api") - return Utils.statusBorderCard((this.selectedSession)?.status) - if (this.selectedSessionType == "main") - return Utils.statusBorderCard(!!(this.selectedSession)?.exception?.message) - - } - - groupQueriesBySchema() { - if (this.selectedSession.queries) { - this.queryBySchema = this.selectedSession.queries.reduce((acc: any, item) => { - if (!acc[item.name]) { - acc[item.name] = [] - } - acc[item.name].push(item); - return acc; - }, []); - } - } - - getSessionUrl() { - return Utils.getSessionUrl(this.selectedSession); - } - - navigate(event: MouseEvent, targetType: string, extraParam?: string) { - let params: any[] = []; - switch (targetType) { - case "api": - params.push('dashboard', 'api', this.selectedSession.name); - break; - case "app": - params.push('dashboard', 'app', this.selectedSession.appName) - break; - case "tree": - params.push('session', this.selectedSessionType, this.selectedSession.id, 'tree') - break; - case "parent": - params.push('session', this.sessionParent.type, this.sessionParent.id) - } - if (event.ctrlKey) { - this._router.open(`#/${params.join('/')}`, '_blank') - } else { - this._router.navigate(params, { - queryParams: { env: this.instance.env } - }); - } - } - - ngOnDestroy() { - if (this.paramsSubscription) { - this.paramsSubscription.unsubscribe(); - } - } -} \ No newline at end of file diff --git a/src/app/views/search/main/main.component.html b/src/app/views/search/main/main.component.html index 6d9318b..7506d32 100644 --- a/src/app/views/search/main/main.component.html +++ b/src/app/views/search/main/main.component.html @@ -1,4 +1,4 @@ - +
diff --git a/src/app/views/search/main/main.component.ts b/src/app/views/search/main/main.component.ts index e9b3f7b..238da01 100644 --- a/src/app/views/search/main/main.component.ts +++ b/src/app/views/search/main/main.component.ts @@ -9,7 +9,7 @@ import { Location } from '@angular/common'; import { Utils } from 'src/app/shared/util'; import { TraceService } from 'src/app/service/trace.service'; import { application, makePeriod } from 'src/environments/environment'; -import { FilterConstants, FilterMap, FilterPreset } from '../../constants'; +import {Constants, FilterConstants, FilterMap, FilterPreset} from '../../constants'; import { FilterService } from 'src/app/service/filter.service'; import { InstanceMainSession } from 'src/app/model/trace.model'; import {EnvRouter} from "../../../service/router.service"; @@ -20,6 +20,7 @@ import {EnvRouter} from "../../../service/router.service"; styleUrls: ['./main.component.scss'], }) export class MainComponent implements OnInit, OnDestroy { + MAPPING_TYPE = Constants.MAPPING_TYPE; filterConstants = FilterConstants; utils: Utils = new Utils(); displayedColumns: string[] = ['status', 'app_name', 'name', 'location', 'start', 'durée', 'user']; @@ -38,12 +39,6 @@ export class MainComponent implements OnInit, OnDestroy { filter: string = ''; params: Partial<{ env: string, start: Date, end: Date, type: string }> = {}; - mappingType: {[key: string]: string} = { - batch: 'BATCH', - startup: 'Serveur', - view: 'Vue' - } - @ViewChild(MatPaginator) paginator: MatPaginator; @ViewChild(MatSort) sort: MatSort; @@ -99,7 +94,7 @@ export class MainComponent implements OnInit, OnDestroy { this.dataSource.paginator = this.paginator; this.dataSource.sort = this.sort this.dataSource.sortingDataAccessor = (row: any, columnName: string) => { - if (columnName == "app_name") return row["application"]["name"] as string; + if (columnName == "app_name") return row["appName"] as string; if (columnName == "name") return row["name"] as string; if (columnName == "location") return row['location'] as string; if (columnName == "start") return row['start'] as string; diff --git a/src/app/views/search/rest/rest.component.html b/src/app/views/search/rest/rest.component.html index 50d9ec8..f80fcdd 100644 --- a/src/app/views/search/rest/rest.component.html +++ b/src/app/views/search/rest/rest.component.html @@ -1,4 +1,4 @@ - + @@ -105,7 +105,7 @@
{{ getElapsedTime(row.end, row.start) | number :'1.2-3'}}s
+ matTooltipClass="mat-tooltip">{{ getElapsedTime(row.end, row.start) | duration}}
diff --git a/src/app/views/search/rest/rest.component.ts b/src/app/views/search/rest/rest.component.ts index f1f17b5..768d0b6 100644 --- a/src/app/views/search/rest/rest.component.ts +++ b/src/app/views/search/rest/rest.component.ts @@ -10,7 +10,7 @@ import { Utils } from 'src/app/shared/util'; import { JQueryService } from 'src/app/service/jquery.service'; import { TraceService } from 'src/app/service/trace.service'; import { application, makePeriod } from 'src/environments/environment'; -import { FilterConstants, FilterPreset, FilterMap } from '../../constants'; +import {FilterConstants, FilterPreset, FilterMap, Constants} from '../../constants'; import { FilterService } from 'src/app/service/filter.service'; import { InstanceMainSession, InstanceRestSession, RestSession } from 'src/app/model/trace.model'; import {EnvRouter} from "../../../service/router.service"; @@ -21,6 +21,7 @@ import {EnvRouter} from "../../../service/router.service"; styleUrls: ['./rest.component.scss'], }) export class RestComponent implements OnInit, OnDestroy { + MAPPING_TYPE = Constants.MAPPING_TYPE; filterConstants = FilterConstants; nameDataList: any[]; displayedColumns: string[] = ['status', 'app_name', 'method/path', 'query', 'start', 'durée', 'user']; @@ -55,6 +56,7 @@ export class RestComponent implements OnInit, OnDestroy { this._activatedRoute.queryParams .subscribe({ next: (params: Params) => { + console.log(params['start'], params['end']) this.params.env = params['env'] || application.default_env; this.params.start = params['start'] ? new Date(params['start']) : (application.session.api.default_period || makePeriod(0)).start; this.params.end = params['end'] ? new Date(params['end']) : (application.session.api.default_period || makePeriod(0, 1)).end; @@ -136,7 +138,7 @@ export class RestComponent implements OnInit, OnDestroy { this.dataSource.sort = this.sort; this.dataSource.sortingDataAccessor = (row: any, columnName: string) => { - if (columnName == "app_name") return row["application"]["name"] as string; + if (columnName == "app_name") return row["appName"] as string; if (columnName == "name/port") return row["host"] + ":" + row["port"] as string; if (columnName == "method/path") return row['path'] as string; if (columnName == "start") return row['start'] as string; diff --git a/src/app/views/statistic/_component/exception-table/exception-table.component.html b/src/app/views/statistic/_component/exception-table/exception-table.component.html index 4453d1b..feb6776 100644 --- a/src/app/views/statistic/_component/exception-table/exception-table.component.html +++ b/src/app/views/statistic/_component/exception-table/exception-table.component.html @@ -12,7 +12,7 @@
- + diff --git a/src/app/views/statistic/application/application.component.ts b/src/app/views/statistic/application/application.component.ts index 948b5ed..0400e39 100644 --- a/src/app/views/statistic/application/application.component.ts +++ b/src/app/views/statistic/application/application.component.ts @@ -140,7 +140,7 @@ export class ApplicationComponent implements OnInit, OnDestroy { repartitionRequestByPeriodLine: { observable: this._statsService.getRestSession({ 'column': "count:count,count_error_server:countErrorServer,count_slowest:countSlowest,rest_session.start.date:date", 'rest_session.instance_env': 'instance.id', 'instance.app_name': name, 'rest_session.start.ge': new Date(now.getFullYear(), now.getMonth(), now.getDate() - 6).toISOString(), 'rest_session.start.lt': now.toISOString(), 'instance.environement': env, 'order': 'rest_session.start.date.asc', ...advancedParams }) }, repartitionUserPolar: { observable: this._statsService.getRestSession({ 'column': "count:count,user:user", 'instance_env': 'instance.id', 'instance.app_name': name, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'instance.environement': env, 'user.not': 'null', 'order': 'count.desc', ...advancedParams }).pipe(map((r: any[]) => r.slice(0, 5))) }, repartitionUserBar: { - observable: this._statsService.getRestSession({ 'column': `count:count,start.${groupedBy}:date,start.year:year,user:user`, 'instance_env': 'instance.id', 'instance.app_name': name, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'instance.environement': env, 'user.not': 'null', 'order': `start.year.asc,start.${groupedBy}.asc`, ...advancedParams }).pipe(map((r: any[]) => { + observable: this._statsService.getRestSession({ 'column': `count:count,start.${groupedBy}:date,start.year:year,user:user`, 'instance_env': 'instance.id', 'instance.app_name': name, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'instance.environement': env, 'user.not': 'null', 'order': `start.year.asc,start.${groupedBy}.asc`, ...advancedParams }).pipe(map((r: {count: number, date: number, year: number, user: string}[]) => { let groupBy = groupingBy(r, 'user'); let results: { count: number, user: string, date: any, year: any }[] = Object.entries(groupBy).map((value: [string, any[]]) => { return { @@ -153,6 +153,7 @@ export class ApplicationComponent implements OnInit, OnDestroy { }).sort((a, b) => { return b.totalCount - a.totalCount }).slice(0, 5).flatMap(r => r.data); + return results; }), map((r: any[]) => { From 9042a7e3096f51b6707422d07506eff9f18cae42 Mon Sep 17 00:00:00 2001 From: fufuu Date: Mon, 5 Aug 2024 15:59:45 +0200 Subject: [PATCH 045/126] evols --- src/app/views/constants.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/views/constants.ts b/src/app/views/constants.ts index 258d607..6e83540 100644 --- a/src/app/views/constants.ts +++ b/src/app/views/constants.ts @@ -362,9 +362,9 @@ export class Constants { }; static readonly MAPPING_TYPE: {[key: string]: {title: string, icon: string}} = { - rest: {title: 'Liste des Appels REST', icon: 'swap_vert'}, + rest: {title: 'Appel d\'API', icon: 'call_received'}, batch: {title: 'Lancement de Batch', icon: 'manufacturing'}, - startup: {title: 'Liste des Serveurs', icon: 'restart_alt'}, + startup: {title: 'Lancement de Serveur', icon: 'restart_alt'}, view: {title: 'Navigation', icon: 'ads_click'} } } From 442380d69bfb31e0f5b12a275a9186e2c1d2b73b Mon Sep 17 00:00:00 2001 From: fufuu Date: Mon, 5 Aug 2024 16:07:52 +0200 Subject: [PATCH 046/126] hotfix --- src/app/views/search/main/main.component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/views/search/main/main.component.ts b/src/app/views/search/main/main.component.ts index 238da01..214d3dc 100644 --- a/src/app/views/search/main/main.component.ts +++ b/src/app/views/search/main/main.component.ts @@ -98,7 +98,7 @@ export class MainComponent implements OnInit, OnDestroy { if (columnName == "name") return row["name"] as string; if (columnName == "location") return row['location'] as string; if (columnName == "start") return row['start'] as string; - if (columnName == "Durée") return (row["end"] - row["start"]) + if (columnName == "durée") return (row["end"] - row["start"]) var columnValue = row[columnName as keyof any] as string; return columnValue; From d8992b31656f2a47e851420940aaff0732868eb5 Mon Sep 17 00:00:00 2001 From: fufuu Date: Tue, 6 Aug 2024 14:10:48 +0200 Subject: [PATCH 047/126] evols / anos --- src/app/app.component.html | 2 +- .../detail/session/main/main.component.html | 10 +- .../detail/session/rest/rest.component.html | 10 +- src/app/views/search/main/main.component.html | 210 ++++++++++-------- src/app/views/search/main/main.component.scss | 5 + src/app/views/search/main/main.component.ts | 35 ++- .../application/application.component.ts | 2 +- 7 files changed, 166 insertions(+), 108 deletions(-) diff --git a/src/app/app.component.html b/src/app/app.component.html index c542060..0d80a88 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -1,6 +1,6 @@
{{element.count}} {{element?.class || '[Class indisponible]'}}: {{element?.message || '[Message indisponible]'}} {{element.count}} {{element?.message || '[Message indisponible]'}} +{{addExceptionCount}} Autres...
+
+ + + search + - -
- - + + + + done + + + + + warning + + + + +
+
+
- -
- - - - + + + + - - - - + + + + + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + - -
Serveur - {{row.appName || ''}} - + + Nom -
- {{row.name || 'N/A'}} -
-
Serveur + {{ row.appName || '' }} + Nom +
+ {{ row.name || 'N/A' }} +
+
Chemin -
- {{row.location ||'N/A'}} -
-
Chemin +
+ {{ row.location || 'N/A' }} +
+
Début -
- {{ (row.start*1000 |date:'dd/MM/yyyy')}} -
-
-
- {{ (row.start*1000 |date:'HH:mm:ss.SSS')}} -
-
Début +
+ {{ (row.start * 1000 |date:'dd/MM/yyyy') }} +
+
+
+ {{ (row.start * 1000 |date:'HH:mm:ss.SSS') }} +
+
Durée -
- {{ getElapsedTime(row.end,row.start) | duration}}
-
-
Durée +
+ {{ getElapsedTime(row.end, row.start) | duration }}
+
+
Utilisateur {{row.user || 'N/A'}} Utilisateur {{ row.user || 'N/A' }}
-
- +
+
+ info - Aucun résultat -
-
+ Aucun résultat +
+
Chargement en cours... -
-
+
+ + + -
- +
+
\ No newline at end of file diff --git a/src/app/views/search/main/main.component.scss b/src/app/views/search/main/main.component.scss index 24f4611..70891ce 100644 --- a/src/app/views/search/main/main.component.scss +++ b/src/app/views/search/main/main.component.scss @@ -31,4 +31,9 @@ table overflow: auto; } +.searchwidth { + flex-grow: 1; +} + + diff --git a/src/app/views/search/main/main.component.ts b/src/app/views/search/main/main.component.ts index 214d3dc..b736803 100644 --- a/src/app/views/search/main/main.component.ts +++ b/src/app/views/search/main/main.component.ts @@ -11,7 +11,7 @@ import { TraceService } from 'src/app/service/trace.service'; import { application, makePeriod } from 'src/environments/environment'; import {Constants, FilterConstants, FilterMap, FilterPreset} from '../../constants'; import { FilterService } from 'src/app/service/filter.service'; -import { InstanceMainSession } from 'src/app/model/trace.model'; +import {InstanceMainSession, InstanceRestSession} from 'src/app/model/trace.model'; import {EnvRouter} from "../../../service/router.service"; @@ -35,7 +35,7 @@ export class MainComponent implements OnInit, OnDestroy { isLoading = false; advancedParams: Partial<{[key:string]:any}> focusFieldName: any - + filterTable = new Map(); filter: string = ''; params: Partial<{ env: string, start: Date, end: Date, type: string }> = {}; @@ -103,7 +103,24 @@ export class MainComponent implements OnInit, OnDestroy { var columnValue = row[columnName as keyof any] as string; return columnValue; } - this.dataSource.filter = this.filter; + this.dataSource.filterPredicate = (data: InstanceMainSession, filter: string) => { + var map: Map = new Map(JSON.parse(filter)); + let isMatch = true; + for (let [key, value] of map.entries()) { + if (key == 'filter') { + isMatch = isMatch && (value == '' || (data.appName?.toLowerCase().includes(value) || + data.name?.toLowerCase().includes(value) || data.location?.toLowerCase().includes(value) || + data.user?.toLowerCase().includes(value))); + } else if (key == 'status') { + const s = data.exception?.type || data.exception?.message ? "KO" : "OK"; + isMatch = isMatch && (!value.length || (value.some((status: any) => { + return s == status; + }))); + } + } + return isMatch; + } + this.dataSource.filter = JSON.stringify(Array.from(this.filterTable.entries())); this.dataSource.paginator.pageIndex = 0; this.isLoading = false; } @@ -161,13 +178,19 @@ export class MainComponent implements OnInit, OnDestroy { applyFilter(event: Event) { - this.filter = (event.target as HTMLInputElement).value.trim().toLowerCase(); - this.dataSource.filter = this.filter; - + const filterValue = (event.target as HTMLInputElement).value; + this.filterTable.set('filter', filterValue.trim().toLowerCase()); + this.dataSource.filter = JSON.stringify(Array.from(this.filterTable.entries())); if (this.dataSource.paginator) { this.dataSource.paginator.firstPage(); } } + + toggleFilter(filter: string[]) { + this.filterTable.set('status', filter); + this.dataSource.filter = JSON.stringify(Array.from(this.filterTable.entries())); + } + resetFilters(){ this.patchDateValue((application.session.api.default_period || makePeriod(0)).start,(application.session.api.default_period || makePeriod(0, 1)).end); this.advancedParams = {}; diff --git a/src/app/views/statistic/application/application.component.ts b/src/app/views/statistic/application/application.component.ts index 0400e39..76b3c69 100644 --- a/src/app/views/statistic/application/application.component.ts +++ b/src/app/views/statistic/application/application.component.ts @@ -163,7 +163,7 @@ export class ApplicationComponent implements OnInit, OnDestroy { }, repartitionApiBar: { observable: this._statsService.getRestSession({ 'column': "count_succes:countSucces,count_error_client:countErrorClient,count_error_server:countErrorServer,api_name", 'rest_session.instance_env': 'instance.id', 'instance.app_name': name, 'rest_session.start.ge': start.toISOString(), 'rest_session.start.lt': end.toISOString(), 'instance.environement': env, 'api_name.not': 'null', 'order': 'count.desc', ...advancedParams }).pipe(map((d: any) => d.slice(0, 5))) }, dependenciesTable: { observable: this._statsService.getRestSession({ 'column': "count:count,count_succes:countSucces,count_error_client:countErrClient,count_error_server:countErrServer,instance.app_name:name", 'instance_env': 'instance.id', 'id': 'rest_request.parent', 'rest_request.remote': 'rest_session_join.id', 'rest_session_join.instance_env': 'instance_join.id', 'instance_join.app_name': name, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'rest_session_join.start.ge': start.toISOString(), 'rest_session_join.start.lt': end.toISOString(), 'instance_join.environement': env, 'instance_join.app_name.not': 'null', 'order': 'count.desc', ...advancedParams }) }, - dependentsTable: { observable: this._statsService.getRestSession({ 'column': "count:count,count_succes:countSucces,count_error_client:countErrClient,count_error_server:countErrServer,instance_join.app_name:name", 'instance_env': 'instance.id', 'id': 'rest_request.parent', 'rest_request.remote': 'rest_session_join.id', 'rest_session_join.instance_env': 'instance_join.id', 'instance.app_name': name, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'rest_session_join.start.ge': start.toISOString(), 'rest_session_join.start.lt': end.toISOString(), 'instance.environement': env, 'instance.app_name.not': 'null', 'order': 'count.desc', ...advancedParams }) }, + dependentsTable: { observable: this._statsService.getRestSession({ 'column': "rest_session_join.count:count,rest_session_join.count_succes:countSucces,rest_session_join.count_error_client:countErrClient,rest_session_join.count_error_server:countErrServer,instance_join.app_name:name", 'instance_env': 'instance.id', 'id': 'rest_request.parent', 'rest_request.remote': 'rest_session_join.id', 'rest_session_join.instance_env': 'instance_join.id', 'instance.app_name': name, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'rest_session_join.start.ge': start.toISOString(), 'rest_session_join.start.lt': end.toISOString(), 'instance.environement': env, 'instance.app_name.not': 'null', 'order': 'count.desc', ...advancedParams }) }, exceptionsTable: { observable: this._statsService.getRestSession({ 'column': 'count,err_type,err_msg', 'err.group': '', 'rest_session.instance_env': 'instance.id', "status.ge": 500, "instance.environement": env, "instance.app_name": name, 'rest_session.start.ge': start.toISOString(), 'rest_session.start.lt': end.toISOString(), 'order': 'count.desc', ...advancedParams })} }; }; From 7b47c1f934113084d44ceae1f4397f764430bce0 Mon Sep 17 00:00:00 2001 From: fufuu Date: Tue, 6 Aug 2024 14:12:47 +0200 Subject: [PATCH 048/126] evols / anos --- src/app/views/statistic/rest/rest.component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/views/statistic/rest/rest.component.ts b/src/app/views/statistic/rest/rest.component.ts index 2a114da..1ddaf28 100644 --- a/src/app/views/statistic/rest/rest.component.ts +++ b/src/app/views/statistic/rest/rest.component.ts @@ -164,7 +164,7 @@ export class RestComponent implements OnInit, OnDestroy { })) }, dependenciesTable: { observable: this._statsService.getRestSession({ 'column': "count:count,count_succes:countSucces,count_error_client:countErrClient,count_error_server:countErrServer,api_name:name", 'instance_env': 'instance.id', "id": "rest_request.parent", "rest_request.remote": "rest_session_join.id", 'rest_session_join.api_name': name, 'rest_session_join.start.ge': start.toISOString(), 'rest_session_join.start.lt': end.toISOString(), 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'instance.environement': env, 'api_name.not': 'null', 'order': 'count.desc', ...advancedParams }) }, - dependentsTable: { observable: this._statsService.getRestSession({ 'column': "count:count,count_succes:countSucces,count_error_client:countErrClient,count_error_server:countErrServer,rest_session_join.api_name:name", 'instance_env': 'instance.id', "id": "rest_request.parent", "rest_request.remote": "rest_session_join.id", 'api_name': name, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'rest_session_join.start.ge': start.toISOString(), 'rest_session_join.start.lt': end.toISOString(), 'instance.environement': env, 'rest_session_join.api_name.not': 'null', 'order': 'count.desc', ...advancedParams }) }, + dependentsTable: { observable: this._statsService.getRestSession({ 'column': "rest_session_join.count:count,rest_session_join.count_succes:countSucces,rest_session_join.count_error_client:countErrClient,rest_session_join.count_error_server:countErrServer,rest_session_join.api_name:name", 'instance_env': 'instance.id', "id": "rest_request.parent", "rest_request.remote": "rest_session_join.id", 'api_name': name, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'rest_session_join.start.ge': start.toISOString(), 'rest_session_join.start.lt': end.toISOString(), 'instance.environement': env, 'rest_session_join.api_name.not': 'null', 'order': 'count.desc', ...advancedParams }) }, exceptionsTable: { observable: this._statsService.getRestSession({ 'column': 'count,err_type,err_msg', 'instance_env': 'instance.id', 'err.group': '', "status.ge": 500, "instance.environement": env, "api_name": name, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'order': 'count.desc', ...advancedParams })} }; } From e297acbbc5192b0cc603fadc6282d1927887f5e5 Mon Sep 17 00:00:00 2001 From: fufuu Date: Tue, 6 Aug 2024 15:25:17 +0200 Subject: [PATCH 049/126] evols / anos --- .../database-table.component.html | 2 +- .../database-table.component.ts | 4 +- .../ftp-table/ftp-table.component.html | 99 +++++++++++++++++++ .../ftp-table/ftp-table.component.scss | 11 +++ .../ftp-table/ftp-table.component.ts | 86 ++++++++++++++++ .../rest-table/rest-table.component.ts | 2 +- .../_component/timeline/timeline.component.ts | 2 +- .../detail/session/main/main.component.html | 10 +- .../detail/session/rest/rest.component.html | 10 +- .../exception-table.component.html | 2 +- .../exception-table.component.ts | 5 +- .../views/statistic/rest/rest.component.ts | 4 +- 12 files changed, 217 insertions(+), 20 deletions(-) create mode 100644 src/app/views/detail/session/_component/ftp-table/ftp-table.component.html create mode 100644 src/app/views/detail/session/_component/ftp-table/ftp-table.component.scss create mode 100644 src/app/views/detail/session/_component/ftp-table/ftp-table.component.ts diff --git a/src/app/views/detail/session/_component/database-table/database-table.component.html b/src/app/views/detail/session/_component/database-table/database-table.component.html index 034fba2..7abd92f 100644 --- a/src/app/views/detail/session/_component/database-table/database-table.component.html +++ b/src/app/views/detail/session/_component/database-table/database-table.component.html @@ -18,7 +18,7 @@ BDD - {{getCommand(element.commands)}} + {{getCommand(element.commands)}}
{{element["name"] || 'N/A'}} diff --git a/src/app/views/detail/session/_component/database-table/database-table.component.ts b/src/app/views/detail/session/_component/database-table/database-table.component.ts index 327d2f0..6ce96de 100644 --- a/src/app/views/detail/session/_component/database-table/database-table.component.ts +++ b/src/app/views/detail/session/_component/database-table/database-table.component.ts @@ -6,7 +6,7 @@ import { DatabaseRequest } from "src/app/model/trace.model"; import { Utils } from "src/app/shared/util"; @Component({ - selector: 'request-database-table', + selector: 'database-table', templateUrl: './database-table.component.html', styleUrls: ['./database-table.component.scss'] }) @@ -35,7 +35,7 @@ export class DatabaseTableComponent implements OnInit { } getCommand(commands: string[]): string { - let command = "" + let command = "[--]"; if (commands?.length == 1) { command = `[${commands[0]}]` } else if (commands?.length > 1) { diff --git a/src/app/views/detail/session/_component/ftp-table/ftp-table.component.html b/src/app/views/detail/session/_component/ftp-table/ftp-table.component.html new file mode 100644 index 0000000..d7278d2 --- /dev/null +++ b/src/app/views/detail/session/_component/ftp-table/ftp-table.component.html @@ -0,0 +1,99 @@ +
+ + + search + + + + + + done + + + + + error + + + + + warning + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + Hôte + {{element['host']}}:{{element['port']}} + API + [{{element.method}}] +
+ {{element['path']}} +
Début +
+ {{ (element.start*1000 |date:'dd/MM/yyyy')}} +
+
+
+ {{ (element.start*1000 |date:'HH:mm:ss.SSS')}} +
+
Durée + + {{getElapsedTime(element.end,element.start)| number :'1.2-3' }}s + +
+
+ + info + + Aucun résultat +
+
+ +
\ No newline at end of file diff --git a/src/app/views/detail/session/_component/ftp-table/ftp-table.component.scss b/src/app/views/detail/session/_component/ftp-table/ftp-table.component.scss new file mode 100644 index 0000000..780ed25 --- /dev/null +++ b/src/app/views/detail/session/_component/ftp-table/ftp-table.component.scss @@ -0,0 +1,11 @@ +.searchwidth { + flex-grow: 1; +} + +.mat-mdc-row .mat-mdc-cell { + cursor: pointer; +} + +.mat-mdc-row:hover .mat-mdc-cell { + background-color: rgb(206, 206, 206); +} \ No newline at end of file diff --git a/src/app/views/detail/session/_component/ftp-table/ftp-table.component.ts b/src/app/views/detail/session/_component/ftp-table/ftp-table.component.ts new file mode 100644 index 0000000..94d2886 --- /dev/null +++ b/src/app/views/detail/session/_component/ftp-table/ftp-table.component.ts @@ -0,0 +1,86 @@ +import { Component, EventEmitter, Input, OnInit, Output, ViewChild, inject } from "@angular/core"; +import { MatPaginator } from "@angular/material/paginator"; +import { MatSort } from "@angular/material/sort"; +import { MatTableDataSource } from "@angular/material/table"; +import { RestRequest } from "src/app/model/trace.model"; +import { Utils } from "src/app/shared/util"; + +@Component({ + selector: 'ftp-table', + templateUrl: './ftp-table.component.html', + styleUrls: ['./ftp-table.component.scss'] +}) +export class FtpTableComponent implements OnInit { + displayedColumns: string[] = ['status', 'host', 'path', 'start', 'duree']; + dataSource: MatTableDataSource = new MatTableDataSource(); + filterTable = new Map(); + + @ViewChild('paginator', {static: true}) paginator: MatPaginator; + @ViewChild('sort', {static: true}) sort: MatSort; + + @Input() set requests(requests: RestRequest[]) { + if(requests) { + this.dataSource = new MatTableDataSource(requests); + this.dataSource.paginator = this.paginator; + this.dataSource.sort = this.sort; + } + } + @Output() onClickRow: EventEmitter<{event: MouseEvent, row: any}> = new EventEmitter(); + + ngOnInit() { + this.dataSource.sortingDataAccessor = sortingDataAccessor; + this.dataSource.filterPredicate = filterPredicate; + } + + applyFilter(event: Event) { + const filterValue = (event.target as HTMLInputElement).value; + this.filterTable.set('filter', filterValue.trim().toLowerCase()); + this.dataSource.filter = JSON.stringify(Array.from(this.filterTable.entries())); + if (this.dataSource.paginator) { + this.dataSource.paginator.firstPage(); + } + } + + toggleFilter(filter: string[]) { + this.filterTable.set('status', filter); + this.dataSource.filter = JSON.stringify(Array.from(this.filterTable.entries())); + } + + selectedRequest(event: MouseEvent, row: any) { + console.log(row) + this.onClickRow.emit({event: event, row: row}); + } + + getElapsedTime(end: number, start: number,) { + return end - start; + } + + statusBorder(status: any) { + return Utils.statusBorder(status); + } +} + +const sortingDataAccessor = (row: any, columnName: string) => { + if (columnName == "host") return row["host"] + ":" + row["port"] as string; + if (columnName == "start") return row['start'] as string; + if (columnName == "duree") return (row["end"] - row["start"]); + return row[columnName as keyof any] as string; +} + +const filterPredicate = (data: RestRequest, filter: string) => { + var map: Map = new Map(JSON.parse(filter)); + let isMatch = true; + for (let [key, value] of map.entries()) { + if (key == 'filter') { + isMatch = isMatch && (value == '' || + (data.host?.toLowerCase().includes(value) || data.method?.toLowerCase().includes(value) || data.query?.toLowerCase().includes(value) || + data.path?.toLowerCase().includes(value))); + } else if (key == 'status') { + const s = data.status.toString(); + isMatch = isMatch && (!value.length || (value.some((status: any) => { + return s.startsWith(status[0]); + }))); + } + } + return isMatch; +} diff --git a/src/app/views/detail/session/_component/rest-table/rest-table.component.ts b/src/app/views/detail/session/_component/rest-table/rest-table.component.ts index b503c44..e4c20f2 100644 --- a/src/app/views/detail/session/_component/rest-table/rest-table.component.ts +++ b/src/app/views/detail/session/_component/rest-table/rest-table.component.ts @@ -6,7 +6,7 @@ import { RestRequest } from "src/app/model/trace.model"; import { Utils } from "src/app/shared/util"; @Component({ - selector: 'request-rest-table', + selector: 'rest-table', templateUrl: './rest-table.component.html', styleUrls: ['./rest-table.component.scss'] }) diff --git a/src/app/views/detail/session/_component/timeline/timeline.component.ts b/src/app/views/detail/session/_component/timeline/timeline.component.ts index f83619d..a6617ad 100644 --- a/src/app/views/detail/session/_component/timeline/timeline.component.ts +++ b/src/app/views/detail/session/_component/timeline/timeline.component.ts @@ -5,7 +5,7 @@ import { DatabaseRequest, InstanceEnvironment, InstanceMainSession, InstanceRest import {EnvRouter} from "../../../../../service/router.service"; @Component({ - selector: 'request-timeline-table', + selector: 'timeline-table', templateUrl: './timeline.component.html', styleUrls: ['./timeline.component.scss'] }) diff --git a/src/app/views/detail/session/main/main.component.html b/src/app/views/detail/session/main/main.component.html index b1d128c..ea40dff 100644 --- a/src/app/views/detail/session/main/main.component.html +++ b/src/app/views/detail/session/main/main.component.html @@ -92,8 +92,8 @@
- +
@@ -105,8 +105,8 @@
- +
@@ -117,7 +117,7 @@
- +
diff --git a/src/app/views/detail/session/rest/rest.component.html b/src/app/views/detail/session/rest/rest.component.html index d7f9174..b083fb4 100644 --- a/src/app/views/detail/session/rest/rest.component.html +++ b/src/app/views/detail/session/rest/rest.component.html @@ -107,8 +107,8 @@ - +
@@ -119,9 +119,9 @@
- - +
@@ -132,7 +132,7 @@
- + diff --git a/src/app/views/statistic/_component/exception-table/exception-table.component.html b/src/app/views/statistic/_component/exception-table/exception-table.component.html index feb6776..779ad51 100644 --- a/src/app/views/statistic/_component/exception-table/exception-table.component.html +++ b/src/app/views/statistic/_component/exception-table/exception-table.component.html @@ -12,7 +12,7 @@
- + diff --git a/src/app/views/statistic/_component/exception-table/exception-table.component.ts b/src/app/views/statistic/_component/exception-table/exception-table.component.ts index 50cb284..b469c31 100644 --- a/src/app/views/statistic/_component/exception-table/exception-table.component.ts +++ b/src/app/views/statistic/_component/exception-table/exception-table.component.ts @@ -15,8 +15,9 @@ export class ExceptionTableComponent { @Input() set data(objects: any) { if (objects?.length) { //.pipe(map((d: any) => d.slice(0, 5))) - this.dataSource = new MatTableDataSource(objects.slice(0, 5).map((r: any) => { - return { count: r['COUNT'], message: r?.errorMessage, class: r?.errorType }; + this.dataSource = new MatTableDataSource(objects.slice(0, 5).map((r: {COUNT: number, errorMessage: string, errorType: string}) => { + const index = r?.errorType.lastIndexOf('.') + 1; + return { count: r.COUNT, message: r?.errorMessage, class: r?.errorType?.substring(index) }; })); if (objects.length > 5) { this.addExceptionCount = objects.reduce((acc: number, curr: any, i: number) => { diff --git a/src/app/views/statistic/rest/rest.component.ts b/src/app/views/statistic/rest/rest.component.ts index 1ddaf28..2e492a0 100644 --- a/src/app/views/statistic/rest/rest.component.ts +++ b/src/app/views/statistic/rest/rest.component.ts @@ -141,9 +141,9 @@ export class RestComponent implements OnInit, OnDestroy { })) }, repartitionRequestByPeriodLine: { observable: this._statsService.getRestSession({ 'column': `count:count,count_error_server:countErrorServer,count_slowest:countSlowest,rest_session.start.date:date`, 'rest_session.instance_env': 'instance.id', 'api_name': name, 'rest_session.start.ge': new Date(now.getFullYear(), now.getMonth(), now.getDate() - 6).toISOString(), 'rest_session.start.lt': now.toISOString(), 'instance.environement': env, 'order': 'rest_session.start.date.asc', ...advancedParams }) }, // 7 derniers jours - repartitionUserPolar: { observable: this._statsService.getRestSession({ 'column': "count:count,instance.user:user", 'rest_session.instance_env': 'instance.id', 'api_name': name, 'rest_session.start.ge': start.toISOString(), 'rest_session.start.lt': end.toISOString(), 'instance.environement': env, 'instance.user.not': 'null', 'order': 'count.desc', ...advancedParams }).pipe(map((r: any[]) => r.slice(0, 5))) }, + repartitionUserPolar: { observable: this._statsService.getRestSession({ 'column': "count:count,user:user", 'rest_session.instance_env': 'instance.id', 'api_name': name, 'rest_session.start.ge': start.toISOString(), 'rest_session.start.lt': end.toISOString(), 'instance.environement': env, 'user.not': 'null', 'order': 'count.desc', ...advancedParams }).pipe(map((r: any[]) => r.slice(0, 5))) }, repartitionUserBar: { - observable: this._statsService.getRestSession({ 'column': `count:count,rest_session.start.${groupedBy}:date,rest_session.start.year:year,instance.user:user`, 'rest_session.instance_env': 'instance.id', 'api_name': name, 'rest_session.start.ge': start.toISOString(), 'rest_session.start.lt': end.toISOString(), 'instance.environement': env, 'instance.user.not': 'null', 'order': `rest_session.start.year.asc,rest_session.start.${groupedBy}.asc`, ...advancedParams }).pipe(map((r: any[]) => { + observable: this._statsService.getRestSession({ 'column': `count:count,start.${groupedBy}:date,start.year:year,user:user`, 'instance_env': 'instance.id', 'api_name': name, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'instance.environement': env, 'user.not': 'null', 'order': `start.year.asc,start.${groupedBy}.asc`, ...advancedParams }).pipe(map((r: any[]) => { let groupBy = groupingBy(r, 'user'); let results: { count: number, user: string, date: any, year: any }[] = Object.entries(groupBy).map((value: [string, any[]]) => { return { From 8276cfa1a638035485b7dd5aed55b2b42b6c0469 Mon Sep 17 00:00:00 2001 From: fufuu Date: Tue, 6 Aug 2024 15:27:13 +0200 Subject: [PATCH 050/126] modules --- src/app/views/views.module.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/app/views/views.module.ts b/src/app/views/views.module.ts index 612137e..0cf5160 100644 --- a/src/app/views/views.module.ts +++ b/src/app/views/views.module.ts @@ -24,6 +24,7 @@ import {RestTableComponent} from './detail/session/_component/rest-table/rest-ta import {DatabaseTableComponent} from './detail/session/_component/database-table/database-table.component'; import {TimelineComponent} from './detail/session/_component/timeline/timeline.component'; import {DashboardComponent} from './dashboard/dashboard.component'; +import {FtpTableComponent} from "./detail/session/_component/ftp-table/ftp-table.component"; @NgModule({ imports: [ @@ -46,6 +47,7 @@ import {DashboardComponent} from './dashboard/dashboard.component'; DetailDatabaseComponent, RestTableComponent, DatabaseTableComponent, + FtpTableComponent, TimelineComponent, ApplicationComponent, UserComponent, From 9a1cef42d8cc4780cc673e88a8f81b38cdf6c92f Mon Sep 17 00:00:00 2001 From: fufuu Date: Tue, 6 Aug 2024 15:36:18 +0200 Subject: [PATCH 051/126] evols detail --- src/app/views/detail/session/rest/rest.component.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/views/detail/session/rest/rest.component.html b/src/app/views/detail/session/rest/rest.component.html index b083fb4..304c85d 100644 --- a/src/app/views/detail/session/rest/rest.component.html +++ b/src/app/views/detail/session/rest/rest.component.html @@ -102,8 +102,8 @@
- west -
REST
+ call_made +
API
From 6b6e87e7df5a143e612334250d2788e1e2535df6 Mon Sep 17 00:00:00 2001 From: fufuu Date: Tue, 6 Aug 2024 16:39:48 +0200 Subject: [PATCH 052/126] evols / anos --- .../ftp-table/ftp-table.component.html | 26 ------------------- .../ftp-table/ftp-table.component.ts | 25 +++--------------- .../rest-table/rest-table.component.html | 2 +- .../detail/session/rest/rest.component.html | 3 +++ .../detail/session/rest/rest.component.ts | 4 ++- 5 files changed, 10 insertions(+), 50 deletions(-) diff --git a/src/app/views/detail/session/_component/ftp-table/ftp-table.component.html b/src/app/views/detail/session/_component/ftp-table/ftp-table.component.html index d7278d2..7f25fee 100644 --- a/src/app/views/detail/session/_component/ftp-table/ftp-table.component.html +++ b/src/app/views/detail/session/_component/ftp-table/ftp-table.component.html @@ -1,29 +1,3 @@ -
- - - search - - - - - - done - - - - - error - - - - - warning - - - -
{{element.count}} {{element?.message || '[Message indisponible]'}} {{element.count}} [{{element?.class}}] {{element?.message || '[Message indisponible]'}} +{{addExceptionCount}} Autres...
diff --git a/src/app/views/detail/session/_component/ftp-table/ftp-table.component.ts b/src/app/views/detail/session/_component/ftp-table/ftp-table.component.ts index 94d2886..33a3e59 100644 --- a/src/app/views/detail/session/_component/ftp-table/ftp-table.component.ts +++ b/src/app/views/detail/session/_component/ftp-table/ftp-table.component.ts @@ -2,7 +2,7 @@ import { Component, EventEmitter, Input, OnInit, Output, ViewChild, inject } fro import { MatPaginator } from "@angular/material/paginator"; import { MatSort } from "@angular/material/sort"; import { MatTableDataSource } from "@angular/material/table"; -import { RestRequest } from "src/app/model/trace.model"; +import {FtpRequest, RestRequest} from "src/app/model/trace.model"; import { Utils } from "src/app/shared/util"; @Component({ @@ -12,13 +12,13 @@ import { Utils } from "src/app/shared/util"; }) export class FtpTableComponent implements OnInit { displayedColumns: string[] = ['status', 'host', 'path', 'start', 'duree']; - dataSource: MatTableDataSource = new MatTableDataSource(); + dataSource: MatTableDataSource = new MatTableDataSource(); filterTable = new Map(); @ViewChild('paginator', {static: true}) paginator: MatPaginator; @ViewChild('sort', {static: true}) sort: MatSort; - @Input() set requests(requests: RestRequest[]) { + @Input() set requests(requests: FtpRequest[]) { if(requests) { this.dataSource = new MatTableDataSource(requests); this.dataSource.paginator = this.paginator; @@ -29,7 +29,6 @@ export class FtpTableComponent implements OnInit { ngOnInit() { this.dataSource.sortingDataAccessor = sortingDataAccessor; - this.dataSource.filterPredicate = filterPredicate; } applyFilter(event: Event) { @@ -66,21 +65,3 @@ const sortingDataAccessor = (row: any, columnName: string) => { if (columnName == "duree") return (row["end"] - row["start"]); return row[columnName as keyof any] as string; } - -const filterPredicate = (data: RestRequest, filter: string) => { - var map: Map = new Map(JSON.parse(filter)); - let isMatch = true; - for (let [key, value] of map.entries()) { - if (key == 'filter') { - isMatch = isMatch && (value == '' || - (data.host?.toLowerCase().includes(value) || data.method?.toLowerCase().includes(value) || data.query?.toLowerCase().includes(value) || - data.path?.toLowerCase().includes(value))); - } else if (key == 'status') { - const s = data.status.toString(); - isMatch = isMatch && (!value.length || (value.some((status: any) => { - return s.startsWith(status[0]); - }))); - } - } - return isMatch; -} diff --git a/src/app/views/detail/session/_component/rest-table/rest-table.component.html b/src/app/views/detail/session/_component/rest-table/rest-table.component.html index d7278d2..20dfe96 100644 --- a/src/app/views/detail/session/_component/rest-table/rest-table.component.html +++ b/src/app/views/detail/session/_component/rest-table/rest-table.component.html @@ -48,7 +48,7 @@ diff --git a/src/app/views/detail/session/rest/rest.component.html b/src/app/views/detail/session/rest/rest.component.html index 304c85d..4aa6782 100644 --- a/src/app/views/detail/session/rest/rest.component.html +++ b/src/app/views/detail/session/rest/rest.component.html @@ -66,6 +66,9 @@
{{instance.name}} {{instance.version}}
+
+ +
diff --git a/src/app/views/detail/session/rest/rest.component.ts b/src/app/views/detail/session/rest/rest.component.ts index a6e0670..f421698 100644 --- a/src/app/views/detail/session/rest/rest.component.ts +++ b/src/app/views/detail/session/rest/rest.component.ts @@ -51,7 +51,8 @@ export class RestComponent implements OnInit, OnDestroy { parent: this._traceService.getSessionParent(id).pipe(catchError(() => of(null))), requests: this._traceService.getRestRequests(s.id), queries: this._traceService.getDatabaseRequests(s.id), - stages: this._traceService.getLocalRequests(s.id) + stages: this._traceService.getLocalRequests(s.id), + ftps: this._traceService.getFtpRequests(s.id) }); }), finalize(() => this.isLoading = false) @@ -62,6 +63,7 @@ export class RestComponent implements OnInit, OnDestroy { this.session.requests = result.requests; this.session.queries = result.queries; this.session.stages = result.stages; + this.session.ftpRequests = result.ftps; this.instance = result.instance; this.sessionParent = result.parent; this.groupQueriesBySchema(); From 995621788d650264c7c8b17232878d09599555a2 Mon Sep 17 00:00:00 2001 From: fufuu Date: Tue, 13 Aug 2024 17:32:44 +0200 Subject: [PATCH 053/126] nouvelles features --- src/app/app.module.ts | 43 +- src/app/model/trace.model.ts | 11 +- src/app/service/trace.service.ts | 18 +- .../advanced-filter-modal.component.ts | 6 - src/app/shared/pipe/duration.pipe.ts | 12 +- src/app/shared/util.ts | 4 + .../detail/database/database.component.html | 58 +-- .../detail/database/database.component.scss | 7 + .../detail/database/database.component.ts | 227 +++------ src/app/views/detail/ftp/ftp.component.html | 47 ++ src/app/views/detail/ftp/ftp.component.scss | 87 ++++ src/app/views/detail/ftp/ftp.component.ts | 111 +++++ src/app/views/detail/ldap/ldap.component.html | 51 ++ src/app/views/detail/ldap/ldap.component.scss | 87 ++++ src/app/views/detail/ldap/ldap.component.ts | 116 +++++ .../database-table.component.html | 2 +- .../database-table.component.ts | 11 +- .../_component/detail-session.component.html | 0 .../_component/detail-session.component.scss | 0 .../_component/detail-session.component.ts | 0 .../ftp-table/ftp-table.component.html | 15 +- .../ftp-table/ftp-table.component.ts | 32 +- .../ldap-table/ldap-table.component.html | 62 +++ .../ldap-table/ldap-table.component.scss | 11 + .../ldap-table/ldap-table.component.ts | 48 ++ .../rest-table/rest-table.component.html | 2 +- .../rest-table/rest-table.component.ts | 15 +- .../smtp-table/smtp-table.component.html | 62 +++ .../smtp-table/smtp-table.component.scss | 11 + .../smtp-table/smtp-table.component.ts | 47 ++ .../_component/timeline/timeline.component.ts | 43 +- .../detail/session/main/main.component.html | 82 +++- .../detail/session/main/main.component.ts | 53 ++- .../detail/session/rest/rest.component.html | 76 ++- .../detail/session/rest/rest.component.ts | 43 +- src/app/views/detail/smtp/smtp.component.html | 113 +++++ src/app/views/detail/smtp/smtp.component.scss | 75 +++ src/app/views/detail/smtp/smtp.component.ts | 121 +++++ src/app/views/search/main/main.component.html | 6 +- src/app/views/search/main/main.component.ts | 447 +++++++++--------- src/app/views/search/rest/rest.component.html | 2 +- src/app/views/search/rest/rest.component.ts | 37 +- src/app/views/views.module.ts | 10 + src/styles.scss | 4 +- 44 files changed, 1709 insertions(+), 606 deletions(-) create mode 100644 src/app/views/detail/ftp/ftp.component.html create mode 100644 src/app/views/detail/ftp/ftp.component.scss create mode 100644 src/app/views/detail/ftp/ftp.component.ts create mode 100644 src/app/views/detail/ldap/ldap.component.html create mode 100644 src/app/views/detail/ldap/ldap.component.scss create mode 100644 src/app/views/detail/ldap/ldap.component.ts create mode 100644 src/app/views/detail/session/_component/detail-session.component.html create mode 100644 src/app/views/detail/session/_component/detail-session.component.scss create mode 100644 src/app/views/detail/session/_component/detail-session.component.ts create mode 100644 src/app/views/detail/session/_component/ldap-table/ldap-table.component.html create mode 100644 src/app/views/detail/session/_component/ldap-table/ldap-table.component.scss create mode 100644 src/app/views/detail/session/_component/ldap-table/ldap-table.component.ts create mode 100644 src/app/views/detail/session/_component/smtp-table/smtp-table.component.html create mode 100644 src/app/views/detail/session/_component/smtp-table/smtp-table.component.scss create mode 100644 src/app/views/detail/session/_component/smtp-table/smtp-table.component.ts create mode 100644 src/app/views/detail/smtp/smtp.component.html create mode 100644 src/app/views/detail/smtp/smtp.component.scss create mode 100644 src/app/views/detail/smtp/smtp.component.ts diff --git a/src/app/app.module.ts b/src/app/app.module.ts index e8adf77..79c24f9 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -25,6 +25,9 @@ import {RestComponent as DetailSessionRestComponent} from "./views/detail/sessio import {MainComponent as SearchMainComponent} from './views/search/main/main.component'; import {MainComponent as DetailSessionMainComponent} from "./views/detail/session/main/main.component"; import {EnvRouter} from "./service/router.service"; +import {FtpComponent as DetailFtpComponent} from "./views/detail/ftp/ftp.component"; +import {LdapComponent as DetailLdapComponent} from "./views/detail/ldap/ldap.component"; +import {SmtpComponent as DetailSmtpComponent} from "./views/detail/smtp/smtp.component"; registerLocaleData(localeFr, 'fr-FR'); const routes: Route[] = [ @@ -47,11 +50,29 @@ const routes: Route[] = [ title: 'Detail Appel REST' }, { - path: 'database/:id_database', + path: 'database/:id_jdbc', data: { type: 'rest' }, component: DetailDatabaseComponent, title: 'Detail Base de donnée' }, + { + path: 'ftp/:id_ftp', + data: { type: 'rest' }, + component: DetailFtpComponent, + title: 'Detail Ftp' + }, + { + path: 'ldap/:id_ldap', + data: { type: 'rest' }, + component: DetailLdapComponent, + title: 'Detail Ldap' + }, + { + path: 'smtp/:id_smtp', + data: { type: 'rest' }, + component: DetailSmtpComponent, + title: 'Detail Smtp' + }, { path: 'tree', data: { type: 'rest' }, @@ -95,11 +116,29 @@ const routes: Route[] = [ }, }, { - path: 'database/:id_database', + path: 'database/:id_jdbc', component: DetailDatabaseComponent, data: { type: 'main' }, title: 'Detail Base de donnée' }, + { + path: 'ftp/:id_ftp', + data: { type: 'main' }, + component: DetailFtpComponent, + title: 'Detail Ftp' + }, + { + path: 'ldap/:id_ldap', + data: { type: 'main' }, + component: DetailLdapComponent, + title: 'Detail Ldap' + }, + { + path: 'ldap/:id_smtp', + data: { type: 'main' }, + component: DetailSmtpComponent, + title: 'Detail Smtp' + }, { path: 'tree', data: { type: 'main' }, diff --git a/src/app/model/trace.model.ts b/src/app/model/trace.model.ts index f830ebb..be93ab3 100644 --- a/src/app/model/trace.model.ts +++ b/src/app/model/trace.model.ts @@ -102,14 +102,16 @@ export interface DatabaseRequestStage extends RequestStage { export interface FtpRequestStage extends RequestStage { args: Array; + order?: number; } export interface MailRequestStage extends RequestStage { - + order?: number; } export interface NamingRequestStage extends RequestStage { args: Array; + order?: number; } export interface Mail { @@ -133,6 +135,8 @@ export interface SessionStage { start: number; end: number; threadName: string; + + duration: number; } export interface ExceptionInfo { @@ -151,4 +155,9 @@ export interface InstanceEnvironment { type: string; instant: number; collector: string; +} + +export interface Period { + start: number; + end: number; } \ No newline at end of file diff --git a/src/app/service/trace.service.ts b/src/app/service/trace.service.ts index 5101a53..8e59958 100644 --- a/src/app/service/trace.service.ts +++ b/src/app/service/trace.service.ts @@ -4,11 +4,11 @@ import { Observable, catchError, throwError } from "rxjs"; import { DatabaseRequest, DatabaseRequestStage, - FtpRequest, + FtpRequest, FtpRequestStage, InstanceEnvironment, InstanceMainSession, InstanceRestSession, - LocalRequest, MailRequest, MailRequestStage, NamingRequest, NamingRequestStage, + LocalRequest, Mail, MailRequest, MailRequestStage, NamingRequest, NamingRequestStage, RestRequest, RestSession } from "../model/trace.model"; @@ -70,8 +70,8 @@ export class TraceService { return this.http.get(`${this.server}/session/${idSession}/request/ftp`); } - getFtpRequestStages(idSession: string, idFtp: number): Observable> { - return this.http.get>(`${this.server}/session/${idSession}/request/ftp/${idFtp}/stage`); + getFtpRequestStages(idSession: string, idFtp: number): Observable> { + return this.http.get>(`${this.server}/session/${idSession}/request/ftp/${idFtp}/stage`); }; getSmtpRequests(idSession: string): Observable>; @@ -86,16 +86,20 @@ export class TraceService { return this.http.get>(`${this.server}/session/${idSession}/request/smtp/${idSmtp}/stage`); }; + getSmtpRequestMails(idSession: string, idSmtp: number): Observable> { + return this.http.get>(`${this.server}/session/${idSession}/request/smtp/${idSmtp}/mail`); + }; + getLdapRequests(idSession: string): Observable>; getLdapRequests(idSession: string, idLdap: number): Observable; getLdapRequests(idSession: string, idLdap?: number): Observable { if(idLdap) - return this.http.get(`${this.server}/session/${idSession}/request/smtp/${idLdap}`); - return this.http.get(`${this.server}/session/${idSession}/request/smtp`); + return this.http.get(`${this.server}/session/${idSession}/request/ldap/${idLdap}`); + return this.http.get(`${this.server}/session/${idSession}/request/ldap`); } getLdapRequestStages(idSession: string, idLdap: number): Observable> { - return this.http.get>(`${this.server}/session/${idSession}/request/smtp/${idLdap}/stage`); + return this.http.get>(`${this.server}/session/${idSession}/request/ldap/${idLdap}/stage`); }; getLocalRequests(id: string): Observable> { diff --git a/src/app/shared/_component/advanced-filter/advanced-filter-modal/advanced-filter-modal.component.ts b/src/app/shared/_component/advanced-filter/advanced-filter-modal/advanced-filter-modal.component.ts index a1443a3..c3a58f3 100644 --- a/src/app/shared/_component/advanced-filter/advanced-filter-modal/advanced-filter-modal.component.ts +++ b/src/app/shared/_component/advanced-filter/advanced-filter-modal/advanced-filter-modal.component.ts @@ -166,10 +166,4 @@ export class AdvancedFilterComponent implements OnInit, AfterContentChecked, OnD return true; return false; } - - - - - - } \ No newline at end of file diff --git a/src/app/shared/pipe/duration.pipe.ts b/src/app/shared/pipe/duration.pipe.ts index 7cbdca1..386d403 100644 --- a/src/app/shared/pipe/duration.pipe.ts +++ b/src/app/shared/pipe/duration.pipe.ts @@ -1,5 +1,6 @@ import {inject, Pipe, PipeTransform} from "@angular/core"; import {DecimalPipe} from "@angular/common"; +import {Period} from "../../model/trace.model"; @Pipe({ name:"duration" @@ -8,12 +9,13 @@ import {DecimalPipe} from "@angular/common"; export class DurationPipe implements PipeTransform { _decimalPipe = inject(DecimalPipe); - transform(value: any, ...args: any[]):string { - if(!value && value !== 0) return ''; + transform(value: Period | number, ...args: any[]):string { + if(value == null) return; + let time = typeof value == "object" ? value.end - value.start : value; - const remainingSeconds = this._decimalPipe.transform(Math.round((value % 60) * 1000) / 1000); - const minutes = Math.floor((value % 3600) / 60); - const hours = Math.floor(value/3600); + const remainingSeconds = this._decimalPipe.transform(Math.round((time % 60) * 1000) / 1000); + const minutes = Math.floor((time % 3600) / 60); + const hours = Math.floor(time/3600); const hourString = hours > 0 ? `${hours}h` : '' const minuteString = minutes > 0 ? `${minutes}min` : '' diff --git a/src/app/shared/util.ts b/src/app/shared/util.ts index e289df2..a07a9cc 100644 --- a/src/app/shared/util.ts +++ b/src/app/shared/util.ts @@ -207,4 +207,8 @@ export function extractInfo(filterKey: string) { } } return null; +} + +export function getElapsedTime(end: number, start: number) { + return end - start; } \ No newline at end of file diff --git a/src/app/views/detail/database/database.component.html b/src/app/views/detail/database/database.component.html index 0ef017b..e2d79bc 100644 --- a/src/app/views/detail/database/database.component.html +++ b/src/app/views/detail/database/database.component.html @@ -1,10 +1,10 @@ -
- +
+

- settings_suggest - {{ selectedQuery?.name || 'N/A' }} + Database + {{ request.host }}{{ ':'+ request.port }} -- {{ request.name}}

@@ -18,9 +18,9 @@
- warning{{getException(selectedQuery?.actions)?.exception?.message}} + *ngIf="exception" + [matTooltip]="exception.type" TooltipPosition="below"> + warning{{exception.message}}
@@ -28,42 +28,16 @@ person
- {{selectedQuery?.user || "N/A"}} le {{( selectedQuery?.start*1000 ) | date: 'dd/MM/yyyy à HH:mm:ss.SSS': 'fr' }} + {{request.user || "N/A"}} le {{( request.start*1000 ) | date: 'dd/MM/yyyy à HH:mm:ss.SSS': 'fr' }} en {{ { start: request.start, end: request.end } | duration }}
- en {{ getElapsedTime(selectedQuery?.end, selectedQuery?.start) | number :'1.2-3'}}s + {{ request.productName }} v.{{ request.productVersion }}
- {{getSessionStatusTooltip(selectedQuery)}} -
- - - - - Database - {{selectedQuery?.name}} - -
- -
-
- - - -
- {{selectedQuery?.host}} {{ ':'+ selectedQuery?.port || '' }} -
- - {{selectedQuery?.productName}} - - - {{selectedQuery?.productVersion}} -
- -
+
+
-
-
+ + +

- Aucun détail disponible ..
- Vérifiez que TraceAPI est bien configuré sur {{ - selectedQuery?.host}} + Aucun détail disponible ..

diff --git a/src/app/views/detail/database/database.component.scss b/src/app/views/detail/database/database.component.scss index ffc8b36..1faabc0 100644 --- a/src/app/views/detail/database/database.component.scss +++ b/src/app/views/detail/database/database.component.scss @@ -77,5 +77,12 @@ table { text-decoration: solid; } +.success { + border-left: 4px solid green; +} + +.fail { + border-left: 4px solid red; +} \ No newline at end of file diff --git a/src/app/views/detail/database/database.component.ts b/src/app/views/detail/database/database.component.ts index 5ce1174..afc5c20 100644 --- a/src/app/views/detail/database/database.component.ts +++ b/src/app/views/detail/database/database.component.ts @@ -1,33 +1,45 @@ -import {Component, ElementRef, NgZone, OnDestroy, ViewChild} from '@angular/core'; +import {Component, ElementRef, inject, NgZone, OnDestroy, OnInit, ViewChild} from '@angular/core'; import {ActivatedRoute} from '@angular/router'; -import {combineLatest, forkJoin} from "rxjs"; +import {combineLatest, finalize, forkJoin, Subscription} from "rxjs"; import {DataItem, Timeline} from 'vis-timeline'; import {Utils} from 'src/app/shared/util'; import {DatePipe, Location} from '@angular/common'; import {TraceService} from 'src/app/service/trace.service'; import {application} from 'src/environments/environment'; -import {DatabaseRequest, DatabaseRequestStage} from 'src/app/model/trace.model'; +import { + DatabaseRequest, + DatabaseRequestStage, + ExceptionInfo, + Mail, + MailRequest, + MailRequestStage +} from 'src/app/model/trace.model'; import {EnvRouter} from "../../../service/router.service"; +import {MatTableDataSource} from "@angular/material/table"; +import {DurationPipe} from "../../../shared/pipe/duration.pipe"; @Component({ templateUrl: './database.component.html', styleUrls: ['./database.component.scss'], - }) -export class DatabaseComponent implements OnDestroy { - utils: Utils = new Utils; - selectedQuery: DatabaseRequest; - dbQueryId: number; - dbQueryParentId: string; - dbQueryParentType: string; - mainType: string; +export class DatabaseComponent implements OnInit, OnDestroy { + private _activatedRoute: ActivatedRoute = inject(ActivatedRoute); + private _traceService: TraceService = inject(TraceService); + private _router: EnvRouter = inject(EnvRouter); + + private params: Partial<{idSession: string, idJdbc: number, typeSession: string, typeMain: string, env: string}> = {}; + private subscription: Subscription[] = []; + private pipe = new DatePipe('fr-FR'); + private durationPipe = new DurationPipe(); + + timeLine: Timeline; + request: DatabaseRequest; + exception: ExceptionInfo; + isComplete: boolean = true; isLoading: boolean = false; - paramsSubscription: any; - timeLine: Timeline; - env: any; - pipe = new DatePipe('fr-FR') + @ViewChild('timeline') timelineContainer: ElementRef; jdbcActionDescription: { [key: string]: string } = @@ -47,90 +59,57 @@ export class DatabaseComponent implements OnDestroy { 'SAVEPOINT': 'This command allows you to set a savepoint within a transaction' }; - - constructor(private _activatedRoute: ActivatedRoute, - private _traceService: TraceService, - private _router: EnvRouter, - private _location: Location) { - this.paramsSubscription = combineLatest([ + ngOnInit() { + this.subscription.push(combineLatest([ this._activatedRoute.params, this._activatedRoute.data, this._activatedRoute.queryParams ]).subscribe({ next: ([params, data, queryParams]) => { - this.dbQueryId = params.id_database; - this.dbQueryParentId = params.id_session; - this.dbQueryParentType = data.type; - this.mainType = params.type_main; - this.env = queryParams.env || application.default_env; - this._location.replaceState(`${this._router.url.split('?')[0]}?env=${this.env}`) - this.getDbRequestById(); + this.params = {idSession: params.id_session, idJdbc: params.id_jdbc, + typeSession: data.type, typeMain: params.type_main, env: queryParams.env || application.default_env}; + this.getRequest(); } - }); + })) } - getDbRequestById() { + getRequest(){ this.isLoading = true; - forkJoin({ - query: this._traceService.getDatabaseRequests(this.dbQueryParentId, this.dbQueryId), - stages: this._traceService.getDatabaseRequestStages(this.dbQueryParentId, this.dbQueryId) - }).subscribe({ - next: res => { - if (res) { - this.selectedQuery = res.query; - this.selectedQuery.actions = res.stages; - this.visjs(); - this.isLoading = false; - this.isComplete = true; - } else { - this.isLoading = false; - this.isComplete = false; - // navigate to tab incoming - } - }, - error: err => { - this.isLoading = false; + this.subscription.push(forkJoin({ + request: this._traceService.getDatabaseRequests(this.params.idSession, this.params.idJdbc), + stages: this._traceService.getDatabaseRequestStages(this.params.idSession, this.params.idJdbc) + }).pipe(finalize(() => this.isLoading = false)).subscribe({ + next: (value: {request: DatabaseRequest, stages: DatabaseRequestStage[]}) => { + this.request = value.request; + this.request.actions = value.stages; + this.exception = value.stages.find(s => s.exception?.type || s.exception?.message)?.exception; + this.createTimeline(); } - }); + })) } - visjs() { - if (this.timeLine) { // destroy if exists - this.timeLine.destroy(); - } - let timeline_end = Math.ceil(this.selectedQuery.end * 1000) ; - let timeline_start = Math.trunc(this.selectedQuery.start * 1000); - let actions = this.selectedQuery.actions; - this.sortInnerArrayByDate(actions) - - let groups = actions.map((g: DatabaseRequestStage,i:number ) => ({ id: i, content: g?.name, title: this.jdbcActionDescription[g?.name] })) + createTimeline() { + let timeline_end = Math.ceil(this.request.end * 1000) ; + let timeline_start = Math.trunc(this.request.start * 1000); + let actions = this.request.actions.sort((a, b) => a.order - b.order); - let dataArray = actions.map((c: DatabaseRequestStage, i: number) => { - let e: any = { - group: groups[i].id, + let items = actions.map((c: DatabaseRequestStage, i: number) => { + let item: DataItem = { + group: c.order, start: Math.trunc(c.start * 1000), end: Math.trunc(c.end * 1000), - title: `${this.pipe.transform(new Date(c.start * 1000), 'HH:mm:ss.SSS')} - ${this.pipe.transform(new Date(c.end * 1000), 'HH:mm:ss.SSS')}
-

${c.name}${c?.count ? '(' + c?.count + ')' : ''}: ${this.getElapsedTime(c.end, c.start).toFixed(3)}s

`, - //className : 'vis-dot', - } - if((c.name == 'FETCH' || c.name == 'BATCH' ||c.name == 'EXECUTE') && c.count){ // changed c.type to c.name - e.content = c.count.toString(); + content: '', + title: `${this.pipe.transform(new Date(c.start * 1000), 'HH:mm:ss.SSS')} - ${this.pipe.transform(new Date(c.end * 1000), 'HH:mm:ss.SSS')} (${this.durationPipe.transform({start: c.start, end: c.end})})
+

${c.count ? c.count : ''}

` } - e.type = e.end <= e.start ? 'point' : 'range'// TODO : change this to equals dh_dbt is set to timestamps(6), currently set to timestmap(3) - if (c?.exception?.message || c?.exception?.type) { - e.className = 'bdd-failed'; - e.title += `
${c?.exception?.message}
`; // TODO : fix css on tooltip + item.type = item.end <= item.start ? 'point' : 'range' // TODO : change this to equals dh_dbt is set to timestamps(6), currently set to timestmap(3) + if (c.exception?.message || c.exception?.type) { + item.className = 'bdd-failed'; } - - - return e; + return item; }) - console.log(this.selectedQuery, dataArray, groups, timeline_start, timeline_end) - - // Create a Timeline - this.timeLine = new Timeline(this.timelineContainer.nativeElement, dataArray, groups, + this.timeLine = new Timeline(this.timelineContainer.nativeElement, items, actions.map((g: DatabaseRequestStage,i:number ) => ({ id: g.order, content: g?.name, title: this.jdbcActionDescription[g?.name] })), { min: timeline_start, max: timeline_end, @@ -147,103 +126,25 @@ export class DatabaseComponent implements OnDestroy { }); } - getElapsedTime(end: number, start: number) { - // return (new Date(end * 1000).getTime() - new Date(start * 1000).getTime()) / 1000 - return end - start; - } - - getRe(re: string) { - return this.utils.getRe(re); - } - - statusBorder(status: any) { - return Utils.statusBorder(status); - } - - getStateColorBool() { - return Utils.getStateColorBool(this.selectedQuery?.completed) - } - - getSessionDetailBorder() { - - return Utils.statusBorderCard(!this.selectedQuery?.completed) - - } - - getSessionStatusTooltip(session: any) { - return session?.completed ? "réussi" : "échoué"; - } - - - configDbactions(query: DatabaseRequest) { - query.actions.forEach((db: any, i: number) => { - if (query.actions[i + 1]) { - let diffElapsed = new Date(db.end * 1000).getTime() - new Date(+query.actions[i + 1].start * 1000).getTime(); - - if (diffElapsed != 0) { - query.actions.splice(i + 1, 0, { - 'name': ' ', - 'exception': {'type': null, 'message': null}, - 'start': db.end, - 'end': query.actions[i + 1].start - }) - } - } - }); - } - - getSessionUrl(selectedSession: any) { - return Utils.getSessionUrl(selectedSession); - } - - navigate(event: MouseEvent, targetType: string, extraParam?: string) { let params: any[] = []; switch (targetType) { case "parent": - if(this.mainType) params.push('session', this.dbQueryParentType, this.mainType, this.dbQueryParentId) - else params.push('session', this.dbQueryParentType, this.dbQueryParentId) + if(this.params.typeMain) params.push('session', this.params.typeSession, this.params.typeMain, this.params.idSession) + else params.push('session', this.params.typeSession, this.params.idSession) } if (event.ctrlKey) { this._router.open(`#/${params.join('/')}`, '_blank') } else { this._router.navigate(params, { - queryParams: {env: this.env} + queryParams: {env: this.params.env} }); } } - - sortInnerArrayByDate(innerArray: DatabaseRequestStage[]): any[] { - return innerArray.sort((a, b) => { - return a.order - b.order - }); - } - - isQueryCompleted(query: DatabaseRequest): boolean { - return query.actions.every((a: DatabaseRequestStage) => !a?.exception?.type && !a?.exception?.message); - } - - getCommand(commands: string[]): string { - let command = "" - if (commands?.length == 1) { - command = `[${commands[0]}]` - } else if (commands?.length > 1) { - command = "[SQL]" - } - return command; - } - - getException(actions: DatabaseRequestStage[]): DatabaseRequestStage { - return actions.filter(a => a?.exception?.message || a?.exception?.type)[0] - } - ngOnDestroy() { - if (this.paramsSubscription) { - this.paramsSubscription.unsubscribe(); - } + this.subscription.forEach(s => s.unsubscribe()); + this.timeLine.destroy(); } - - } diff --git a/src/app/views/detail/ftp/ftp.component.html b/src/app/views/detail/ftp/ftp.component.html new file mode 100644 index 0000000..cef091c --- /dev/null +++ b/src/app/views/detail/ftp/ftp.component.html @@ -0,0 +1,47 @@ +
+ + +
+ smb_share + {{ request.host + ':' + request.port || 'N/A' }} +
+ +
+ +
+
+ +
+
+ warning{{exception.message}} +
+
+
+ + person +
+ {{request.user || "N/A"}} le {{( request.start*1000 ) | date: 'dd/MM/yyyy à HH:mm:ss.SSS': 'fr' }} + en {{{ start: request.start, end: request.end } | duration}} +
+
+
+
+ + +
+
+ +
+ view_timeline + Chronologie +
+ +
+
+
+ diff --git a/src/app/views/detail/ftp/ftp.component.scss b/src/app/views/detail/ftp/ftp.component.scss new file mode 100644 index 0000000..7341723 --- /dev/null +++ b/src/app/views/detail/ftp/ftp.component.scss @@ -0,0 +1,87 @@ +.header-card { + display: flex; + flex-direction: row; + gap: 0.5em; + margin-bottom: 2em; +} + +a { + color: inherit; + text-decoration: none; +} + +mat-card-title { + display: flex; + align-items: center; + padding: 0 16px; + height: 48px; + .right { + margin-left: auto; + } +} + +mat-card-content { + height: 100%; padding: 0 16px 16px; +} + +mat-card-footer { + padding: 0 16px; + border: 1px solid rgba(0,0,0,.05); + display: flex; + align-items: center; + gap: 0.5em; + font-style: italic; + font-size: 14px; + .right { + margin-left: auto; + display: flex; + align-items: center; + } +} + + +table { + table-layout: auto; +} +.dbfailed { + background-color: red !important; +} + +.progress { + height: 20px; + display: flex; +} + +.progress-bar { + justify-content: center; + overflow: hidden; + color: #fff; + text-align: center; + white-space: nowrap; +} + +.mat-mdc-row .mat-mdc-cell { + cursor: pointer; +} + +.mat-mdc-row:hover .mat-mdc-cell { + background-color: rgb(206, 206, 206); +} + +.mat-mdc-table .mdc-data-table__header-row { + background-color: #d1d1d1; +} + +.url { + color: blue; + text-decoration: solid; +} + +.success { + border-left: 4px solid green; +} + +.fail { + border-left: 4px solid red; +} + diff --git a/src/app/views/detail/ftp/ftp.component.ts b/src/app/views/detail/ftp/ftp.component.ts new file mode 100644 index 0000000..770097e --- /dev/null +++ b/src/app/views/detail/ftp/ftp.component.ts @@ -0,0 +1,111 @@ +import {Component, ElementRef, inject, OnDestroy, OnInit, ViewChild} from "@angular/core"; +import {DataItem, Timeline} from "vis-timeline"; +import {ActivatedRoute} from "@angular/router"; +import {TraceService} from "../../../service/trace.service"; +import {DatePipe} from "@angular/common"; +import {combineLatest, finalize, forkJoin, map, Subscription} from "rxjs"; +import {application} from "../../../../environments/environment"; +import {ExceptionInfo, FtpRequest, FtpRequestStage} from "../../../model/trace.model"; +import {EnvRouter} from "../../../service/router.service"; +import {Utils} from "../../../shared/util"; +import {DurationPipe} from "../../../shared/pipe/duration.pipe"; + +@Component({ + templateUrl: './ftp.component.html', + styleUrls: ['./ftp.component.scss'], +}) +export class FtpComponent implements OnInit, OnDestroy { + private _activatedRoute: ActivatedRoute = inject(ActivatedRoute); + private _traceService: TraceService = inject(TraceService); + private _router: EnvRouter = inject(EnvRouter); + + private timeLine: Timeline; + private subscription: Subscription[] = []; + private params: Partial<{idSession: string, idFtp: number, typeSession: string, typeMain: string, env: string}> = {}; + private pipe = new DatePipe('fr-FR'); + private durationPipe = new DurationPipe(); + + request: FtpRequest; + exception: ExceptionInfo; + isLoading: boolean; + + @ViewChild('timeline') timelineContainer: ElementRef; + + ngOnInit() { + this.subscription.push(combineLatest([ + this._activatedRoute.params, + this._activatedRoute.data, + this._activatedRoute.queryParams + ]).subscribe({ + next: ([params, data, queryParams]) => { + this.params = {idSession: params.id_session, idFtp: params.id_ftp, + typeSession: data.type, typeMain: params.type_main, env: queryParams.env || application.default_env}; + this.getRequest(); + } + })); + } + + ngOnDestroy() { + this.subscription.forEach(s => s.unsubscribe()); + this.timeLine.destroy(); + } + + getRequest() { + this.isLoading = true; + this.subscription.push(forkJoin({ + request: this._traceService.getFtpRequests(this.params.idSession, this.params.idFtp).pipe(map(f => ({...f, duration: Utils.getElapsedTime(f.start, f.end)}))), + stages: this._traceService.getFtpRequestStages(this.params.idSession, this.params.idFtp) + }).pipe(finalize(() => this.isLoading = false)).subscribe({ + next: (value: {request: FtpRequest, stages: FtpRequestStage[]}) => { + this.request = value.request; + this.request.actions = value.stages; + this.exception = value.stages.find(s => s.exception?.type || s.exception?.message)?.exception; + this.createTimeline(); + } + })); + } + + createTimeline() { + let timeline_start = Math.trunc(this.request.start * 1000); + let timeline_end = Math.ceil(this.request.end * 1000); + let actions = this.request.actions.sort((a, b) => a.order - b.order); + + let items = actions.map(a => { + let item: DataItem = { + group: a.order, + start: Math.trunc(a.start * 1000), + end: Math.trunc(a.end * 1000), + content: '', + title: `${this.pipe.transform(new Date(a.start * 1000), 'HH:mm:ss.SSS')} - ${this.pipe.transform(new Date(a.end * 1000), 'HH:mm:ss.SSS')} (${this.durationPipe.transform({start: a.start, end: a.end})})
+

${a?.args ? a.args.join('
') : ''}

` + } + + item.type = item.end <= item.start ? 'point' : 'range'; + if (a.exception?.message || a.exception?.type) { + item.className = 'bdd-failed'; + } + return item; + }); + + this.timeLine = new Timeline(this.timelineContainer.nativeElement, items, actions.map(a => ({ id: a.order, content: a?.name })), { + min: timeline_start, + max: timeline_end + }); + } + + navigate(event: MouseEvent, targetType: string, extraParam?: string) { + let params: any[] = []; + switch (targetType) { + case "parent": + if(this.params.typeMain) params.push('session', this.params.typeSession, this.params.typeMain, this.params.idSession); + else params.push('session', this.params.typeSession, this.params.idSession); + } + if (event.ctrlKey) { + this._router.open(`#/${params.join('/')}`, '_blank') + } else { + this._router.navigate(params, { + queryParams: {env: this.params.env} + }); + } + } +} \ No newline at end of file diff --git a/src/app/views/detail/ldap/ldap.component.html b/src/app/views/detail/ldap/ldap.component.html new file mode 100644 index 0000000..386627f --- /dev/null +++ b/src/app/views/detail/ldap/ldap.component.html @@ -0,0 +1,51 @@ +
+ + +
+ user_attributes + {{ request.host + ':' + request.port || 'N/A' }} +
+ +
+ +
+
+ +
+
+ warning{{exception.message}} +
+
+
+ + person +
+ {{request.user || "N/A"}} le {{( request.start*1000 ) | date: 'dd/MM/yyyy à HH:mm:ss.SSS': 'fr' }} + en {{{ start: request.start, end: request.end } | duration}} +
+
+
+
+ + +
+
+ +
+ view_timeline + Chronologie +
+ +
+
+
+ +
+ Chargement en cours... +
+ diff --git a/src/app/views/detail/ldap/ldap.component.scss b/src/app/views/detail/ldap/ldap.component.scss new file mode 100644 index 0000000..7341723 --- /dev/null +++ b/src/app/views/detail/ldap/ldap.component.scss @@ -0,0 +1,87 @@ +.header-card { + display: flex; + flex-direction: row; + gap: 0.5em; + margin-bottom: 2em; +} + +a { + color: inherit; + text-decoration: none; +} + +mat-card-title { + display: flex; + align-items: center; + padding: 0 16px; + height: 48px; + .right { + margin-left: auto; + } +} + +mat-card-content { + height: 100%; padding: 0 16px 16px; +} + +mat-card-footer { + padding: 0 16px; + border: 1px solid rgba(0,0,0,.05); + display: flex; + align-items: center; + gap: 0.5em; + font-style: italic; + font-size: 14px; + .right { + margin-left: auto; + display: flex; + align-items: center; + } +} + + +table { + table-layout: auto; +} +.dbfailed { + background-color: red !important; +} + +.progress { + height: 20px; + display: flex; +} + +.progress-bar { + justify-content: center; + overflow: hidden; + color: #fff; + text-align: center; + white-space: nowrap; +} + +.mat-mdc-row .mat-mdc-cell { + cursor: pointer; +} + +.mat-mdc-row:hover .mat-mdc-cell { + background-color: rgb(206, 206, 206); +} + +.mat-mdc-table .mdc-data-table__header-row { + background-color: #d1d1d1; +} + +.url { + color: blue; + text-decoration: solid; +} + +.success { + border-left: 4px solid green; +} + +.fail { + border-left: 4px solid red; +} + diff --git a/src/app/views/detail/ldap/ldap.component.ts b/src/app/views/detail/ldap/ldap.component.ts new file mode 100644 index 0000000..3f51eee --- /dev/null +++ b/src/app/views/detail/ldap/ldap.component.ts @@ -0,0 +1,116 @@ +import {Component, ElementRef, inject, OnDestroy, OnInit, ViewChild} from "@angular/core"; +import {ActivatedRoute} from "@angular/router"; +import {TraceService} from "../../../service/trace.service"; +import {DataItem, Timeline} from "vis-timeline"; +import {combineLatest, finalize, forkJoin, Subscription} from "rxjs"; +import { + ExceptionInfo, + FtpRequest, + FtpRequestStage, + NamingRequest, + NamingRequestStage +} from "../../../model/trace.model"; +import {DatePipe} from "@angular/common"; +import {application} from "../../../../environments/environment"; +import {DurationPipe} from "../../../shared/pipe/duration.pipe"; +import {EnvRouter} from "../../../service/router.service"; + +@Component({ + templateUrl: './ldap.component.html', + styleUrls: ['./ldap.component.scss'], +}) +export class LdapComponent implements OnInit, OnDestroy { + private _activatedRoute: ActivatedRoute = inject(ActivatedRoute); + private _traceService: TraceService = inject(TraceService); + private _router: EnvRouter = inject(EnvRouter); + + private timeLine: Timeline; + private subscription: Subscription[] = []; + private params: Partial<{idSession: string, idLdap: number, typeSession: string, typeMain: string, env: string}> = {}; + private pipe = new DatePipe('fr-FR'); + private durationPipe = new DurationPipe(); + + request: NamingRequest; + exception: ExceptionInfo; + isLoading: boolean; + + @ViewChild('timeline') timelineContainer: ElementRef; + + ngOnInit() { + this.subscription.push(combineLatest([ + this._activatedRoute.params, + this._activatedRoute.data, + this._activatedRoute.queryParams + ]).subscribe({ + next: ([params, data, queryParams]) => { + this.params = {idSession: params.id_session, idLdap: params.id_ldap, + typeSession: data.type, typeMain: params.type_main, env: queryParams.env || application.default_env}; + this.getRequest(); + } + })); + } + + ngOnDestroy() { + this.subscription.forEach(s => s.unsubscribe()); + this.timeLine.destroy(); + } + + getRequest() { + this.isLoading = true; + this.subscription.push(forkJoin({ + request: this._traceService.getLdapRequests(this.params.idSession, this.params.idLdap), + stages: this._traceService.getLdapRequestStages(this.params.idSession, this.params.idLdap) + }).pipe(finalize(() => this.isLoading = false)).subscribe({ + next: (value: {request: NamingRequest, stages: NamingRequestStage[]}) => { + this.request = value.request; + this.request.actions = value.stages; + this.exception = value.stages.find(s => s.exception?.type || s.exception?.message)?.exception; + this.createTimeline(); + } + })); + } + + createTimeline() { + let timeline_start = Math.trunc(this.request.start * 1000); + let timeline_end = Math.ceil(this.request.end * 1000); + let actions = this.request.actions.sort((a, b) => a.order - b.order); + + let items = actions.map(a => { + let item: DataItem = { + group: a.order, + start: Math.trunc(a.start * 1000), + end: Math.trunc(a.end * 1000), + content: '', + title: `${this.pipe.transform(a.start * 1000, 'HH:mm:ss.SSS')} - ${this.pipe.transform(a.end * 1000, 'HH:mm:ss.SSS')} (${this.durationPipe.transform({start: a.start, end: a.end})})
+

${a?.args ? a.args.join('
') : ''}

` + } + console.log(item) + item.type = item.end <= item.start ? 'point' : 'range'; + if (a.exception?.message || a.exception?.type) { + item.className = 'bdd-failed'; + } + return item; + }); + + this.timeLine = new Timeline(this.timelineContainer.nativeElement, items, actions.map(a => ({ id: a.order, content: a?.name })), { + min: timeline_start, + max: timeline_end + }); + } + + navigate(event: MouseEvent, targetType: string, extraParam?: string) { + let params: any[] = []; + switch (targetType) { + case "parent": + if(this.params.typeMain) params.push('session', this.params.typeSession, this.params.typeMain, this.params.idSession); + else params.push('session', this.params.typeSession, this.params.idSession); + } + if (event.ctrlKey) { + this._router.open(`#/${params.join('/')}`, '_blank') + } else { + this._router.navigate(params, { + queryParams: {env: this.params.env} + }); + } + } +} \ No newline at end of file diff --git a/src/app/views/detail/session/_component/database-table/database-table.component.html b/src/app/views/detail/session/_component/database-table/database-table.component.html index 7abd92f..5b54717 100644 --- a/src/app/views/detail/session/_component/database-table/database-table.component.html +++ b/src/app/views/detail/session/_component/database-table/database-table.component.html @@ -42,7 +42,7 @@
diff --git a/src/app/views/detail/session/_component/database-table/database-table.component.ts b/src/app/views/detail/session/_component/database-table/database-table.component.ts index 6ce96de..6fe9207 100644 --- a/src/app/views/detail/session/_component/database-table/database-table.component.ts +++ b/src/app/views/detail/session/_component/database-table/database-table.component.ts @@ -1,9 +1,8 @@ -import { Component, EventEmitter, Input, OnInit, Output, ViewChild } from "@angular/core"; -import { MatPaginator } from "@angular/material/paginator"; -import { MatSort } from "@angular/material/sort"; -import { MatTableDataSource } from "@angular/material/table"; -import { DatabaseRequest } from "src/app/model/trace.model"; -import { Utils } from "src/app/shared/util"; +import {Component, EventEmitter, Input, OnInit, Output, ViewChild} from "@angular/core"; +import {MatPaginator} from "@angular/material/paginator"; +import {MatSort} from "@angular/material/sort"; +import {MatTableDataSource} from "@angular/material/table"; +import {DatabaseRequest} from "src/app/model/trace.model"; @Component({ selector: 'database-table', diff --git a/src/app/views/detail/session/_component/detail-session.component.html b/src/app/views/detail/session/_component/detail-session.component.html new file mode 100644 index 0000000..e69de29 diff --git a/src/app/views/detail/session/_component/detail-session.component.scss b/src/app/views/detail/session/_component/detail-session.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/app/views/detail/session/_component/detail-session.component.ts b/src/app/views/detail/session/_component/detail-session.component.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/app/views/detail/session/_component/ftp-table/ftp-table.component.html b/src/app/views/detail/session/_component/ftp-table/ftp-table.component.html index 7f25fee..ffb151e 100644 --- a/src/app/views/detail/session/_component/ftp-table/ftp-table.component.html +++ b/src/app/views/detail/session/_component/ftp-table/ftp-table.component.html @@ -6,9 +6,7 @@ - @@ -19,15 +17,6 @@ - - - - - diff --git a/src/app/views/detail/session/_component/ftp-table/ftp-table.component.ts b/src/app/views/detail/session/_component/ftp-table/ftp-table.component.ts index 33a3e59..adfdd04 100644 --- a/src/app/views/detail/session/_component/ftp-table/ftp-table.component.ts +++ b/src/app/views/detail/session/_component/ftp-table/ftp-table.component.ts @@ -1,9 +1,8 @@ -import { Component, EventEmitter, Input, OnInit, Output, ViewChild, inject } from "@angular/core"; -import { MatPaginator } from "@angular/material/paginator"; -import { MatSort } from "@angular/material/sort"; -import { MatTableDataSource } from "@angular/material/table"; -import {FtpRequest, RestRequest} from "src/app/model/trace.model"; -import { Utils } from "src/app/shared/util"; +import {Component, EventEmitter, Input, OnInit, Output, ViewChild} from "@angular/core"; +import {MatPaginator} from "@angular/material/paginator"; +import {MatSort} from "@angular/material/sort"; +import {MatTableDataSource} from "@angular/material/table"; +import {FtpRequest} from "src/app/model/trace.model"; @Component({ selector: 'ftp-table', @@ -11,9 +10,8 @@ import { Utils } from "src/app/shared/util"; styleUrls: ['./ftp-table.component.scss'] }) export class FtpTableComponent implements OnInit { - displayedColumns: string[] = ['status', 'host', 'path', 'start', 'duree']; + displayedColumns: string[] = ['status', 'host', 'start', 'duree']; dataSource: MatTableDataSource = new MatTableDataSource(); - filterTable = new Map(); @ViewChild('paginator', {static: true}) paginator: MatPaginator; @ViewChild('sort', {static: true}) sort: MatSort; @@ -30,20 +28,6 @@ export class FtpTableComponent implements OnInit { ngOnInit() { this.dataSource.sortingDataAccessor = sortingDataAccessor; } - - applyFilter(event: Event) { - const filterValue = (event.target as HTMLInputElement).value; - this.filterTable.set('filter', filterValue.trim().toLowerCase()); - this.dataSource.filter = JSON.stringify(Array.from(this.filterTable.entries())); - if (this.dataSource.paginator) { - this.dataSource.paginator.firstPage(); - } - } - - toggleFilter(filter: string[]) { - this.filterTable.set('status', filter); - this.dataSource.filter = JSON.stringify(Array.from(this.filterTable.entries())); - } selectedRequest(event: MouseEvent, row: any) { console.log(row) @@ -53,10 +37,6 @@ export class FtpTableComponent implements OnInit { getElapsedTime(end: number, start: number,) { return end - start; } - - statusBorder(status: any) { - return Utils.statusBorder(status); - } } const sortingDataAccessor = (row: any, columnName: string) => { diff --git a/src/app/views/detail/session/_component/ldap-table/ldap-table.component.html b/src/app/views/detail/session/_component/ldap-table/ldap-table.component.html new file mode 100644 index 0000000..ffb151e --- /dev/null +++ b/src/app/views/detail/session/_component/ldap-table/ldap-table.component.html @@ -0,0 +1,62 @@ +
+
API - [{{element.method}}] + [{{element.method}}]
{{element['path']}}
- {{getElapsedTime(element.end,element.start)| number :'1.2-3' || 'N/A'}}s + {{(getElapsedTime(element.end,element.start) | duration) || 'N/A'}} + API - [{{element.method}}] -
- {{element['path']}} -
Début @@ -47,7 +36,7 @@ - {{getElapsedTime(element.end,element.start)| number :'1.2-3' }}s + {{getElapsedTime(element.end,element.start) | duration }}
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + Hôte + {{element['host']}}:{{element['port']}} + Début +
+ {{ (element.start*1000 |date:'dd/MM/yyyy')}} +
+
+
+ {{ (element.start*1000 |date:'HH:mm:ss.SSS')}} +
+
Durée + + {{getElapsedTime(element.end,element.start) | duration }} + +
+
+ + info + + Aucun résultat +
+
+ +
\ No newline at end of file diff --git a/src/app/views/detail/session/_component/ldap-table/ldap-table.component.scss b/src/app/views/detail/session/_component/ldap-table/ldap-table.component.scss new file mode 100644 index 0000000..780ed25 --- /dev/null +++ b/src/app/views/detail/session/_component/ldap-table/ldap-table.component.scss @@ -0,0 +1,11 @@ +.searchwidth { + flex-grow: 1; +} + +.mat-mdc-row .mat-mdc-cell { + cursor: pointer; +} + +.mat-mdc-row:hover .mat-mdc-cell { + background-color: rgb(206, 206, 206); +} \ No newline at end of file diff --git a/src/app/views/detail/session/_component/ldap-table/ldap-table.component.ts b/src/app/views/detail/session/_component/ldap-table/ldap-table.component.ts new file mode 100644 index 0000000..7d071b9 --- /dev/null +++ b/src/app/views/detail/session/_component/ldap-table/ldap-table.component.ts @@ -0,0 +1,48 @@ +import {Component, EventEmitter, Input, OnInit, Output, ViewChild} from "@angular/core"; +import {MatPaginator} from "@angular/material/paginator"; +import {MatSort} from "@angular/material/sort"; +import {MatTableDataSource} from "@angular/material/table"; +import {NamingRequest} from "src/app/model/trace.model"; + +@Component({ + selector: 'ldap-table', + templateUrl: './ldap-table.component.html', + styleUrls: ['./ldap-table.component.scss'] +}) +export class LdapTableComponent implements OnInit { + displayedColumns: string[] = ['status', 'host', 'start', 'duree']; + dataSource: MatTableDataSource = new MatTableDataSource(); + + @ViewChild('paginator', {static: true}) paginator: MatPaginator; + @ViewChild('sort', {static: true}) sort: MatSort; + + @Input() set requests(requests: NamingRequest[]) { + if(requests) { + this.dataSource = new MatTableDataSource(requests); + this.dataSource.paginator = this.paginator; + this.dataSource.sort = this.sort; + } + } + + @Output() onClickRow: EventEmitter<{event: MouseEvent, row: any}> = new EventEmitter(); + + ngOnInit() { + this.dataSource.sortingDataAccessor = sortingDataAccessor; + } + + selectedRequest(event: MouseEvent, row: any) { + console.log(row) + this.onClickRow.emit({event: event, row: row}); + } + + getElapsedTime(end: number, start: number,) { + return end - start; + } +} + +const sortingDataAccessor = (row: any, columnName: string) => { + if (columnName == "host") return row["host"] + ":" + row["port"] as string; + if (columnName == "start") return row['start'] as string; + if (columnName == "duree") return (row["end"] - row["start"]); + return row[columnName as keyof any] as string; +} diff --git a/src/app/views/detail/session/_component/rest-table/rest-table.component.html b/src/app/views/detail/session/_component/rest-table/rest-table.component.html index 20dfe96..44ffe05 100644 --- a/src/app/views/detail/session/_component/rest-table/rest-table.component.html +++ b/src/app/views/detail/session/_component/rest-table/rest-table.component.html @@ -73,7 +73,7 @@ - {{getElapsedTime(element.end,element.start)| number :'1.2-3' }}s + {{getElapsedTime(element.end,element.start) | duration }} diff --git a/src/app/views/detail/session/_component/rest-table/rest-table.component.ts b/src/app/views/detail/session/_component/rest-table/rest-table.component.ts index e4c20f2..b6c8ee0 100644 --- a/src/app/views/detail/session/_component/rest-table/rest-table.component.ts +++ b/src/app/views/detail/session/_component/rest-table/rest-table.component.ts @@ -1,9 +1,8 @@ -import { Component, EventEmitter, Input, OnInit, Output, ViewChild, inject } from "@angular/core"; -import { MatPaginator } from "@angular/material/paginator"; -import { MatSort } from "@angular/material/sort"; -import { MatTableDataSource } from "@angular/material/table"; -import { RestRequest } from "src/app/model/trace.model"; -import { Utils } from "src/app/shared/util"; +import {Component, EventEmitter, Input, OnInit, Output, ViewChild} from "@angular/core"; +import {MatPaginator} from "@angular/material/paginator"; +import {MatSort} from "@angular/material/sort"; +import {MatTableDataSource} from "@angular/material/table"; +import {RestRequest} from "src/app/model/trace.model"; @Component({ selector: 'rest-table', @@ -54,10 +53,6 @@ export class RestTableComponent implements OnInit { getElapsedTime(end: number, start: number,) { return end - start; } - - statusBorder(status: any) { - return Utils.statusBorder(status); - } } const sortingDataAccessor = (row: any, columnName: string) => { diff --git a/src/app/views/detail/session/_component/smtp-table/smtp-table.component.html b/src/app/views/detail/session/_component/smtp-table/smtp-table.component.html new file mode 100644 index 0000000..ffb151e --- /dev/null +++ b/src/app/views/detail/session/_component/smtp-table/smtp-table.component.html @@ -0,0 +1,62 @@ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + Hôte + {{element['host']}}:{{element['port']}} + Début +
+ {{ (element.start*1000 |date:'dd/MM/yyyy')}} +
+
+
+ {{ (element.start*1000 |date:'HH:mm:ss.SSS')}} +
+
Durée + + {{getElapsedTime(element.end,element.start) | duration }} + +
+
+ + info + + Aucun résultat +
+
+ +
\ No newline at end of file diff --git a/src/app/views/detail/session/_component/smtp-table/smtp-table.component.scss b/src/app/views/detail/session/_component/smtp-table/smtp-table.component.scss new file mode 100644 index 0000000..780ed25 --- /dev/null +++ b/src/app/views/detail/session/_component/smtp-table/smtp-table.component.scss @@ -0,0 +1,11 @@ +.searchwidth { + flex-grow: 1; +} + +.mat-mdc-row .mat-mdc-cell { + cursor: pointer; +} + +.mat-mdc-row:hover .mat-mdc-cell { + background-color: rgb(206, 206, 206); +} \ No newline at end of file diff --git a/src/app/views/detail/session/_component/smtp-table/smtp-table.component.ts b/src/app/views/detail/session/_component/smtp-table/smtp-table.component.ts new file mode 100644 index 0000000..b66a20e --- /dev/null +++ b/src/app/views/detail/session/_component/smtp-table/smtp-table.component.ts @@ -0,0 +1,47 @@ +import {Component, EventEmitter, Input, OnInit, Output, ViewChild} from "@angular/core"; +import {MatPaginator} from "@angular/material/paginator"; +import {MatSort} from "@angular/material/sort"; +import {MatTableDataSource} from "@angular/material/table"; +import {MailRequest} from "src/app/model/trace.model"; + +@Component({ + selector: 'smtp-table', + templateUrl: './smtp-table.component.html', + styleUrls: ['./smtp-table.component.scss'] +}) +export class SmtpTableComponent implements OnInit { + displayedColumns: string[] = ['status', 'host', 'start', 'duree']; + dataSource: MatTableDataSource = new MatTableDataSource(); + + @ViewChild('paginator', {static: true}) paginator: MatPaginator; + @ViewChild('sort', {static: true}) sort: MatSort; + + @Input() set requests(requests: MailRequest[]) { + if(requests) { + this.dataSource = new MatTableDataSource(requests); + this.dataSource.paginator = this.paginator; + this.dataSource.sort = this.sort; + } + } + @Output() onClickRow: EventEmitter<{event: MouseEvent, row: any}> = new EventEmitter(); + + ngOnInit() { + this.dataSource.sortingDataAccessor = sortingDataAccessor; + } + + selectedRequest(event: MouseEvent, row: any) { + console.log(row) + this.onClickRow.emit({event: event, row: row}); + } + + getElapsedTime(end: number, start: number,) { + return end - start; + } +} + +const sortingDataAccessor = (row: any, columnName: string) => { + if (columnName == "host") return row["host"] + ":" + row["port"] as string; + if (columnName == "start") return row['start'] as string; + if (columnName == "duree") return (row["end"] - row["start"]); + return row[columnName as keyof any] as string; +} diff --git a/src/app/views/detail/session/_component/timeline/timeline.component.ts b/src/app/views/detail/session/_component/timeline/timeline.component.ts index a6617ad..5b6f67b 100644 --- a/src/app/views/detail/session/_component/timeline/timeline.component.ts +++ b/src/app/views/detail/session/_component/timeline/timeline.component.ts @@ -1,7 +1,14 @@ -import { DatePipe } from "@angular/common"; -import { Component, ElementRef, Input, OnChanges, OnInit, SimpleChanges, ViewChild, inject } from "@angular/core"; -import { Timeline } from "vis-timeline"; -import { DatabaseRequest, InstanceEnvironment, InstanceMainSession, InstanceRestSession, LocalRequest, RestRequest } from "src/app/model/trace.model"; +import {DatePipe} from "@angular/common"; +import {Component, ElementRef, inject, Input, OnChanges, SimpleChanges, ViewChild} from "@angular/core"; +import {Timeline} from "vis-timeline"; +import { + DatabaseRequest, + InstanceEnvironment, + InstanceMainSession, + InstanceRestSession, + LocalRequest, + RestRequest +} from "src/app/model/trace.model"; import {EnvRouter} from "../../../../../service/router.service"; @Component({ @@ -28,10 +35,8 @@ export class TimelineComponent implements OnChanges { let dataArray: any = [...this.request.requests, ...this.request.queries, ...this.request.stages.map((s: any) => ({ ...s, isStage: true }))]; - dataArray.splice(0, 0, { ...this.request, isStage: true }) + dataArray.splice(0, 0, { ...this.request, isStage: true }); this.sortInnerArrayByDate(dataArray); - - let data: any; let groups: any; let isWebapp = false, title = ''; @@ -49,14 +54,14 @@ export class TimelineComponent implements OnChanges { } data = dataArray.map((c: any, i: number) => { let o = { - id: c.id ?? -1, + id: c.id ?? `${c.idRequest}_no_session`, group: isWebapp ? 0 : c.threadName, - content: c.hasOwnProperty('isStage') ? '' : (c.schema || c.host || 'N/A'), + content: c.hasOwnProperty('isStage') ? '' : (c.name || c.host || 'N/A'), start: c.start * 1000, end: c.end * 1000, title: `${this.pipe.transform(new Date(c.start * 1000), 'HH:mm:ss.SSS')} - ${this.pipe.transform(new Date(c.end * 1000), 'HH:mm:ss.SSS')}

${c[title]}: ${this.getElapsedTime(c.end, c.start).toFixed(3)}s

`, - className: c.hasOwnProperty('schema') ? "bdd" : !c.hasOwnProperty('isStage') ? "rest" : "", + className: c.hasOwnProperty('name') ? "bdd" : !c.hasOwnProperty('isStage') ? "rest" : "", type: c.hasOwnProperty('isStage') ? 'background' : 'range' } if (o.end > timeline_end) { @@ -64,8 +69,6 @@ export class TimelineComponent implements OnChanges { } return o; }) - - console.log(data, dataArray) if (this.timeline) { // destroy if exists this.timeline.destroy(); } @@ -89,20 +92,22 @@ export class TimelineComponent implements OnChanges { }); let that = this; - this.timeline.on('click', function (props: any) { + this.timeline.on('doubleClick', function (props: any) { let id = props.item; - console.log('test', props) - if (isNaN(id)) { - that._router.navigate(['session', 'rest', id]); - } else { - if(id != -1) + if(id) { + if (isNaN(id)) { + if(id.lastIndexOf('_no_session') == -1) { + that._router.navigate(['session', 'rest', id]); + } + } else { that._router.navigate(['session', 'rest', that.request.id, 'database', id]); + } } + }); if (timeline_end != +this.request.end * 1000) { this.timeline.addCustomTime(+this.request.end * 1000, "async"); - } } } diff --git a/src/app/views/detail/session/main/main.component.html b/src/app/views/detail/session/main/main.component.html index ea40dff..9f78495 100644 --- a/src/app/views/detail/session/main/main.component.html +++ b/src/app/views/detail/session/main/main.component.html @@ -20,12 +20,11 @@ -
- warning - {{ session.exception?.message || session.exception?.type }} + warning +
{{ session.exception?.message || session.exception?.type }}
@@ -84,38 +83,77 @@
-
- -
- west -
REST
+
+ +
+ call_made +
API
- +
+ (onClickRow)="selectedRequest($event)"> +
+
+
+ +
+ smb_share +
FTP
+
+ +
+ + +
+
+
+ +
+ outgoing_mail +
SMTP
+
+ +
+ + +
+
+
+ +
+ user_attributes +
LDAP
+
+ +
+ +
-
- -
+
+ +
Database -
Base de - donnée
+
BDD
- +
+ (onClickRow)="selectedQuery($event)"> +
-
- -
+
+ +
view_timeline Chronologie
- +
diff --git a/src/app/views/detail/session/main/main.component.ts b/src/app/views/detail/session/main/main.component.ts index 7f2797a..7c07aa1 100644 --- a/src/app/views/detail/session/main/main.component.ts +++ b/src/app/views/detail/session/main/main.component.ts @@ -19,7 +19,6 @@ export class MainComponent implements OnInit, OnDestroy { session: InstanceMainSession; instance: InstanceEnvironment; - sessionParent: { id: string, type: string }; isLoading: boolean = false; subscriptions: Array = []; queryBySchema: any[]; @@ -46,10 +45,12 @@ export class MainComponent implements OnInit, OnDestroy { return forkJoin({ session: of(s), instance: this._traceService.getInstance(s.instanceId), - parent: this._traceService.getSessionParent(id).pipe(catchError(() => of(null))), requests: this._traceService.getRestRequests(s.id), queries: this._traceService.getDatabaseRequests(s.id), - stages: this._traceService.getLocalRequests(s.id) + stages: this._traceService.getLocalRequests(s.id), + ftps: this._traceService.getFtpRequests(s.id), + mails: this._traceService.getSmtpRequests(s.id), + ldaps: this._traceService.getLdapRequests(s.id) }); }), finalize(() => this.isLoading = false) @@ -61,8 +62,10 @@ export class MainComponent implements OnInit, OnDestroy { this.session.requests = result.requests; this.session.queries = result.queries; this.session.stages = result.stages; + this.session.ftpRequests = result.ftps; + this.session.mailRequests = result.mails; + this.session.ldapRequests = result.ldaps; this.instance = result.instance; - this.sessionParent = result.parent; this.groupQueriesBySchema(); } } @@ -85,9 +88,45 @@ export class MainComponent implements OnInit, OnDestroy { console.log(event) if (event.row) { if (event.event.ctrlKey) { - this._router.open(`#/session/rest/${event.row}`, '_blank',) + this._router.open(`#/session/main/${event.row}`, '_blank',) } else { - this._router.navigate(['/session', 'rest', event.row], { queryParams: { env: this.env } }); // TODO remove env FIX BUG + this._router.navigate(['/session', 'main', event.row], { queryParams: { env: this.env } }); // TODO remove env FIX BUG + } + } + } + + selectedFtp(event: { event: MouseEvent, row: any }) { // TODO finish this + if (event.row) { + if (event.event.ctrlKey) { + this._router.open(`#/session/main/${this.session.id}/ftp/${event.row}`, '_blank',) + } else { + this._router.navigate(['/session/main', this.session.id, 'ftp', event.row], { + queryParams: { env: this.instance.env } + }); + } + } + } + + selectedLdap(event: { event: MouseEvent, row: any }) { // TODO finish this + if (event.row) { + if (event.event.ctrlKey) { + this._router.open(`#/session/main/${this.session.id}/ldap/${event.row}`, '_blank',) + } else { + this._router.navigate(['/session/main', this.session.id, 'ldap', event.row], { + queryParams: { env: this.instance.env } + }); + } + } + } + + selectedSmtp(event: { event: MouseEvent, row: any }) { // TODO finish this + if (event.row) { + if (event.event.ctrlKey) { + this._router.open(`#/session/main/${this.session.id}/smtp/${event.row}`, '_blank',) + } else { + this._router.navigate(['/session/main', this.session.id, 'smtp', event.row], { + queryParams: { env: this.instance.env } + }); } } } @@ -116,8 +155,6 @@ export class MainComponent implements OnInit, OnDestroy { case "tree": params.push('session', 'main', this.session.type, this.session.id, 'tree') break; - case "parent": - params.push('session', this.sessionParent.type, this.sessionParent.id) } if (event.ctrlKey) { this._router.open(`#/${params.join('/')}`, '_blank') diff --git a/src/app/views/detail/session/rest/rest.component.html b/src/app/views/detail/session/rest/rest.component.html index 4aa6782..f3d268f 100644 --- a/src/app/views/detail/session/rest/rest.component.html +++ b/src/app/views/detail/session/rest/rest.component.html @@ -28,12 +28,11 @@
-
- warning - {{ session.exception?.message || session.exception?.type }} + warning +
{{ session.exception?.message || session.exception?.type }}
@@ -102,38 +101,77 @@
-
- -
+
+ +
call_made
API
- +
+ (onClickRow)="selectedRequest($event)"> +
+
+
+ +
+ smb_share +
FTP
+
+ +
+ + +
+
+
+ +
+ outgoing_mail +
SMTP
+
+ +
+ + +
+
+
+ +
+ user_attributes +
LDAP
+
+ +
+ +
-
- -
+
+ +
Database -
Base de donnée
+
BDD
- +
+ (onClickRow)="selectedQuery($event)">
-
- -
+
+ +
view_timeline Chronologie
- +
diff --git a/src/app/views/detail/session/rest/rest.component.ts b/src/app/views/detail/session/rest/rest.component.ts index f421698..7d4ad09 100644 --- a/src/app/views/detail/session/rest/rest.component.ts +++ b/src/app/views/detail/session/rest/rest.component.ts @@ -52,7 +52,9 @@ export class RestComponent implements OnInit, OnDestroy { requests: this._traceService.getRestRequests(s.id), queries: this._traceService.getDatabaseRequests(s.id), stages: this._traceService.getLocalRequests(s.id), - ftps: this._traceService.getFtpRequests(s.id) + ftps: this._traceService.getFtpRequests(s.id), + mails: this._traceService.getSmtpRequests(s.id), + ldaps: this._traceService.getLdapRequests(s.id) }); }), finalize(() => this.isLoading = false) @@ -64,6 +66,8 @@ export class RestComponent implements OnInit, OnDestroy { this.session.queries = result.queries; this.session.stages = result.stages; this.session.ftpRequests = result.ftps; + this.session.mailRequests = result.mails; + this.session.ldapRequests = result.ldaps; this.instance = result.instance; this.sessionParent = result.parent; this.groupQueriesBySchema(); @@ -82,6 +86,43 @@ export class RestComponent implements OnInit, OnDestroy { } } + selectedFtp(event: { event: MouseEvent, row: any }) { // TODO finish this + if (event.row) { + if (event.event.ctrlKey) { + this._router.open(`#/session/rest/${this.session.id}/ftp/${event.row}`, '_blank',) + } else { + this._router.navigate(['/session/rest', this.session.id, 'ftp', event.row], { + queryParams: { env: this.instance.env } + }); + } + } + } + + selectedLdap(event: { event: MouseEvent, row: any }) { // TODO finish this + if (event.row) { + if (event.event.ctrlKey) { + this._router.open(`#/session/rest/${this.session.id}/ldap/${event.row}`, '_blank',) + } else { + this._router.navigate(['/session/rest', this.session.id, 'ldap', event.row], { + queryParams: { env: this.instance.env } + }); + } + } + } + + selectedSmtp(event: { event: MouseEvent, row: any }) { // TODO finish this + console.log(event) + if (event.row) { + if (event.event.ctrlKey) { + this._router.open(`#/session/rest/${this.session.id}/smtp/${event.row}`, '_blank',) + } else { + this._router.navigate(['/session/rest', this.session.id, 'smtp', event.row], { + queryParams: { env: this.instance.env } + }); + } + } + } + selectedQuery(event: { event: MouseEvent, row: any }) { // TODO finish this if (event.row) { if (event.event.ctrlKey) { diff --git a/src/app/views/detail/smtp/smtp.component.html b/src/app/views/detail/smtp/smtp.component.html new file mode 100644 index 0000000..11bce43 --- /dev/null +++ b/src/app/views/detail/smtp/smtp.component.html @@ -0,0 +1,113 @@ +
+ + +
+ outgoing_mail + {{ request.host + ':' + request.port || 'N/A' }} +
+ +
+ +
+
+ +
+
+ warning{{exception.message}} +
+
+
+ + person +
+ {{request.user || "N/A"}} le {{( request.start*1000 ) | date: 'dd/MM/yyyy à HH:mm:ss.SSS': 'fr' }} + en {{{ start: request.start, end: request.end } | duration}} +
+
+
+
+ + +
+
+ +
+ view_timeline + Chronologie +
+ +
+
+
+ +
+
+ +
+ attach_email + Mails +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + subject + Objet + + + {{ element.subject }} + De +
+ + {{ f }} + +
+
A +
+ + {{ f }} + +
+
Cc +
+ + {{ f }} + +
+
+
+
+ + +
+ Chargement en cours... +
diff --git a/src/app/views/detail/smtp/smtp.component.scss b/src/app/views/detail/smtp/smtp.component.scss new file mode 100644 index 0000000..f93b4e5 --- /dev/null +++ b/src/app/views/detail/smtp/smtp.component.scss @@ -0,0 +1,75 @@ +.header-card { + display: flex; + flex-direction: row; + gap: 0.5em; + margin-bottom: 2em; +} + +a { + color: inherit; + text-decoration: none; +} + +mat-card-title { + display: flex; + align-items: center; + padding: 0 16px; + height: 48px; + .right { + margin-left: auto; + } +} + +mat-card-content { + height: 100%; padding: 0 16px 16px; +} + +mat-card-footer { + padding: 0 16px; + border: 1px solid rgba(0,0,0,.05); + display: flex; + align-items: center; + gap: 0.5em; + font-style: italic; + font-size: 14px; + .right { + margin-left: auto; + display: flex; + align-items: center; + } +} + + +table { + table-layout: auto; +} +.dbfailed { + background-color: red !important; +} + +.progress { + height: 20px; + display: flex; +} + +.progress-bar { + justify-content: center; + overflow: hidden; + color: #fff; + text-align: center; + white-space: nowrap; +} + +.url { + color: blue; + text-decoration: solid; +} + +.success { + border-left: 4px solid green; +} + +.fail { + border-left: 4px solid red; +} + diff --git a/src/app/views/detail/smtp/smtp.component.ts b/src/app/views/detail/smtp/smtp.component.ts new file mode 100644 index 0000000..9c0f34c --- /dev/null +++ b/src/app/views/detail/smtp/smtp.component.ts @@ -0,0 +1,121 @@ +import {Component, ElementRef, inject, OnDestroy, OnInit, ViewChild} from "@angular/core"; +import {ActivatedRoute} from "@angular/router"; +import {TraceService} from "../../../service/trace.service"; +import {DataItem, Timeline} from "vis-timeline"; +import {combineLatest, finalize, forkJoin, Subscription} from "rxjs"; +import { + ExceptionInfo, Mail, + MailRequest, + MailRequestStage, + NamingRequest, + NamingRequestStage +} from "../../../model/trace.model"; +import {DatePipe} from "@angular/common"; +import {application} from "../../../../environments/environment"; +import {EnvRouter} from "../../../service/router.service"; +import {DurationPipe} from "../../../shared/pipe/duration.pipe"; +import {MatTableDataSource} from "@angular/material/table"; + +@Component({ + templateUrl: './smtp.component.html', + styleUrls: ['./smtp.component.scss'], +}) +export class SmtpComponent implements OnInit, OnDestroy { + private _activatedRoute: ActivatedRoute = inject(ActivatedRoute); + private _traceService: TraceService = inject(TraceService); + private _router: EnvRouter = inject(EnvRouter); + + private timeLine: Timeline; + private subscription: Subscription[] = []; + private params: Partial<{idSession: string, idSmtp: number, typeSession: string, typeMain: string, env: string}> = {}; + private pipe = new DatePipe('fr-FR'); + private durationPipe = new DurationPipe(); + + request: MailRequest; + exception: ExceptionInfo; + isLoading: boolean; + + displayedColumns: string[] = ['subject', 'from', 'recipients', 'replyTo']; + dataSource: MatTableDataSource = new MatTableDataSource(); + + @ViewChild('timeline') timelineContainer: ElementRef; + + ngOnInit() { + this.subscription.push(combineLatest([ + this._activatedRoute.params, + this._activatedRoute.data, + this._activatedRoute.queryParams + ]).subscribe({ + next: ([params, data, queryParams]) => { + this.params = {idSession: params.id_session, idSmtp: params.id_smtp, + typeSession: data.type, typeMain: params.type_main, env: queryParams.env || application.default_env}; + this.getRequest(); + } + })); + } + + ngOnDestroy() { + this.subscription.forEach(s => s.unsubscribe()); + this.timeLine.destroy(); + } + + getRequest() { + this.isLoading = true; + this.subscription.push(forkJoin({ + request: this._traceService.getSmtpRequests(this.params.idSession, this.params.idSmtp), + stages: this._traceService.getSmtpRequestStages(this.params.idSession, this.params.idSmtp), + mails: this._traceService.getSmtpRequestMails(this.params.idSession, this.params.idSmtp) + }).pipe(finalize(() => this.isLoading = false)).subscribe({ + next: (value: {request: MailRequest, stages: MailRequestStage[], mails: Mail[]}) => { + this.request = value.request; + this.request.actions = value.stages; + this.request.mails = value.mails; + this.exception = value.stages.find(s => s.exception?.type || s.exception?.message)?.exception; + this.dataSource = new MatTableDataSource(this.request.mails); + this.createTimeline(); + } + })); + } + + createTimeline() { + let timeline_start = Math.trunc(this.request.start * 1000); + let timeline_end = Math.ceil(this.request.end * 1000); + let actions = this.request.actions.sort((a, b) => a.order - b.order); + + let items = actions.map(a => { + let item: DataItem = { + group: a.order, + start: Math.trunc(a.start * 1000), + end: Math.trunc(a.end * 1000), + content: '', + title: `${this.pipe.transform(new Date(a.start * 1000), 'HH:mm:ss.SSS')} - ${this.pipe.transform(new Date(a.end * 1000), 'HH:mm:ss.SSS')} (${this.durationPipe.transform({start: a.start, end: a.end})})
` + } + item.type = item.end <= item.start ? 'point' : 'range'; + if (a?.exception?.message || a?.exception?.type) { + item.className = 'bdd-failed'; + } + return item; + }); + + this.timeLine = new Timeline(this.timelineContainer.nativeElement, items, actions.map(a => ({ id: a.order, content: a?.name })), { + min: timeline_start, + max: timeline_end + }); + } + + navigate(event: MouseEvent, targetType: string, extraParam?: string) { + let params: any[] = []; + switch (targetType) { + case "parent": + if(this.params.typeMain) params.push('session', this.params.typeSession, this.params.typeMain, this.params.idSession); + else params.push('session', this.params.typeSession, this.params.idSession); + } + if (event.ctrlKey) { + this._router.open(`#/${params.join('/')}`, '_blank') + } else { + this._router.navigate(params, { + queryParams: {env: this.params.env} + }); + } + } +} \ No newline at end of file diff --git a/src/app/views/search/main/main.component.html b/src/app/views/search/main/main.component.html index 902ca02..0686838 100644 --- a/src/app/views/search/main/main.component.html +++ b/src/app/views/search/main/main.component.html @@ -88,11 +88,11 @@ Début
- {{ (row.start * 1000 |date:'dd/MM/yyyy') }} + {{ (row.start * 1000 | date:'dd/MM/yyyy') }}

- {{ (row.start * 1000 |date:'HH:mm:ss.SSS') }} + {{ (row.start * 1000 | date:'HH:mm:ss.SSS') }}
@@ -103,7 +103,7 @@
- {{ getElapsedTime(row.end, row.start) | duration }}
+ {{ { start: row.start, end: row.end } | duration }}
diff --git a/src/app/views/search/main/main.component.ts b/src/app/views/search/main/main.component.ts index b736803..06ff2df 100644 --- a/src/app/views/search/main/main.component.ts +++ b/src/app/views/search/main/main.component.ts @@ -1,243 +1,234 @@ -import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core'; -import { FormControl, FormGroup, Validators } from '@angular/forms'; -import { MatPaginator } from '@angular/material/paginator'; -import { MatSort } from '@angular/material/sort'; -import { MatTableDataSource } from '@angular/material/table'; -import { ActivatedRoute, Params, Router } from '@angular/router'; -import {BehaviorSubject, combineLatest, Subscription} from 'rxjs'; -import { Location } from '@angular/common'; -import { Utils } from 'src/app/shared/util'; -import { TraceService } from 'src/app/service/trace.service'; -import { application, makePeriod } from 'src/environments/environment'; +import {Component, OnDestroy, OnInit, ViewChild} from '@angular/core'; +import {FormControl, FormGroup, Validators} from '@angular/forms'; +import {MatPaginator} from '@angular/material/paginator'; +import {MatSort} from '@angular/material/sort'; +import {MatTableDataSource} from '@angular/material/table'; +import {ActivatedRoute} from '@angular/router'; +import {combineLatest, Subscription} from 'rxjs'; +import {Location} from '@angular/common'; +import {Utils} from 'src/app/shared/util'; +import {TraceService} from 'src/app/service/trace.service'; +import {application, makePeriod} from 'src/environments/environment'; import {Constants, FilterConstants, FilterMap, FilterPreset} from '../../constants'; -import { FilterService } from 'src/app/service/filter.service'; -import {InstanceMainSession, InstanceRestSession} from 'src/app/model/trace.model'; +import {FilterService} from 'src/app/service/filter.service'; +import {InstanceMainSession} from 'src/app/model/trace.model'; import {EnvRouter} from "../../../service/router.service"; @Component({ - templateUrl: './main.component.html', - styleUrls: ['./main.component.scss'], + templateUrl: './main.component.html', + styleUrls: ['./main.component.scss'], }) export class MainComponent implements OnInit, OnDestroy { - MAPPING_TYPE = Constants.MAPPING_TYPE; - filterConstants = FilterConstants; - utils: Utils = new Utils(); - displayedColumns: string[] = ['status', 'app_name', 'name', 'location', 'start', 'durée', 'user']; - dataSource: MatTableDataSource = new MatTableDataSource(); - serverFilterForm = new FormGroup({ - dateRangePicker: new FormGroup({ - start: new FormControl(null, [Validators.required]), - end: new FormControl(null, [Validators.required]), - }) - }); - subscription: Subscription; - isLoading = false; - advancedParams: Partial<{[key:string]:any}> - focusFieldName: any - filterTable = new Map(); - filter: string = ''; - params: Partial<{ env: string, start: Date, end: Date, type: string }> = {}; - - @ViewChild(MatPaginator) paginator: MatPaginator; - @ViewChild(MatSort) sort: MatSort; - - constructor(private _router: EnvRouter, - private _traceService: TraceService, - private _activatedRoute: ActivatedRoute, - private _location: Location, - private _filter: FilterService) { - - combineLatest([ - this._activatedRoute.params, - this._activatedRoute.queryParams - ]).subscribe({ - next: ([params, queryParams]) => { - this.params.env = queryParams['env'] || application.default_env; - - this.params.type = params['type_main']; - this.params.start = queryParams['start'] ? new Date(queryParams['start']) : (application.session.main.default_period || makePeriod(0, 1)).start; - this.params.end = queryParams['end'] ? new Date(queryParams['end']) : (application.session.main.default_period || makePeriod(0, 1)).end; - this.patchDateValue(this.params.start, new Date(this.params.end.getFullYear(), this.params.end.getMonth(), this.params.end.getDate() - 1)); - this.getMainRequests(); - this._location.replaceState(`${this._router.url.split('?')[0]}?env=${this.params.env}&start=${this.params.start.toISOString()}&end=${this.params.end.toISOString()}`) + MAPPING_TYPE = Constants.MAPPING_TYPE; + filterConstants = FilterConstants; + utils: Utils = new Utils(); + displayedColumns: string[] = ['status', 'app_name', 'name', 'location', 'start', 'durée', 'user']; + dataSource: MatTableDataSource = new MatTableDataSource(); + serverFilterForm = new FormGroup({ + dateRangePicker: new FormGroup({ + start: new FormControl(null, [Validators.required]), + end: new FormControl(null, [Validators.required]), + }) + }); + subscription: Subscription; + isLoading = false; + advancedParams: Partial<{ [key: string]: any }> + focusFieldName: any + filterTable = new Map(); + filter: string = ''; + params: Partial<{ env: string, start: Date, end: Date, type: string }> = {}; + + @ViewChild(MatPaginator) paginator: MatPaginator; + @ViewChild(MatSort) sort: MatSort; + + constructor(private _router: EnvRouter, + private _traceService: TraceService, + private _activatedRoute: ActivatedRoute, + private _location: Location, + private _filter: FilterService) { + + combineLatest([ + this._activatedRoute.params, + this._activatedRoute.queryParams + ]).subscribe({ + next: ([params, queryParams]) => { + this.params.env = queryParams['env'] || application.default_env; + + this.params.type = params['type_main']; + this.params.start = queryParams['start'] ? new Date(queryParams['start']) : (application.session.main.default_period || makePeriod(0, 1)).start; + this.params.end = queryParams['end'] ? new Date(queryParams['end']) : (application.session.main.default_period || makePeriod(0, 1)).end; + this.patchDateValue(this.params.start, new Date(this.params.end.getFullYear(), this.params.end.getMonth(), this.params.end.getDate() - 1)); + this.getMainRequests(); + this._location.replaceState(`${this._router.url.split('?')[0]}?env=${this.params.env}&start=${this.params.start.toISOString()}&end=${this.params.end.toISOString()}`) + } + }); + } + + + ngOnInit(): void { + + } + + ngOnDestroy(): void { + this.subscription.unsubscribe(); + } + + getMainRequests() { + let params = { + 'env': this.params.env, + 'launchmode': this.params.type.toUpperCase(), + 'start': this.params.start.toISOString(), + 'end': this.params.end.toISOString(), + 'lazy': false + }; + if (this.advancedParams) { + Object.assign(params, this.advancedParams); } - }); - } - - - ngOnInit(): void { - - } - - ngOnDestroy(): void { - this.subscription.unsubscribe(); - } - - getMainRequests() { - let params = { - 'env': this.params.env, - 'launchmode': this.params.type.toUpperCase(), - 'start': this.params.start.toISOString(), - 'end': this.params.end.toISOString(), - 'lazy': false - }; - if(this.advancedParams){ - Object.assign(params, this.advancedParams); - } - - this.isLoading = true; - this.dataSource.data = []; - this.subscription = this._traceService.getMainSessions(params).subscribe((d: InstanceMainSession[]) => { - if (d) { - this.dataSource = new MatTableDataSource(d); - this.dataSource.paginator = this.paginator; - this.dataSource.sort = this.sort - this.dataSource.sortingDataAccessor = (row: any, columnName: string) => { - if (columnName == "app_name") return row["appName"] as string; - if (columnName == "name") return row["name"] as string; - if (columnName == "location") return row['location'] as string; - if (columnName == "start") return row['start'] as string; - if (columnName == "durée") return (row["end"] - row["start"]) - - var columnValue = row[columnName as keyof any] as string; - return columnValue; + + this.isLoading = true; + this.dataSource.data = []; + this.subscription = this._traceService.getMainSessions(params).subscribe((d: InstanceMainSession[]) => { + if (d) { + this.dataSource = new MatTableDataSource(d); + this.dataSource.paginator = this.paginator; + this.dataSource.sort = this.sort + this.dataSource.sortingDataAccessor = (row: any, columnName: string) => { + if (columnName == "app_name") return row["appName"] as string; + if (columnName == "name") return row["name"] as string; + if (columnName == "location") return row['location'] as string; + if (columnName == "start") return row['start'] as string; + if (columnName == "durée") return (row["end"] - row["start"]) + + var columnValue = row[columnName as keyof any] as string; + return columnValue; + } + this.dataSource.filterPredicate = (data: InstanceMainSession, filter: string) => { + var map: Map = new Map(JSON.parse(filter)); + let isMatch = true; + for (let [key, value] of map.entries()) { + if (key == 'filter') { + isMatch = isMatch && (value == '' || (data.appName?.toLowerCase().includes(value) || + data.name?.toLowerCase().includes(value) || data.location?.toLowerCase().includes(value) || + data.user?.toLowerCase().includes(value))); + } else if (key == 'status') { + const s = data.exception?.type || data.exception?.message ? "KO" : "OK"; + isMatch = isMatch && (!value.length || (value.some((status: any) => { + return s == status; + }))); + } + } + return isMatch; + } + this.dataSource.filter = JSON.stringify(Array.from(this.filterTable.entries())); + this.dataSource.paginator.pageIndex = 0; + this.isLoading = false; + } + }, error => { + this.isLoading = false; + }) + } + + + search() { + if (this.serverFilterForm.valid) { + let start = this.serverFilterForm.getRawValue().dateRangePicker.start; + let end = this.serverFilterForm.getRawValue().dateRangePicker.end + let excludedEnd = new Date(end.getFullYear(), end.getMonth(), end.getDate() + 1) + if (this.params.start.toISOString() != start.toISOString() + || this.params.end.toISOString() != excludedEnd.toISOString()) { + this._router.navigate([], { + relativeTo: this._activatedRoute, + queryParamsHandling: 'merge', + queryParams: {start: start.toISOString(), end: excludedEnd.toISOString()} + }) + } else { + this.getMainRequests(); + } } - this.dataSource.filterPredicate = (data: InstanceMainSession, filter: string) => { - var map: Map = new Map(JSON.parse(filter)); - let isMatch = true; - for (let [key, value] of map.entries()) { - if (key == 'filter') { - isMatch = isMatch && (value == '' || (data.appName?.toLowerCase().includes(value) || - data.name?.toLowerCase().includes(value) || data.location?.toLowerCase().includes(value) || - data.user?.toLowerCase().includes(value))); - } else if (key == 'status') { - const s = data.exception?.type || data.exception?.message ? "KO" : "OK"; - isMatch = isMatch && (!value.length || (value.some((status: any) => { - return s == status; - }))); + } + + patchDateValue(start: Date, end: Date) { + this.serverFilterForm.patchValue({ + dateRangePicker: { + start: start, + end: end } - } - return isMatch; + }, {emitEvent: false}); + } + + selectedRequest(event: MouseEvent, row: any) { + console.log(row) + if (event.ctrlKey) { + this._router.open(`#/session/main/${row.type.toLowerCase()}/${row.id}`, '_blank') + } else { + this._router.navigate(['/session/main', row.type.toLowerCase(), row.id], { + queryParams: {'env': this.params.env} + }); } + } + + applyFilter(event: Event) { + const filterValue = (event.target as HTMLInputElement).value; + this.filterTable.set('filter', filterValue.trim().toLowerCase()); this.dataSource.filter = JSON.stringify(Array.from(this.filterTable.entries())); - this.dataSource.paginator.pageIndex = 0; - this.isLoading = false; - } - }, error => { - this.isLoading = false; - }) - } - - - search() { - if (this.serverFilterForm.valid) { - let start = this.serverFilterForm.getRawValue().dateRangePicker.start; - let end = this.serverFilterForm.getRawValue().dateRangePicker.end - let excludedEnd = new Date(end.getFullYear(), end.getMonth(), end.getDate() + 1) - if (this.params.start.toISOString() != start.toISOString() - || this.params.end.toISOString() != excludedEnd.toISOString()) { - this._router.navigate([], { - relativeTo: this._activatedRoute, - queryParamsHandling: 'merge', - queryParams: { start: start.toISOString(), end: excludedEnd.toISOString() } - }) - } else { - this.getMainRequests(); - } - } - } - - patchDateValue(start: Date, end: Date) { - this.serverFilterForm.patchValue({ - dateRangePicker: { - start: start, - end: end - } - }, { emitEvent: false }); - } - - selectedRequest(event: MouseEvent, row: any) { - console.log(row) - if (event.ctrlKey) { - this._router.open(`#/session/main/${row.type.toLowerCase()}/${row.id}`, '_blank') - } else { - this._router.navigate(['/session/main', row.type.toLowerCase(), row.id], { - queryParams: { 'env': this.params.env } - }); - } - } - - getElapsedTime(end: number, start: number,) { - return (new Date(end * 1000).getTime() - new Date(start * 1000).getTime()) / 1000 - } - - statusBorder(status: number) { - return Utils.statusBorder(status) - } - - - applyFilter(event: Event) { - const filterValue = (event.target as HTMLInputElement).value; - this.filterTable.set('filter', filterValue.trim().toLowerCase()); - this.dataSource.filter = JSON.stringify(Array.from(this.filterTable.entries())); - if (this.dataSource.paginator) { - this.dataSource.paginator.firstPage(); - } - } - - toggleFilter(filter: string[]) { - this.filterTable.set('status', filter); - this.dataSource.filter = JSON.stringify(Array.from(this.filterTable.entries())); - } - - resetFilters(){ - this.patchDateValue((application.session.api.default_period || makePeriod(0)).start,(application.session.api.default_period || makePeriod(0, 1)).end); - this.advancedParams = {}; - this._filter.setFilterMap({}) - } - - handlePresetSelection(filterPreset: FilterPreset) { - const formControlNamelist = Object.keys(this.serverFilterForm.controls); - Object.entries(filterPreset.values).reduce((accumulator: any, [key, value]) => { - - if (formControlNamelist.includes(key)) { - this.serverFilterForm.patchValue({ - [key]: value - }) - delete filterPreset.values[key]; - } - },{}) - this.advancedParams = filterPreset.values - this._filter.setFilterMap(this.advancedParams); - this.search() - } - - handlePresetSelectionReset() { - this.resetFilters(); - this.search(); - } - - handleFilterReset(){ - this.resetFilters(); - } - - focusField(fieldName: string) { - this.focusFieldName = [fieldName]; - } - - handledialogclose(filterMap: FilterMap) { - this.advancedParams = filterMap; - this._filter.setFilterMap(this.advancedParams); - this.search() - } - - handleRemovedFilter(filterName: string) { - if(this.advancedParams[filterName]){ - delete this.advancedParams[filterName]; - this._filter.setFilterMap(this.advancedParams); - } - } + if (this.dataSource.paginator) { + this.dataSource.paginator.firstPage(); + } + } + + toggleFilter(filter: string[]) { + this.filterTable.set('status', filter); + this.dataSource.filter = JSON.stringify(Array.from(this.filterTable.entries())); + } + + resetFilters() { + this.patchDateValue((application.session.api.default_period || makePeriod(0)).start, (application.session.api.default_period || makePeriod(0, 1)).end); + this.advancedParams = {}; + this._filter.setFilterMap({}) + } + + handlePresetSelection(filterPreset: FilterPreset) { + const formControlNamelist = Object.keys(this.serverFilterForm.controls); + Object.entries(filterPreset.values).reduce((accumulator: any, [key, value]) => { + + if (formControlNamelist.includes(key)) { + this.serverFilterForm.patchValue({ + [key]: value + }) + delete filterPreset.values[key]; + } + }, {}) + this.advancedParams = filterPreset.values + this._filter.setFilterMap(this.advancedParams); + this.search() + } + + handlePresetSelectionReset() { + this.resetFilters(); + this.search(); + } + + handleFilterReset() { + this.resetFilters(); + } + + focusField(fieldName: string) { + this.focusFieldName = [fieldName]; + } + + handledialogclose(filterMap: FilterMap) { + this.advancedParams = filterMap; + this._filter.setFilterMap(this.advancedParams); + this.search() + } + + handleRemovedFilter(filterName: string) { + if (this.advancedParams[filterName]) { + delete this.advancedParams[filterName]; + this._filter.setFilterMap(this.advancedParams); + } + } } diff --git a/src/app/views/search/rest/rest.component.html b/src/app/views/search/rest/rest.component.html index f80fcdd..649b048 100644 --- a/src/app/views/search/rest/rest.component.html +++ b/src/app/views/search/rest/rest.component.html @@ -105,7 +105,7 @@
{{ getElapsedTime(row.end, row.start) | duration}}
+ matTooltipClass="mat-tooltip">{{ { start: row.start, end: row.end } | duration }}
diff --git a/src/app/views/search/rest/rest.component.ts b/src/app/views/search/rest/rest.component.ts index 768d0b6..9b75ae2 100644 --- a/src/app/views/search/rest/rest.component.ts +++ b/src/app/views/search/rest/rest.component.ts @@ -1,18 +1,18 @@ -import { Component, OnInit, ViewChild, OnDestroy } from '@angular/core'; -import { FormControl, FormGroup, Validators } from '@angular/forms'; -import { MatPaginator } from '@angular/material/paginator'; -import { MatSort } from '@angular/material/sort'; -import { MatTableDataSource } from '@angular/material/table'; -import { Location } from '@angular/common'; -import { ActivatedRoute, Params } from '@angular/router'; -import { BehaviorSubject, Observable, Subscription, finalize } from 'rxjs'; -import { Utils } from 'src/app/shared/util'; -import { JQueryService } from 'src/app/service/jquery.service'; -import { TraceService } from 'src/app/service/trace.service'; -import { application, makePeriod } from 'src/environments/environment'; -import {FilterConstants, FilterPreset, FilterMap, Constants} from '../../constants'; -import { FilterService } from 'src/app/service/filter.service'; -import { InstanceMainSession, InstanceRestSession, RestSession } from 'src/app/model/trace.model'; +import {Component, OnDestroy, OnInit, ViewChild} from '@angular/core'; +import {FormControl, FormGroup, Validators} from '@angular/forms'; +import {MatPaginator} from '@angular/material/paginator'; +import {MatSort} from '@angular/material/sort'; +import {MatTableDataSource} from '@angular/material/table'; +import {Location} from '@angular/common'; +import {ActivatedRoute, Params} from '@angular/router'; +import {BehaviorSubject, finalize, Subscription} from 'rxjs'; +import {Utils} from 'src/app/shared/util'; +import {JQueryService} from 'src/app/service/jquery.service'; +import {TraceService} from 'src/app/service/trace.service'; +import {application, makePeriod} from 'src/environments/environment'; +import {Constants, FilterConstants, FilterMap, FilterPreset} from '../../constants'; +import {FilterService} from 'src/app/service/filter.service'; +import {InstanceRestSession} from 'src/app/model/trace.model'; import {EnvRouter} from "../../../service/router.service"; @@ -144,8 +144,7 @@ export class RestComponent implements OnInit, OnDestroy { if (columnName == "start") return row['start'] as string; if (columnName == "durée") return (row["end"] - row["start"]) - var columnValue = row[columnName as keyof any] as string; - return columnValue; + return row[columnName as keyof any] as string; } this.dataSource.filterPredicate = (data: InstanceRestSession, filter: string) => { @@ -201,10 +200,6 @@ export class RestComponent implements OnInit, OnDestroy { } } - getElapsedTime(end: number, start: number,) { - return (new Date(end * 1000).getTime() - new Date(start * 1000).getTime()) / 1000 - } - statusBorder(status: number) { return Utils.statusBorder(status) diff --git a/src/app/views/views.module.ts b/src/app/views/views.module.ts index 0cf5160..a20d65a 100644 --- a/src/app/views/views.module.ts +++ b/src/app/views/views.module.ts @@ -25,6 +25,11 @@ import {DatabaseTableComponent} from './detail/session/_component/database-table import {TimelineComponent} from './detail/session/_component/timeline/timeline.component'; import {DashboardComponent} from './dashboard/dashboard.component'; import {FtpTableComponent} from "./detail/session/_component/ftp-table/ftp-table.component"; +import {SmtpTableComponent} from "./detail/session/_component/smtp-table/smtp-table.component"; +import {LdapTableComponent} from "./detail/session/_component/ldap-table/ldap-table.component"; +import {FtpComponent as DetailFtpComponent} from "./detail/ftp/ftp.component"; +import {LdapComponent as DetailLdapComponent} from "./detail/ldap/ldap.component"; +import {SmtpComponent as DetailSmtpComponent} from "./detail/smtp/smtp.component"; @NgModule({ imports: [ @@ -45,9 +50,14 @@ import {FtpTableComponent} from "./detail/session/_component/ftp-table/ftp-table DetailSessionRestComponent, DetailSessionMainComponent, DetailDatabaseComponent, + DetailFtpComponent, + DetailLdapComponent, + DetailSmtpComponent, RestTableComponent, DatabaseTableComponent, FtpTableComponent, + SmtpTableComponent, + LdapTableComponent, TimelineComponent, ApplicationComponent, UserComponent, diff --git a/src/styles.scss b/src/styles.scss index e685f1d..3ef20c5 100644 --- a/src/styles.scss +++ b/src/styles.scss @@ -107,14 +107,16 @@ mat-form-field.no-subscript { .vis-item.bdd{ background-color: #008080; //rgb(150, 205, 50); - border-color: #002e2e;//rgb(150, 205, 50); + border-color: #002e2e; //rgb(150, 205, 50); color:white; + cursor: pointer; } .vis-item.bdd-failed{ background-color: red; //rgb(150, 205, 50); border-color: rgb(185, 40, 40);//rgb(150, 205, 50); color:white; + cursor: pointer; } .vis-custom-time { // makes markers not draggable From 0ef918eecbe77a07ab620767c7239099caae9aa9 Mon Sep 17 00:00:00 2001 From: fufuu Date: Wed, 14 Aug 2024 15:47:49 +0200 Subject: [PATCH 054/126] refacto --- src/app/app.module.ts | 60 +++---- src/app/model/trace.model.ts | 2 - src/app/shared/pipe/duration.pipe.ts | 2 +- ...mponent.html => detail-database.view.html} | 2 +- ...mponent.scss => detail-database.view.scss} | 0 ...e.component.ts => detail-database.view.ts} | 6 +- ...tp.component.html => detail-ftp.view.html} | 0 ...tp.component.scss => detail-ftp.view.scss} | 0 .../{ftp.component.ts => detail-ftp.view.ts} | 6 +- ...p.component.html => detail-ldap.view.html} | 0 ...p.component.scss => detail-ldap.view.scss} | 0 ...{ldap.component.ts => detail-ldap.view.ts} | 6 +- ...l => detail-database-table.component.html} | 2 +- ...s => detail-database-table.component.scss} | 0 ....ts => detail-database-table.component.ts} | 11 +- .../_component/detail-session.component.html | 75 ++++++++ .../_component/detail-session.component.ts | 73 ++++++++ .../detail-ftp-table.component.html} | 2 +- ...t.scss => detail-ftp-table.component.scss} | 0 ...onent.ts => detail-ftp-table.component.ts} | 10 +- ....html => detail-ldap-table.component.html} | 2 +- ....scss => detail-ldap-table.component.scss} | 0 ...nent.ts => detail-ldap-table.component.ts} | 10 +- ....html => detail-rest-table.component.html} | 2 +- ....scss => detail-rest-table.component.scss} | 0 ...nent.ts => detail-rest-table.component.ts} | 11 +- .../detail-smtp-table.component.html} | 2 +- ....scss => detail-smtp-table.component.scss} | 0 ...nent.ts => detail-smtp-table.component.ts} | 11 +- ...nt.html => detail-timeline.component.html} | 0 ...nt.scss => detail-timeline.component.scss} | 0 ...ponent.ts => detail-timeline.component.ts} | 75 ++++---- .../main/detail-session-main.view.html | 96 ++++++++++ ...ent.scss => detail-session-main.view.scss} | 0 ...mponent.ts => detail-session-main.view.ts} | 69 +------ .../detail/session/main/main.component.html | 170 ------------------ ...ent.html => detail-session-rest.view.html} | 76 +------- ...ent.scss => detail-session-rest.view.scss} | 0 ...mponent.ts => detail-session-rest.view.ts} | 6 +- ...p.component.html => detail-smtp.view.html} | 0 ...p.component.scss => detail-smtp.view.scss} | 0 ...{smtp.component.ts => detail-smtp.view.ts} | 6 +- ...n.component.html => search-main.view.html} | 0 ...n.component.scss => search-main.view.scss} | 0 ...{main.component.ts => search-main.view.ts} | 8 +- ...t.component.html => search-rest.view.html} | 0 ...t.component.scss => search-rest.view.scss} | 0 ...{rest.component.ts => search-rest.view.ts} | 6 +- ...atistic-dependencies-table.component.html} | 0 ...atistic-dependencies-table.component.scss} | 0 ...statistic-dependencies-table.component.ts} | 6 +- ...statistic-dependents-table.component.html} | 0 ...statistic-dependents-table.component.scss} | 0 ...> statistic-dependents-table.component.ts} | 6 +- ... statistic-exception-table.component.html} | 0 ... statistic-exception-table.component.scss} | 0 ...=> statistic-exception-table.component.ts} | 6 +- ...t.html => statistic-application.view.html} | 0 ...t.scss => statistic-application.view.scss} | 0 ...onent.ts => statistic-application.view.ts} | 6 +- ...nent.html => statistic-database.view.html} | 0 ...nent.scss => statistic-database.view.scss} | 0 ...omponent.ts => statistic-database.view.ts} | 6 +- ...omponent.html => statistic-rest.view.html} | 0 ...omponent.scss => statistic-rest.view.scss} | 0 ...st.component.ts => statistic-rest.view.ts} | 6 +- ...atistic-user-session-table.component.html} | 0 ...atistic-user-session-table.component.scss} | 0 ...statistic-user-session-table.component.ts} | 6 +- ...omponent.html => statistic-user.view.html} | 0 ...omponent.scss => statistic-user.view.scss} | 0 ...er.component.ts => statistic-user.view.ts} | 6 +- .../{tree.component.html => tree.view.html} | 0 .../{tree.component.scss => tree.view.scss} | 0 .../tree/{tree.component.ts => tree.view.ts} | 8 +- src/app/views/views.module.ts | 102 ++++++----- src/index.html | 2 +- 77 files changed, 447 insertions(+), 520 deletions(-) rename src/app/views/detail/database/{database.component.html => detail-database.view.html} (94%) rename src/app/views/detail/database/{database.component.scss => detail-database.view.scss} (100%) rename src/app/views/detail/database/{database.component.ts => detail-database.view.ts} (97%) rename src/app/views/detail/ftp/{ftp.component.html => detail-ftp.view.html} (100%) rename src/app/views/detail/ftp/{ftp.component.scss => detail-ftp.view.scss} (100%) rename src/app/views/detail/ftp/{ftp.component.ts => detail-ftp.view.ts} (96%) rename src/app/views/detail/ldap/{ldap.component.html => detail-ldap.view.html} (100%) rename src/app/views/detail/ldap/{ldap.component.scss => detail-ldap.view.scss} (100%) rename src/app/views/detail/ldap/{ldap.component.ts => detail-ldap.view.ts} (96%) rename src/app/views/detail/session/_component/database-table/{database-table.component.html => detail-database-table.component.html} (96%) rename src/app/views/detail/session/_component/database-table/{database-table.component.scss => detail-database-table.component.scss} (100%) rename src/app/views/detail/session/_component/database-table/{database-table.component.ts => detail-database-table.component.ts} (86%) rename src/app/views/detail/session/_component/{smtp-table/smtp-table.component.html => ftp-table/detail-ftp-table.component.html} (97%) rename src/app/views/detail/session/_component/ftp-table/{ftp-table.component.scss => detail-ftp-table.component.scss} (100%) rename src/app/views/detail/session/_component/ftp-table/{ftp-table.component.ts => detail-ftp-table.component.ts} (86%) rename src/app/views/detail/session/_component/ldap-table/{ldap-table.component.html => detail-ldap-table.component.html} (97%) rename src/app/views/detail/session/_component/ldap-table/{ldap-table.component.scss => detail-ldap-table.component.scss} (100%) rename src/app/views/detail/session/_component/ldap-table/{ldap-table.component.ts => detail-ldap-table.component.ts} (86%) rename src/app/views/detail/session/_component/rest-table/{rest-table.component.html => detail-rest-table.component.html} (98%) rename src/app/views/detail/session/_component/rest-table/{rest-table.component.scss => detail-rest-table.component.scss} (100%) rename src/app/views/detail/session/_component/rest-table/{rest-table.component.ts => detail-rest-table.component.ts} (91%) rename src/app/views/detail/session/_component/{ftp-table/ftp-table.component.html => smtp-table/detail-smtp-table.component.html} (97%) rename src/app/views/detail/session/_component/smtp-table/{smtp-table.component.scss => detail-smtp-table.component.scss} (100%) rename src/app/views/detail/session/_component/smtp-table/{smtp-table.component.ts => detail-smtp-table.component.ts} (85%) rename src/app/views/detail/session/_component/timeline/{timeline.component.html => detail-timeline.component.html} (100%) rename src/app/views/detail/session/_component/timeline/{timeline.component.scss => detail-timeline.component.scss} (100%) rename src/app/views/detail/session/_component/timeline/{timeline.component.ts => detail-timeline.component.ts} (57%) create mode 100644 src/app/views/detail/session/main/detail-session-main.view.html rename src/app/views/detail/session/main/{main.component.scss => detail-session-main.view.scss} (100%) rename src/app/views/detail/session/main/{main.component.ts => detail-session-main.view.ts} (60%) delete mode 100644 src/app/views/detail/session/main/main.component.html rename src/app/views/detail/session/rest/{rest.component.html => detail-session-rest.view.html} (54%) rename src/app/views/detail/session/rest/{rest.component.scss => detail-session-rest.view.scss} (100%) rename src/app/views/detail/session/rest/{rest.component.ts => detail-session-rest.view.ts} (97%) rename src/app/views/detail/smtp/{smtp.component.html => detail-smtp.view.html} (100%) rename src/app/views/detail/smtp/{smtp.component.scss => detail-smtp.view.scss} (100%) rename src/app/views/detail/smtp/{smtp.component.ts => detail-smtp.view.ts} (97%) rename src/app/views/search/main/{main.component.html => search-main.view.html} (100%) rename src/app/views/search/main/{main.component.scss => search-main.view.scss} (100%) rename src/app/views/search/main/{main.component.ts => search-main.view.ts} (97%) rename src/app/views/search/rest/{rest.component.html => search-rest.view.html} (100%) rename src/app/views/search/rest/{rest.component.scss => search-rest.view.scss} (100%) rename src/app/views/search/rest/{rest.component.ts => search-rest.view.ts} (98%) rename src/app/views/statistic/_component/dependencies-table/{dependencies-table.component.html => statistic-dependencies-table.component.html} (100%) rename src/app/views/statistic/_component/dependencies-table/{dependencies-table.component.scss => statistic-dependencies-table.component.scss} (100%) rename src/app/views/statistic/_component/dependencies-table/{dependencies-table.component.ts => statistic-dependencies-table.component.ts} (93%) rename src/app/views/statistic/_component/dependents-table/{dependents-table.component.html => statistic-dependents-table.component.html} (100%) rename src/app/views/statistic/_component/dependents-table/{dependents-table.component.scss => statistic-dependents-table.component.scss} (100%) rename src/app/views/statistic/_component/dependents-table/{dependents-table.component.ts => statistic-dependents-table.component.ts} (93%) rename src/app/views/statistic/_component/exception-table/{exception-table.component.html => statistic-exception-table.component.html} (100%) rename src/app/views/statistic/_component/exception-table/{exception-table.component.scss => statistic-exception-table.component.scss} (100%) rename src/app/views/statistic/_component/exception-table/{exception-table.component.ts => statistic-exception-table.component.ts} (88%) rename src/app/views/statistic/application/{application.component.html => statistic-application.view.html} (100%) rename src/app/views/statistic/application/{application.component.scss => statistic-application.view.scss} (100%) rename src/app/views/statistic/application/{application.component.ts => statistic-application.view.ts} (98%) rename src/app/views/statistic/database/{database.component.html => statistic-database.view.html} (100%) rename src/app/views/statistic/database/{database.component.scss => statistic-database.view.scss} (100%) rename src/app/views/statistic/database/{database.component.ts => statistic-database.view.ts} (98%) rename src/app/views/statistic/rest/{rest.component.html => statistic-rest.view.html} (100%) rename src/app/views/statistic/rest/{rest.component.scss => statistic-rest.view.scss} (100%) rename src/app/views/statistic/rest/{rest.component.ts => statistic-rest.view.ts} (98%) rename src/app/views/statistic/user/_component/session-table/{session-table.component.html => statistic-user-session-table.component.html} (100%) rename src/app/views/statistic/user/_component/session-table/{session-table.component.scss => statistic-user-session-table.component.scss} (100%) rename src/app/views/statistic/user/_component/session-table/{session-table.component.ts => statistic-user-session-table.component.ts} (84%) rename src/app/views/statistic/user/{user.component.html => statistic-user.view.html} (100%) rename src/app/views/statistic/user/{user.component.scss => statistic-user.view.scss} (100%) rename src/app/views/statistic/user/{user.component.ts => statistic-user.view.ts} (98%) rename src/app/views/tree/{tree.component.html => tree.view.html} (100%) rename src/app/views/tree/{tree.component.scss => tree.view.scss} (100%) rename src/app/views/tree/{tree.component.ts => tree.view.ts} (99%) diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 79c24f9..3b375ed 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -13,21 +13,21 @@ import {HttpClientModule} from '@angular/common/http'; import {DatePipe, DecimalPipe, registerLocaleData} from '@angular/common'; import localeFr from '@angular/common/locales/fr'; -import {TreeComponent} from './views/tree/tree.component'; -import {ApplicationComponent as StatisticApplicationComponent} from './views/statistic/application/application.component'; -import {UserComponent as StatisticUserComponent} from './views/statistic/user/user.component'; -import {DatabaseComponent as DetailDatabaseComponent} from './views/detail/database/database.component'; -import {DatabaseComponent as StatisticDatabaseComponent} from './views/statistic/database/database.component'; +import {TreeView} from './views/tree/tree.view'; +import {DetailDatabaseView} from './views/detail/database/detail-database.view'; import {DashboardComponent} from './views/dashboard/dashboard.component'; -import {RestComponent as SearchRestComponent} from "./views/search/rest/rest.component"; -import {RestComponent as StatisticRestComponent} from "./views/statistic/rest/rest.component"; -import {RestComponent as DetailSessionRestComponent} from "./views/detail/session/rest/rest.component"; -import {MainComponent as SearchMainComponent} from './views/search/main/main.component'; -import {MainComponent as DetailSessionMainComponent} from "./views/detail/session/main/main.component"; +import {SearchRestView} from "./views/search/rest/search-rest.view"; +import {SearchMainView} from './views/search/main/search-main.view'; import {EnvRouter} from "./service/router.service"; -import {FtpComponent as DetailFtpComponent} from "./views/detail/ftp/ftp.component"; -import {LdapComponent as DetailLdapComponent} from "./views/detail/ldap/ldap.component"; -import {SmtpComponent as DetailSmtpComponent} from "./views/detail/smtp/smtp.component"; +import {DetailFtpView} from "./views/detail/ftp/detail-ftp.view"; +import {DetailLdapView} from "./views/detail/ldap/detail-ldap.view"; +import {DetailSmtpView as DetailSmtpComponent} from "./views/detail/smtp/detail-smtp.view"; +import {DetailSessionRestView} from "./views/detail/session/rest/detail-session-rest.view"; +import {DetailSessionMainView} from "./views/detail/session/main/detail-session-main.view"; +import {StatisticApplicationView} from "./views/statistic/application/statistic-application.view"; +import {StatisticRestView} from "./views/statistic/rest/statistic-rest.view"; +import {StatisticUserView} from "./views/statistic/user/statistic-user.view"; +import {StatisticDatabaseView} from "./views/statistic/database/statistic-database.view"; registerLocaleData(localeFr, 'fr-FR'); const routes: Route[] = [ @@ -38,7 +38,7 @@ const routes: Route[] = [ children: [ { path: '', - component: SearchRestComponent, + component: SearchRestView, title: 'Recherche Appels REST', }, { @@ -46,25 +46,25 @@ const routes: Route[] = [ children: [ { path: '', - component: DetailSessionRestComponent, + component: DetailSessionRestView, title: 'Detail Appel REST' }, { path: 'database/:id_jdbc', data: { type: 'rest' }, - component: DetailDatabaseComponent, + component: DetailDatabaseView, title: 'Detail Base de donnée' }, { path: 'ftp/:id_ftp', data: { type: 'rest' }, - component: DetailFtpComponent, + component: DetailFtpView, title: 'Detail Ftp' }, { path: 'ldap/:id_ldap', data: { type: 'rest' }, - component: DetailLdapComponent, + component: DetailLdapView, title: 'Detail Ldap' }, { @@ -76,7 +76,7 @@ const routes: Route[] = [ { path: 'tree', data: { type: 'rest' }, - component: TreeComponent, + component: TreeView, title: 'Arbre d\'Appels' }, { path: '**', pathMatch: 'full', redirectTo: `/session/rest/:id_session` } @@ -90,7 +90,7 @@ const routes: Route[] = [ children: [ { path: '', - component: SearchMainComponent, + component: SearchMainView, title: (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => { if (route.paramMap.get('type_main') == 'batch') { return 'Recherche BATCHs'; @@ -105,7 +105,7 @@ const routes: Route[] = [ children: [ { path: '', - component: DetailSessionMainComponent, + component: DetailSessionMainView, title: (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => { if (route.paramMap.get('type_main') == 'batch') { return 'Detail BATCH'; @@ -117,24 +117,24 @@ const routes: Route[] = [ }, { path: 'database/:id_jdbc', - component: DetailDatabaseComponent, + component: DetailDatabaseView, data: { type: 'main' }, title: 'Detail Base de donnée' }, { path: 'ftp/:id_ftp', data: { type: 'main' }, - component: DetailFtpComponent, + component: DetailFtpView, title: 'Detail Ftp' }, { path: 'ldap/:id_ldap', data: { type: 'main' }, - component: DetailLdapComponent, + component: DetailLdapView, title: 'Detail Ldap' }, { - path: 'ldap/:id_smtp', + path: 'smtp/:id_smtp', data: { type: 'main' }, component: DetailSmtpComponent, title: 'Detail Smtp' @@ -142,7 +142,7 @@ const routes: Route[] = [ { path: 'tree', data: { type: 'main' }, - component: TreeComponent, + component: TreeView, title: 'Arbre d\'appels' }, { path: '**', pathMatch: 'full', redirectTo: `/main/:type_main/:id_session` } @@ -159,22 +159,22 @@ const routes: Route[] = [ children: [ { path: 'app/:name', - component: StatisticApplicationComponent, + component: StatisticApplicationView, title: 'Statistiques Serveur' }, { path: 'rest/:name', - component: StatisticRestComponent, + component: StatisticRestView, title: 'Statistiques API' }, { path: 'user/:name', - component: StatisticUserComponent, + component: StatisticUserView, title: 'Statistiques Utilisateur' }, { path: 'database/:name', - component: StatisticDatabaseComponent, + component: StatisticDatabaseView, title: 'Statistiques Base de Donnée' }, { path: '**', pathMatch: 'full', redirectTo: `/session/rest` } diff --git a/src/app/model/trace.model.ts b/src/app/model/trace.model.ts index be93ab3..e64cce3 100644 --- a/src/app/model/trace.model.ts +++ b/src/app/model/trace.model.ts @@ -135,8 +135,6 @@ export interface SessionStage { start: number; end: number; threadName: string; - - duration: number; } export interface ExceptionInfo { diff --git a/src/app/shared/pipe/duration.pipe.ts b/src/app/shared/pipe/duration.pipe.ts index 386d403..3cf02c5 100644 --- a/src/app/shared/pipe/duration.pipe.ts +++ b/src/app/shared/pipe/duration.pipe.ts @@ -10,7 +10,7 @@ export class DurationPipe implements PipeTransform { _decimalPipe = inject(DecimalPipe); transform(value: Period | number, ...args: any[]):string { - if(value == null) return; + if(value == null) return 'N/A'; let time = typeof value == "object" ? value.end - value.start : value; const remainingSeconds = this._decimalPipe.transform(Math.round((time % 60) * 1000) / 1000); diff --git a/src/app/views/detail/database/database.component.html b/src/app/views/detail/database/detail-database.view.html similarity index 94% rename from src/app/views/detail/database/database.component.html rename to src/app/views/detail/database/detail-database.view.html index e2d79bc..f5f4161 100644 --- a/src/app/views/detail/database/database.component.html +++ b/src/app/views/detail/database/detail-database.view.html @@ -28,7 +28,7 @@ person
- {{request.user || "N/A"}} le {{( request.start*1000 ) | date: 'dd/MM/yyyy à HH:mm:ss.SSS': 'fr' }} en {{ { start: request.start, end: request.end } | duration }} + {{request.user || "N/A"}} le {{( request.start*1000 ) | date: 'dd/MM/yyyy à HH:mm:ss.SSS': 'fr' }} en {{{ start: request.start, end: request.end } | duration}}
{{ request.productName }} v.{{ request.productVersion }} diff --git a/src/app/views/detail/database/database.component.scss b/src/app/views/detail/database/detail-database.view.scss similarity index 100% rename from src/app/views/detail/database/database.component.scss rename to src/app/views/detail/database/detail-database.view.scss diff --git a/src/app/views/detail/database/database.component.ts b/src/app/views/detail/database/detail-database.view.ts similarity index 97% rename from src/app/views/detail/database/database.component.ts rename to src/app/views/detail/database/detail-database.view.ts index afc5c20..0df574d 100644 --- a/src/app/views/detail/database/database.component.ts +++ b/src/app/views/detail/database/detail-database.view.ts @@ -20,10 +20,10 @@ import {MatTableDataSource} from "@angular/material/table"; import {DurationPipe} from "../../../shared/pipe/duration.pipe"; @Component({ - templateUrl: './database.component.html', - styleUrls: ['./database.component.scss'], + templateUrl: './detail-database.view.html', + styleUrls: ['./detail-database.view.scss'], }) -export class DatabaseComponent implements OnInit, OnDestroy { +export class DetailDatabaseView implements OnInit, OnDestroy { private _activatedRoute: ActivatedRoute = inject(ActivatedRoute); private _traceService: TraceService = inject(TraceService); private _router: EnvRouter = inject(EnvRouter); diff --git a/src/app/views/detail/ftp/ftp.component.html b/src/app/views/detail/ftp/detail-ftp.view.html similarity index 100% rename from src/app/views/detail/ftp/ftp.component.html rename to src/app/views/detail/ftp/detail-ftp.view.html diff --git a/src/app/views/detail/ftp/ftp.component.scss b/src/app/views/detail/ftp/detail-ftp.view.scss similarity index 100% rename from src/app/views/detail/ftp/ftp.component.scss rename to src/app/views/detail/ftp/detail-ftp.view.scss diff --git a/src/app/views/detail/ftp/ftp.component.ts b/src/app/views/detail/ftp/detail-ftp.view.ts similarity index 96% rename from src/app/views/detail/ftp/ftp.component.ts rename to src/app/views/detail/ftp/detail-ftp.view.ts index 770097e..d886476 100644 --- a/src/app/views/detail/ftp/ftp.component.ts +++ b/src/app/views/detail/ftp/detail-ftp.view.ts @@ -11,10 +11,10 @@ import {Utils} from "../../../shared/util"; import {DurationPipe} from "../../../shared/pipe/duration.pipe"; @Component({ - templateUrl: './ftp.component.html', - styleUrls: ['./ftp.component.scss'], + templateUrl: './detail-ftp.view.html', + styleUrls: ['./detail-ftp.view.scss'], }) -export class FtpComponent implements OnInit, OnDestroy { +export class DetailFtpView implements OnInit, OnDestroy { private _activatedRoute: ActivatedRoute = inject(ActivatedRoute); private _traceService: TraceService = inject(TraceService); private _router: EnvRouter = inject(EnvRouter); diff --git a/src/app/views/detail/ldap/ldap.component.html b/src/app/views/detail/ldap/detail-ldap.view.html similarity index 100% rename from src/app/views/detail/ldap/ldap.component.html rename to src/app/views/detail/ldap/detail-ldap.view.html diff --git a/src/app/views/detail/ldap/ldap.component.scss b/src/app/views/detail/ldap/detail-ldap.view.scss similarity index 100% rename from src/app/views/detail/ldap/ldap.component.scss rename to src/app/views/detail/ldap/detail-ldap.view.scss diff --git a/src/app/views/detail/ldap/ldap.component.ts b/src/app/views/detail/ldap/detail-ldap.view.ts similarity index 96% rename from src/app/views/detail/ldap/ldap.component.ts rename to src/app/views/detail/ldap/detail-ldap.view.ts index 3f51eee..f097b2d 100644 --- a/src/app/views/detail/ldap/ldap.component.ts +++ b/src/app/views/detail/ldap/detail-ldap.view.ts @@ -16,10 +16,10 @@ import {DurationPipe} from "../../../shared/pipe/duration.pipe"; import {EnvRouter} from "../../../service/router.service"; @Component({ - templateUrl: './ldap.component.html', - styleUrls: ['./ldap.component.scss'], + templateUrl: './detail-ldap.view.html', + styleUrls: ['./detail-ldap.view.scss'], }) -export class LdapComponent implements OnInit, OnDestroy { +export class DetailLdapView implements OnInit, OnDestroy { private _activatedRoute: ActivatedRoute = inject(ActivatedRoute); private _traceService: TraceService = inject(TraceService); private _router: EnvRouter = inject(EnvRouter); diff --git a/src/app/views/detail/session/_component/database-table/database-table.component.html b/src/app/views/detail/session/_component/database-table/detail-database-table.component.html similarity index 96% rename from src/app/views/detail/session/_component/database-table/database-table.component.html rename to src/app/views/detail/session/_component/database-table/detail-database-table.component.html index 5b54717..72cab82 100644 --- a/src/app/views/detail/session/_component/database-table/database-table.component.html +++ b/src/app/views/detail/session/_component/database-table/detail-database-table.component.html @@ -42,7 +42,7 @@ - {{(getElapsedTime(element.end,element.start) | duration) || 'N/A'}} + {{{start: element.start, end: element.end} | duration}} diff --git a/src/app/views/detail/session/_component/database-table/database-table.component.scss b/src/app/views/detail/session/_component/database-table/detail-database-table.component.scss similarity index 100% rename from src/app/views/detail/session/_component/database-table/database-table.component.scss rename to src/app/views/detail/session/_component/database-table/detail-database-table.component.scss diff --git a/src/app/views/detail/session/_component/database-table/database-table.component.ts b/src/app/views/detail/session/_component/database-table/detail-database-table.component.ts similarity index 86% rename from src/app/views/detail/session/_component/database-table/database-table.component.ts rename to src/app/views/detail/session/_component/database-table/detail-database-table.component.ts index 6fe9207..77581b1 100644 --- a/src/app/views/detail/session/_component/database-table/database-table.component.ts +++ b/src/app/views/detail/session/_component/database-table/detail-database-table.component.ts @@ -6,10 +6,10 @@ import {DatabaseRequest} from "src/app/model/trace.model"; @Component({ selector: 'database-table', - templateUrl: './database-table.component.html', - styleUrls: ['./database-table.component.scss'] + templateUrl: './detail-database-table.component.html', + styleUrls: ['./detail-database-table.component.scss'] }) -export class DatabaseTableComponent implements OnInit { +export class DetailDatabaseTableComponent implements OnInit { displayedColumns: string[] = ['status', 'host', 'schema', 'start', 'duree']; dataSource: MatTableDataSource = new MatTableDataSource(); @@ -29,10 +29,6 @@ export class DatabaseTableComponent implements OnInit { this.dataSource.sortingDataAccessor = sortingDataAccessor; } - getElapsedTime(end: number, start: number,) { - return end - start; - } - getCommand(commands: string[]): string { let command = "[--]"; if (commands?.length == 1) { @@ -44,7 +40,6 @@ export class DatabaseTableComponent implements OnInit { } selectedQuery(event: MouseEvent, row: number) { - console.log(row) this.onClickRow.emit({event: event, row: row}); } } diff --git a/src/app/views/detail/session/_component/detail-session.component.html b/src/app/views/detail/session/_component/detail-session.component.html index e69de29..12df271 100644 --- a/src/app/views/detail/session/_component/detail-session.component.html +++ b/src/app/views/detail/session/_component/detail-session.component.html @@ -0,0 +1,75 @@ +
+
+ +
+ call_made +
API
+
+ +
+ +
+
+
+ +
+ smb_share +
FTP
+
+ +
+ + +
+
+
+ +
+ outgoing_mail +
SMTP
+
+ +
+ + +
+
+
+ +
+ user_attributes +
LDAP
+
+ +
+ + +
+
+
+ +
+ Database +
BDD
+
+ +
+ + +
+
+
+ +
+ view_timeline + Chronologie +
+ +
+ +
\ No newline at end of file diff --git a/src/app/views/detail/session/_component/detail-session.component.ts b/src/app/views/detail/session/_component/detail-session.component.ts index e69de29..ee00de9 100644 --- a/src/app/views/detail/session/_component/detail-session.component.ts +++ b/src/app/views/detail/session/_component/detail-session.component.ts @@ -0,0 +1,73 @@ +import {Component, inject, Input, OnInit} from "@angular/core"; +import {InstanceEnvironment, InstanceMainSession} from "../../../../model/trace.model"; +import {EnvRouter} from "../../../../service/router.service"; + +@Component({ + selector: 'detail-session', + templateUrl: './detail-session.component.html', + styleUrls: ['./detail-session.component.scss'] +}) +export class DetailSessionComponent { + private _router: EnvRouter = inject(EnvRouter); + + @Input() session: InstanceMainSession; + @Input() instance: InstanceEnvironment; + + selectedRequest(event: { event: MouseEvent, row: any }) { + if (event.row) { + if (event.event.ctrlKey) { + this._router.open(`#/session/main/${event.row}`, '_blank',) + } else { + this._router.navigate(['/session', 'main', event.row], { queryParams: { env: this.instance.env } }); // TODO remove env FIX BUG + } + } + } + + selectedFtp(event: { event: MouseEvent, row: any }) { // TODO finish this + if (event.row) { + if (event.event.ctrlKey) { + this._router.open(`#/session/main/${this.session.id}/ftp/${event.row}`, '_blank',) + } else { + this._router.navigate(['/session/main', this.session.id, 'ftp', event.row], { + queryParams: { env: this.instance.env } + }); + } + } + } + + selectedLdap(event: { event: MouseEvent, row: any }) { // TODO finish this + if (event.row) { + if (event.event.ctrlKey) { + this._router.open(`#/session/main/${this.session.id}/ldap/${event.row}`, '_blank',) + } else { + this._router.navigate(['/session/main', this.session.id, 'ldap', event.row], { + queryParams: { env: this.instance.env } + }); + } + } + } + + selectedSmtp(event: { event: MouseEvent, row: any }) { // TODO finish this + if (event.row) { + if (event.event.ctrlKey) { + this._router.open(`#/session/main/${this.session.id}/smtp/${event.row}`, '_blank',) + } else { + this._router.navigate(['/session/main', this.session.id, 'smtp', event.row], { + queryParams: { env: this.instance.env } + }); + } + } + } + + selectedQuery(event: { event: MouseEvent, row: any }) { // TODO finish this + if (event.row) { + if (event.event.ctrlKey) { + this._router.open(`#/session/main/${this.session.type}/${this.session.id}/database/${event.row}`, '_blank',) + } else { + this._router.navigate(['/session/main', this.session.type, this.session.id, 'database', event.row], { + queryParams: { env: this.instance.env } + }); + } + } + } +} \ No newline at end of file diff --git a/src/app/views/detail/session/_component/smtp-table/smtp-table.component.html b/src/app/views/detail/session/_component/ftp-table/detail-ftp-table.component.html similarity index 97% rename from src/app/views/detail/session/_component/smtp-table/smtp-table.component.html rename to src/app/views/detail/session/_component/ftp-table/detail-ftp-table.component.html index ffb151e..72afa70 100644 --- a/src/app/views/detail/session/_component/smtp-table/smtp-table.component.html +++ b/src/app/views/detail/session/_component/ftp-table/detail-ftp-table.component.html @@ -36,7 +36,7 @@ - {{getElapsedTime(element.end,element.start) | duration }} + {{{start: element.start, end: element.end} | duration }} diff --git a/src/app/views/detail/session/_component/ftp-table/ftp-table.component.scss b/src/app/views/detail/session/_component/ftp-table/detail-ftp-table.component.scss similarity index 100% rename from src/app/views/detail/session/_component/ftp-table/ftp-table.component.scss rename to src/app/views/detail/session/_component/ftp-table/detail-ftp-table.component.scss diff --git a/src/app/views/detail/session/_component/ftp-table/ftp-table.component.ts b/src/app/views/detail/session/_component/ftp-table/detail-ftp-table.component.ts similarity index 86% rename from src/app/views/detail/session/_component/ftp-table/ftp-table.component.ts rename to src/app/views/detail/session/_component/ftp-table/detail-ftp-table.component.ts index adfdd04..401f34b 100644 --- a/src/app/views/detail/session/_component/ftp-table/ftp-table.component.ts +++ b/src/app/views/detail/session/_component/ftp-table/detail-ftp-table.component.ts @@ -6,10 +6,10 @@ import {FtpRequest} from "src/app/model/trace.model"; @Component({ selector: 'ftp-table', - templateUrl: './ftp-table.component.html', - styleUrls: ['./ftp-table.component.scss'] + templateUrl: './detail-ftp-table.component.html', + styleUrls: ['./detail-ftp-table.component.scss'] }) -export class FtpTableComponent implements OnInit { +export class DetailFtpTableComponent implements OnInit { displayedColumns: string[] = ['status', 'host', 'start', 'duree']; dataSource: MatTableDataSource = new MatTableDataSource(); @@ -33,10 +33,6 @@ export class FtpTableComponent implements OnInit { console.log(row) this.onClickRow.emit({event: event, row: row}); } - - getElapsedTime(end: number, start: number,) { - return end - start; - } } const sortingDataAccessor = (row: any, columnName: string) => { diff --git a/src/app/views/detail/session/_component/ldap-table/ldap-table.component.html b/src/app/views/detail/session/_component/ldap-table/detail-ldap-table.component.html similarity index 97% rename from src/app/views/detail/session/_component/ldap-table/ldap-table.component.html rename to src/app/views/detail/session/_component/ldap-table/detail-ldap-table.component.html index ffb151e..72afa70 100644 --- a/src/app/views/detail/session/_component/ldap-table/ldap-table.component.html +++ b/src/app/views/detail/session/_component/ldap-table/detail-ldap-table.component.html @@ -36,7 +36,7 @@ - {{getElapsedTime(element.end,element.start) | duration }} + {{{start: element.start, end: element.end} | duration }} diff --git a/src/app/views/detail/session/_component/ldap-table/ldap-table.component.scss b/src/app/views/detail/session/_component/ldap-table/detail-ldap-table.component.scss similarity index 100% rename from src/app/views/detail/session/_component/ldap-table/ldap-table.component.scss rename to src/app/views/detail/session/_component/ldap-table/detail-ldap-table.component.scss diff --git a/src/app/views/detail/session/_component/ldap-table/ldap-table.component.ts b/src/app/views/detail/session/_component/ldap-table/detail-ldap-table.component.ts similarity index 86% rename from src/app/views/detail/session/_component/ldap-table/ldap-table.component.ts rename to src/app/views/detail/session/_component/ldap-table/detail-ldap-table.component.ts index 7d071b9..a2806cd 100644 --- a/src/app/views/detail/session/_component/ldap-table/ldap-table.component.ts +++ b/src/app/views/detail/session/_component/ldap-table/detail-ldap-table.component.ts @@ -6,10 +6,10 @@ import {NamingRequest} from "src/app/model/trace.model"; @Component({ selector: 'ldap-table', - templateUrl: './ldap-table.component.html', - styleUrls: ['./ldap-table.component.scss'] + templateUrl: './detail-ldap-table.component.html', + styleUrls: ['./detail-ldap-table.component.scss'] }) -export class LdapTableComponent implements OnInit { +export class DetailLdapTableComponent implements OnInit { displayedColumns: string[] = ['status', 'host', 'start', 'duree']; dataSource: MatTableDataSource = new MatTableDataSource(); @@ -34,10 +34,6 @@ export class LdapTableComponent implements OnInit { console.log(row) this.onClickRow.emit({event: event, row: row}); } - - getElapsedTime(end: number, start: number,) { - return end - start; - } } const sortingDataAccessor = (row: any, columnName: string) => { diff --git a/src/app/views/detail/session/_component/rest-table/rest-table.component.html b/src/app/views/detail/session/_component/rest-table/detail-rest-table.component.html similarity index 98% rename from src/app/views/detail/session/_component/rest-table/rest-table.component.html rename to src/app/views/detail/session/_component/rest-table/detail-rest-table.component.html index 44ffe05..e047473 100644 --- a/src/app/views/detail/session/_component/rest-table/rest-table.component.html +++ b/src/app/views/detail/session/_component/rest-table/detail-rest-table.component.html @@ -73,7 +73,7 @@ - {{getElapsedTime(element.end,element.start) | duration }} + {{{start: element.start, end: element.end} | duration }} diff --git a/src/app/views/detail/session/_component/rest-table/rest-table.component.scss b/src/app/views/detail/session/_component/rest-table/detail-rest-table.component.scss similarity index 100% rename from src/app/views/detail/session/_component/rest-table/rest-table.component.scss rename to src/app/views/detail/session/_component/rest-table/detail-rest-table.component.scss diff --git a/src/app/views/detail/session/_component/rest-table/rest-table.component.ts b/src/app/views/detail/session/_component/rest-table/detail-rest-table.component.ts similarity index 91% rename from src/app/views/detail/session/_component/rest-table/rest-table.component.ts rename to src/app/views/detail/session/_component/rest-table/detail-rest-table.component.ts index b6c8ee0..957a02e 100644 --- a/src/app/views/detail/session/_component/rest-table/rest-table.component.ts +++ b/src/app/views/detail/session/_component/rest-table/detail-rest-table.component.ts @@ -6,10 +6,10 @@ import {RestRequest} from "src/app/model/trace.model"; @Component({ selector: 'rest-table', - templateUrl: './rest-table.component.html', - styleUrls: ['./rest-table.component.scss'] + templateUrl: './detail-rest-table.component.html', + styleUrls: ['./detail-rest-table.component.scss'] }) -export class RestTableComponent implements OnInit { +export class DetailRestTableComponent implements OnInit { displayedColumns: string[] = ['status', 'host', 'path', 'start', 'duree']; dataSource: MatTableDataSource = new MatTableDataSource(); filterTable = new Map(); @@ -46,13 +46,8 @@ export class RestTableComponent implements OnInit { } selectedRequest(event: MouseEvent, row: any) { - console.log(row) this.onClickRow.emit({event: event, row: row}); } - - getElapsedTime(end: number, start: number,) { - return end - start; - } } const sortingDataAccessor = (row: any, columnName: string) => { diff --git a/src/app/views/detail/session/_component/ftp-table/ftp-table.component.html b/src/app/views/detail/session/_component/smtp-table/detail-smtp-table.component.html similarity index 97% rename from src/app/views/detail/session/_component/ftp-table/ftp-table.component.html rename to src/app/views/detail/session/_component/smtp-table/detail-smtp-table.component.html index ffb151e..72afa70 100644 --- a/src/app/views/detail/session/_component/ftp-table/ftp-table.component.html +++ b/src/app/views/detail/session/_component/smtp-table/detail-smtp-table.component.html @@ -36,7 +36,7 @@ - {{getElapsedTime(element.end,element.start) | duration }} + {{{start: element.start, end: element.end} | duration }} diff --git a/src/app/views/detail/session/_component/smtp-table/smtp-table.component.scss b/src/app/views/detail/session/_component/smtp-table/detail-smtp-table.component.scss similarity index 100% rename from src/app/views/detail/session/_component/smtp-table/smtp-table.component.scss rename to src/app/views/detail/session/_component/smtp-table/detail-smtp-table.component.scss diff --git a/src/app/views/detail/session/_component/smtp-table/smtp-table.component.ts b/src/app/views/detail/session/_component/smtp-table/detail-smtp-table.component.ts similarity index 85% rename from src/app/views/detail/session/_component/smtp-table/smtp-table.component.ts rename to src/app/views/detail/session/_component/smtp-table/detail-smtp-table.component.ts index b66a20e..94fa4e1 100644 --- a/src/app/views/detail/session/_component/smtp-table/smtp-table.component.ts +++ b/src/app/views/detail/session/_component/smtp-table/detail-smtp-table.component.ts @@ -6,10 +6,10 @@ import {MailRequest} from "src/app/model/trace.model"; @Component({ selector: 'smtp-table', - templateUrl: './smtp-table.component.html', - styleUrls: ['./smtp-table.component.scss'] + templateUrl: './detail-smtp-table.component.html', + styleUrls: ['./detail-smtp-table.component.scss'] }) -export class SmtpTableComponent implements OnInit { +export class DetailSmtpTableComponent implements OnInit { displayedColumns: string[] = ['status', 'host', 'start', 'duree']; dataSource: MatTableDataSource = new MatTableDataSource(); @@ -30,13 +30,8 @@ export class SmtpTableComponent implements OnInit { } selectedRequest(event: MouseEvent, row: any) { - console.log(row) this.onClickRow.emit({event: event, row: row}); } - - getElapsedTime(end: number, start: number,) { - return end - start; - } } const sortingDataAccessor = (row: any, columnName: string) => { diff --git a/src/app/views/detail/session/_component/timeline/timeline.component.html b/src/app/views/detail/session/_component/timeline/detail-timeline.component.html similarity index 100% rename from src/app/views/detail/session/_component/timeline/timeline.component.html rename to src/app/views/detail/session/_component/timeline/detail-timeline.component.html diff --git a/src/app/views/detail/session/_component/timeline/timeline.component.scss b/src/app/views/detail/session/_component/timeline/detail-timeline.component.scss similarity index 100% rename from src/app/views/detail/session/_component/timeline/timeline.component.scss rename to src/app/views/detail/session/_component/timeline/detail-timeline.component.scss diff --git a/src/app/views/detail/session/_component/timeline/timeline.component.ts b/src/app/views/detail/session/_component/timeline/detail-timeline.component.ts similarity index 57% rename from src/app/views/detail/session/_component/timeline/timeline.component.ts rename to src/app/views/detail/session/_component/timeline/detail-timeline.component.ts index 5b6f67b..ab95a17 100644 --- a/src/app/views/detail/session/_component/timeline/timeline.component.ts +++ b/src/app/views/detail/session/_component/timeline/detail-timeline.component.ts @@ -2,40 +2,47 @@ import {DatePipe} from "@angular/common"; import {Component, ElementRef, inject, Input, OnChanges, SimpleChanges, ViewChild} from "@angular/core"; import {Timeline} from "vis-timeline"; import { - DatabaseRequest, + DatabaseRequest, FtpRequest, InstanceEnvironment, InstanceMainSession, InstanceRestSession, - LocalRequest, + LocalRequest, MailRequest, NamingRequest, RestRequest } from "src/app/model/trace.model"; import {EnvRouter} from "../../../../../service/router.service"; +import {DurationPipe} from "../../../../../shared/pipe/duration.pipe"; +import {ActivatedRoute} from "@angular/router"; @Component({ selector: 'timeline-table', - templateUrl: './timeline.component.html', - styleUrls: ['./timeline.component.scss'] + templateUrl: './detail-timeline.component.html', + styleUrls: ['./detail-timeline.component.scss'] }) -export class TimelineComponent implements OnChanges { +export class DetailTimelineComponent implements OnChanges { private _router: EnvRouter = inject(EnvRouter); + private _activatedRoute = inject(ActivatedRoute); timeline: Timeline; pipe = new DatePipe('fr-FR'); + private durationPipe = new DurationPipe(); @ViewChild('timeline', {static: true}) timelineElement: ElementRef; - @Input() instance:InstanceEnvironment; - @Input() request:InstanceMainSession | InstanceRestSession; + @Input() instance: InstanceEnvironment; + @Input() request: InstanceMainSession | InstanceRestSession; ngOnChanges(changes: SimpleChanges): void { if(changes.instance || changes.request){ if(this.instance && this.request){ - let timeline_end = +this.request.end * 1000 - let timeline_start = +this.request.start * 1000 - let dataArray: any = [...this.request.requests, - ...this.request.queries, - ...this.request.stages.map((s: any) => ({ ...s, isStage: true }))]; - dataArray.splice(0, 0, { ...this.request, isStage: true }); + let timeline_end = this.request.end * 1000 + let timeline_start = this.request.start * 1000 + let dataArray: any = [...this.request.requests.map(r => ({...r, type: 'rest'})), + ...this.request.ftpRequests.map(r => ({...r, type: 'ftp'})), + ...this.request.mailRequests.map(r => ({...r, type: 'smtp'})), + ...this.request.ldapRequests.map(r => ({...r, type: 'ldap'})), + ...this.request.queries.map(r => ({...r, type: 'database'})), + ...this.request.stages.map(r => ({...r, type: 'stage'}))]; + dataArray.splice(0, 0, { ...this.request, type: 'stage' }); this.sortInnerArrayByDate(dataArray); let data: any; let groups: any; @@ -54,21 +61,22 @@ export class TimelineComponent implements OnChanges { } data = dataArray.map((c: any, i: number) => { let o = { - id: c.id ?? `${c.idRequest}_no_session`, + id: c.id ? `${c.id}_${c.type}` : `${c.idRequest}_no_session`, group: isWebapp ? 0 : c.threadName, - content: c.hasOwnProperty('isStage') ? '' : (c.name || c.host || 'N/A'), + content: c.type == 'stage' ? '' : (c.name || c.host || 'N/A'), start: c.start * 1000, end: c.end * 1000, - title: `${this.pipe.transform(new Date(c.start * 1000), 'HH:mm:ss.SSS')} - ${this.pipe.transform(new Date(c.end * 1000), 'HH:mm:ss.SSS')}
-

${c[title]}: ${this.getElapsedTime(c.end, c.start).toFixed(3)}s

`, - className: c.hasOwnProperty('name') ? "bdd" : !c.hasOwnProperty('isStage') ? "rest" : "", - type: c.hasOwnProperty('isStage') ? 'background' : 'range' + title: `${this.pipe.transform(new Date(c.start * 1000), 'HH:mm:ss.SSS')} - ${this.pipe.transform(new Date(c.end * 1000), 'HH:mm:ss.SSS')} (${this.durationPipe.transform({start: c.start, end: c.end})})
+

${c[title]}

`, + className: c.type == 'database' ? "bdd" : c.type != 'stage' ? "rest" : "", + type: c.type == 'stage' ? 'background' : 'range' } if (o.end > timeline_end) { timeline_end = o.end } return o; }) + console.log(data) if (this.timeline) { // destroy if exists this.timeline.destroy(); } @@ -92,22 +100,19 @@ export class TimelineComponent implements OnChanges { }); let that = this; - this.timeline.on('doubleClick', function (props: any) { - let id = props.item; - if(id) { - if (isNaN(id)) { - if(id.lastIndexOf('_no_session') == -1) { - that._router.navigate(['session', 'rest', id]); - } - } else { - that._router.navigate(['session', 'rest', that.request.id, 'database', id]); - } + /*this.timeline.on('doubleClick', function (props: any) { + let id = props.item.split('_')[0]; + let type = props.item.split('_')[1]; + console.log(id, type, that.request.id, that._activatedRoute.snapshot.data.type) + if (type == 'rest') { + that._router.navigate(['session', 'rest', id]); + } else { + that._router.navigate(['session', that._activatedRoute.snapshot.data.type, that.request.id, type, id]); } - - }); + });*/ - if (timeline_end != +this.request.end * 1000) { - this.timeline.addCustomTime(+this.request.end * 1000, "async"); + if (timeline_end != this.request.end * 1000) { + this.timeline.addCustomTime(this.request.end * 1000, "async"); } } } @@ -126,8 +131,4 @@ export class TimelineComponent implements OnChanges { }); } - - getElapsedTime(end: number, start: number,) { - return end - start; - } } \ No newline at end of file diff --git a/src/app/views/detail/session/main/detail-session-main.view.html b/src/app/views/detail/session/main/detail-session-main.view.html new file mode 100644 index 0000000..9e342bf --- /dev/null +++ b/src/app/views/detail/session/main/detail-session-main.view.html @@ -0,0 +1,96 @@ +
+
+ + + + settings_suggest + {{ '[' + session.type + '] ' + session.name || 'N/A' }} + +
+ +
+
+ + + + {{ session.location }} + + + +
+ warning +
{{ session.exception?.message || session.exception?.type }}
+
+
+ + person +
+ + {{ session.user || "N/A" }} + + le {{ (session.start * 1000) | date: 'dd/MM/yyyy à HH:mm:ss.SSS': 'fr' }} +
+
+
+ + + + storage +
{{instance.name}} {{instance.version}}
+
+
+ +
+
+ +
+
+ Database +
+
+ + {{ item.key }} + +
+ {{ item.value[0].productName }} v.{{ item.value[0].productVersion }} +
+
+
+
+ +
+ {{instance.address}} en {{instance.env}} +
+ + {{instance.os}} + + + {{instance.re}} + +
+
+
+ +
+ +
+

+ Aucun détail disponible ..
+

+
+ +
+ Chargement en cours... +
\ No newline at end of file diff --git a/src/app/views/detail/session/main/main.component.scss b/src/app/views/detail/session/main/detail-session-main.view.scss similarity index 100% rename from src/app/views/detail/session/main/main.component.scss rename to src/app/views/detail/session/main/detail-session-main.view.scss diff --git a/src/app/views/detail/session/main/main.component.ts b/src/app/views/detail/session/main/detail-session-main.view.ts similarity index 60% rename from src/app/views/detail/session/main/main.component.ts rename to src/app/views/detail/session/main/detail-session-main.view.ts index 7c07aa1..8bfa18a 100644 --- a/src/app/views/detail/session/main/main.component.ts +++ b/src/app/views/detail/session/main/detail-session-main.view.ts @@ -1,17 +1,17 @@ import {Component, inject, OnDestroy, OnInit} from "@angular/core"; -import {InstanceEnvironment, InstanceMainSession, InstanceRestSession} from "../../../../model/trace.model"; +import {InstanceEnvironment, InstanceMainSession} from "../../../../model/trace.model"; import {ActivatedRoute} from "@angular/router"; import {TraceService} from "../../../../service/trace.service"; import {EnvRouter} from "../../../../service/router.service"; import {Location} from "@angular/common"; -import {catchError, combineLatest, finalize, forkJoin, of, Subscription, switchMap} from "rxjs"; +import {combineLatest, finalize, forkJoin, of, Subscription, switchMap} from "rxjs"; import {application} from "../../../../../environments/environment"; @Component({ - templateUrl: './main.component.html', - styleUrls: ['./main.component.scss'], + templateUrl: './detail-session-main.view.html', + styleUrls: ['./detail-session-main.view.scss'], }) -export class MainComponent implements OnInit, OnDestroy { +export class DetailSessionMainView implements OnInit, OnDestroy { private _activatedRoute: ActivatedRoute = inject(ActivatedRoute); private _traceService: TraceService = inject(TraceService); private _router: EnvRouter = inject(EnvRouter); @@ -84,65 +84,6 @@ export class MainComponent implements OnInit, OnDestroy { } } - selectedRequest(event: { event: MouseEvent, row: any }) { - console.log(event) - if (event.row) { - if (event.event.ctrlKey) { - this._router.open(`#/session/main/${event.row}`, '_blank',) - } else { - this._router.navigate(['/session', 'main', event.row], { queryParams: { env: this.env } }); // TODO remove env FIX BUG - } - } - } - - selectedFtp(event: { event: MouseEvent, row: any }) { // TODO finish this - if (event.row) { - if (event.event.ctrlKey) { - this._router.open(`#/session/main/${this.session.id}/ftp/${event.row}`, '_blank',) - } else { - this._router.navigate(['/session/main', this.session.id, 'ftp', event.row], { - queryParams: { env: this.instance.env } - }); - } - } - } - - selectedLdap(event: { event: MouseEvent, row: any }) { // TODO finish this - if (event.row) { - if (event.event.ctrlKey) { - this._router.open(`#/session/main/${this.session.id}/ldap/${event.row}`, '_blank',) - } else { - this._router.navigate(['/session/main', this.session.id, 'ldap', event.row], { - queryParams: { env: this.instance.env } - }); - } - } - } - - selectedSmtp(event: { event: MouseEvent, row: any }) { // TODO finish this - if (event.row) { - if (event.event.ctrlKey) { - this._router.open(`#/session/main/${this.session.id}/smtp/${event.row}`, '_blank',) - } else { - this._router.navigate(['/session/main', this.session.id, 'smtp', event.row], { - queryParams: { env: this.instance.env } - }); - } - } - } - - selectedQuery(event: { event: MouseEvent, row: any }) { // TODO finish this - if (event.row) { - if (event.event.ctrlKey) { - this._router.open(`#/session/main/${this.session.type}/${this.session.id}/database/${event.row}`, '_blank',) - } else { - this._router.navigate(['/session/main', this.session.type, this.session.id, 'database', event.row], { - queryParams: { env: this.instance.env } - }); - } - } - } - navigate(event: MouseEvent, targetType: string, extraParam?: string) { let params: any[] = []; switch (targetType) { diff --git a/src/app/views/detail/session/main/main.component.html b/src/app/views/detail/session/main/main.component.html deleted file mode 100644 index 9f78495..0000000 --- a/src/app/views/detail/session/main/main.component.html +++ /dev/null @@ -1,170 +0,0 @@ -
-
- - - - settings_suggest - {{ '[' + session.type + '] ' + session.name || 'N/A' }} - -
- -
-
- - - - {{ session.location }} - - - -
- warning -
{{ session.exception?.message || session.exception?.type }}
-
-
- - person -
- - {{ session.user || "N/A" }} - - le {{ (session.start * 1000) | date: 'dd/MM/yyyy à HH:mm:ss.SSS': 'fr' }} -
-
-
- - - - storage -
{{instance.name}} {{instance.version}}
-
-
- -
-
- -
-
- Database -
-
- - {{ item.key }} - -
- {{ item.value[0].productName }} v.{{ item.value[0].productVersion }} -
-
-
-
- -
- {{instance.address}} en {{instance.env}} -
- - {{instance.os}} - - - {{instance.re}} - -
-
-
-
-
- -
- call_made -
API
-
- -
- -
-
-
- -
- smb_share -
FTP
-
- -
- - -
-
-
- -
- outgoing_mail -
SMTP
-
- -
- - -
-
-
- -
- user_attributes -
LDAP
-
- -
- - -
-
-
- -
- Database -
BDD
-
- -
- - -
-
-
- -
- view_timeline - Chronologie -
- -
- -
-
- -
-

- Aucun détail disponible ..
-

-
- -
- Chargement en cours... -
\ No newline at end of file diff --git a/src/app/views/detail/session/rest/rest.component.html b/src/app/views/detail/session/rest/detail-session-rest.view.html similarity index 54% rename from src/app/views/detail/session/rest/rest.component.html rename to src/app/views/detail/session/rest/detail-session-rest.view.html index f3d268f..7890f53 100644 --- a/src/app/views/detail/session/rest/rest.component.html +++ b/src/app/views/detail/session/rest/detail-session-rest.view.html @@ -100,81 +100,7 @@
-
-
- -
- call_made -
API
-
- -
- -
-
-
- -
- smb_share -
FTP
-
- -
- - -
-
-
- -
- outgoing_mail -
SMTP
-
- -
- - -
-
-
- -
- user_attributes -
LDAP
-
- -
- - -
-
-
- -
- Database -
BDD
-
- -
- - -
-
-
- -
- view_timeline - Chronologie -
- -
- -
+
diff --git a/src/app/views/detail/session/rest/rest.component.scss b/src/app/views/detail/session/rest/detail-session-rest.view.scss similarity index 100% rename from src/app/views/detail/session/rest/rest.component.scss rename to src/app/views/detail/session/rest/detail-session-rest.view.scss diff --git a/src/app/views/detail/session/rest/rest.component.ts b/src/app/views/detail/session/rest/detail-session-rest.view.ts similarity index 97% rename from src/app/views/detail/session/rest/rest.component.ts rename to src/app/views/detail/session/rest/detail-session-rest.view.ts index 7d4ad09..5b19946 100644 --- a/src/app/views/detail/session/rest/rest.component.ts +++ b/src/app/views/detail/session/rest/detail-session-rest.view.ts @@ -9,10 +9,10 @@ import {Utils} from "../../../../shared/util"; import {EnvRouter} from "../../../../service/router.service"; @Component({ - templateUrl: './rest.component.html', - styleUrls: ['./rest.component.scss'], + templateUrl: './detail-session-rest.view.html', + styleUrls: ['./detail-session-rest.view.scss'], }) -export class RestComponent implements OnInit, OnDestroy { +export class DetailSessionRestView implements OnInit, OnDestroy { private _activatedRoute: ActivatedRoute = inject(ActivatedRoute); private _traceService: TraceService = inject(TraceService); private _router: EnvRouter = inject(EnvRouter); diff --git a/src/app/views/detail/smtp/smtp.component.html b/src/app/views/detail/smtp/detail-smtp.view.html similarity index 100% rename from src/app/views/detail/smtp/smtp.component.html rename to src/app/views/detail/smtp/detail-smtp.view.html diff --git a/src/app/views/detail/smtp/smtp.component.scss b/src/app/views/detail/smtp/detail-smtp.view.scss similarity index 100% rename from src/app/views/detail/smtp/smtp.component.scss rename to src/app/views/detail/smtp/detail-smtp.view.scss diff --git a/src/app/views/detail/smtp/smtp.component.ts b/src/app/views/detail/smtp/detail-smtp.view.ts similarity index 97% rename from src/app/views/detail/smtp/smtp.component.ts rename to src/app/views/detail/smtp/detail-smtp.view.ts index 9c0f34c..4b57783 100644 --- a/src/app/views/detail/smtp/smtp.component.ts +++ b/src/app/views/detail/smtp/detail-smtp.view.ts @@ -17,10 +17,10 @@ import {DurationPipe} from "../../../shared/pipe/duration.pipe"; import {MatTableDataSource} from "@angular/material/table"; @Component({ - templateUrl: './smtp.component.html', - styleUrls: ['./smtp.component.scss'], + templateUrl: './detail-smtp.view.html', + styleUrls: ['./detail-smtp.view.scss'], }) -export class SmtpComponent implements OnInit, OnDestroy { +export class DetailSmtpView implements OnInit, OnDestroy { private _activatedRoute: ActivatedRoute = inject(ActivatedRoute); private _traceService: TraceService = inject(TraceService); private _router: EnvRouter = inject(EnvRouter); diff --git a/src/app/views/search/main/main.component.html b/src/app/views/search/main/search-main.view.html similarity index 100% rename from src/app/views/search/main/main.component.html rename to src/app/views/search/main/search-main.view.html diff --git a/src/app/views/search/main/main.component.scss b/src/app/views/search/main/search-main.view.scss similarity index 100% rename from src/app/views/search/main/main.component.scss rename to src/app/views/search/main/search-main.view.scss diff --git a/src/app/views/search/main/main.component.ts b/src/app/views/search/main/search-main.view.ts similarity index 97% rename from src/app/views/search/main/main.component.ts rename to src/app/views/search/main/search-main.view.ts index 06ff2df..86f48b0 100644 --- a/src/app/views/search/main/main.component.ts +++ b/src/app/views/search/main/search-main.view.ts @@ -16,10 +16,10 @@ import {EnvRouter} from "../../../service/router.service"; @Component({ - templateUrl: './main.component.html', - styleUrls: ['./main.component.scss'], + templateUrl: './search-main.view.html', + styleUrls: ['./search-main.view.scss'], }) -export class MainComponent implements OnInit, OnDestroy { +export class SearchMainView implements OnInit, OnDestroy { MAPPING_TYPE = Constants.MAPPING_TYPE; filterConstants = FilterConstants; utils: Utils = new Utils(); @@ -55,7 +55,7 @@ export class MainComponent implements OnInit, OnDestroy { next: ([params, queryParams]) => { this.params.env = queryParams['env'] || application.default_env; - this.params.type = params['type_main']; + this.params.type = params.type; this.params.start = queryParams['start'] ? new Date(queryParams['start']) : (application.session.main.default_period || makePeriod(0, 1)).start; this.params.end = queryParams['end'] ? new Date(queryParams['end']) : (application.session.main.default_period || makePeriod(0, 1)).end; this.patchDateValue(this.params.start, new Date(this.params.end.getFullYear(), this.params.end.getMonth(), this.params.end.getDate() - 1)); diff --git a/src/app/views/search/rest/rest.component.html b/src/app/views/search/rest/search-rest.view.html similarity index 100% rename from src/app/views/search/rest/rest.component.html rename to src/app/views/search/rest/search-rest.view.html diff --git a/src/app/views/search/rest/rest.component.scss b/src/app/views/search/rest/search-rest.view.scss similarity index 100% rename from src/app/views/search/rest/rest.component.scss rename to src/app/views/search/rest/search-rest.view.scss diff --git a/src/app/views/search/rest/rest.component.ts b/src/app/views/search/rest/search-rest.view.ts similarity index 98% rename from src/app/views/search/rest/rest.component.ts rename to src/app/views/search/rest/search-rest.view.ts index 9b75ae2..38fd4ba 100644 --- a/src/app/views/search/rest/rest.component.ts +++ b/src/app/views/search/rest/search-rest.view.ts @@ -17,10 +17,10 @@ import {EnvRouter} from "../../../service/router.service"; @Component({ - templateUrl: './rest.component.html', - styleUrls: ['./rest.component.scss'], + templateUrl: './search-rest.view.html', + styleUrls: ['./search-rest.view.scss'], }) -export class RestComponent implements OnInit, OnDestroy { +export class SearchRestView implements OnInit, OnDestroy { MAPPING_TYPE = Constants.MAPPING_TYPE; filterConstants = FilterConstants; nameDataList: any[]; diff --git a/src/app/views/statistic/_component/dependencies-table/dependencies-table.component.html b/src/app/views/statistic/_component/dependencies-table/statistic-dependencies-table.component.html similarity index 100% rename from src/app/views/statistic/_component/dependencies-table/dependencies-table.component.html rename to src/app/views/statistic/_component/dependencies-table/statistic-dependencies-table.component.html diff --git a/src/app/views/statistic/_component/dependencies-table/dependencies-table.component.scss b/src/app/views/statistic/_component/dependencies-table/statistic-dependencies-table.component.scss similarity index 100% rename from src/app/views/statistic/_component/dependencies-table/dependencies-table.component.scss rename to src/app/views/statistic/_component/dependencies-table/statistic-dependencies-table.component.scss diff --git a/src/app/views/statistic/_component/dependencies-table/dependencies-table.component.ts b/src/app/views/statistic/_component/dependencies-table/statistic-dependencies-table.component.ts similarity index 93% rename from src/app/views/statistic/_component/dependencies-table/dependencies-table.component.ts rename to src/app/views/statistic/_component/dependencies-table/statistic-dependencies-table.component.ts index 2378441..e40f427 100644 --- a/src/app/views/statistic/_component/dependencies-table/dependencies-table.component.ts +++ b/src/app/views/statistic/_component/dependencies-table/statistic-dependencies-table.component.ts @@ -5,10 +5,10 @@ import { ChartProvider, field, values } from "@oneteme/jquery-core"; @Component({ selector: 'dependencies-table', - templateUrl: './dependencies-table.component.html', - styleUrls: ['./dependencies-table.component.scss'], + templateUrl: './statistic-dependencies-table.component.html', + styleUrls: ['./statistic-dependencies-table.component.scss'], }) -export class DependenciesTableComponent { +export class StatisticDependenciesTableComponent { displayedColumns: string[] = ['name', 'response']; dataSource: MatTableDataSource<{ name: string, count: number, data: any[] }> = new MatTableDataSource([]); diff --git a/src/app/views/statistic/_component/dependents-table/dependents-table.component.html b/src/app/views/statistic/_component/dependents-table/statistic-dependents-table.component.html similarity index 100% rename from src/app/views/statistic/_component/dependents-table/dependents-table.component.html rename to src/app/views/statistic/_component/dependents-table/statistic-dependents-table.component.html diff --git a/src/app/views/statistic/_component/dependents-table/dependents-table.component.scss b/src/app/views/statistic/_component/dependents-table/statistic-dependents-table.component.scss similarity index 100% rename from src/app/views/statistic/_component/dependents-table/dependents-table.component.scss rename to src/app/views/statistic/_component/dependents-table/statistic-dependents-table.component.scss diff --git a/src/app/views/statistic/_component/dependents-table/dependents-table.component.ts b/src/app/views/statistic/_component/dependents-table/statistic-dependents-table.component.ts similarity index 93% rename from src/app/views/statistic/_component/dependents-table/dependents-table.component.ts rename to src/app/views/statistic/_component/dependents-table/statistic-dependents-table.component.ts index 5a639bf..0889de3 100644 --- a/src/app/views/statistic/_component/dependents-table/dependents-table.component.ts +++ b/src/app/views/statistic/_component/dependents-table/statistic-dependents-table.component.ts @@ -5,10 +5,10 @@ import { ChartProvider, field, values } from "@oneteme/jquery-core"; @Component({ selector: 'dependents-table', - templateUrl: './dependents-table.component.html', - styleUrls: ['./dependents-table.component.scss'], + templateUrl: './statistic-dependents-table.component.html', + styleUrls: ['./statistic-dependents-table.component.scss'], }) -export class DependentsTableComponent { +export class StatisticDependentsTableComponent { displayedColumns: string[] = ['name', 'response']; dataSource: MatTableDataSource<{ name: string, count: number, data: any[] }> = new MatTableDataSource([]); diff --git a/src/app/views/statistic/_component/exception-table/exception-table.component.html b/src/app/views/statistic/_component/exception-table/statistic-exception-table.component.html similarity index 100% rename from src/app/views/statistic/_component/exception-table/exception-table.component.html rename to src/app/views/statistic/_component/exception-table/statistic-exception-table.component.html diff --git a/src/app/views/statistic/_component/exception-table/exception-table.component.scss b/src/app/views/statistic/_component/exception-table/statistic-exception-table.component.scss similarity index 100% rename from src/app/views/statistic/_component/exception-table/exception-table.component.scss rename to src/app/views/statistic/_component/exception-table/statistic-exception-table.component.scss diff --git a/src/app/views/statistic/_component/exception-table/exception-table.component.ts b/src/app/views/statistic/_component/exception-table/statistic-exception-table.component.ts similarity index 88% rename from src/app/views/statistic/_component/exception-table/exception-table.component.ts rename to src/app/views/statistic/_component/exception-table/statistic-exception-table.component.ts index b469c31..12a3da5 100644 --- a/src/app/views/statistic/_component/exception-table/exception-table.component.ts +++ b/src/app/views/statistic/_component/exception-table/statistic-exception-table.component.ts @@ -5,10 +5,10 @@ import { pipe } from "rxjs"; @Component({ selector: 'exception-table', - templateUrl: './exception-table.component.html', - styleUrls: ['./exception-table.component.scss'], + templateUrl: './statistic-exception-table.component.html', + styleUrls: ['./statistic-exception-table.component.scss'], }) -export class ExceptionTableComponent { +export class StatisticExceptionTableComponent { displayedColumns: string[] = ['message']; dataSource: MatTableDataSource<{ count: number, message: string, class: string }> = new MatTableDataSource([]); addExceptionCount: number = 0; diff --git a/src/app/views/statistic/application/application.component.html b/src/app/views/statistic/application/statistic-application.view.html similarity index 100% rename from src/app/views/statistic/application/application.component.html rename to src/app/views/statistic/application/statistic-application.view.html diff --git a/src/app/views/statistic/application/application.component.scss b/src/app/views/statistic/application/statistic-application.view.scss similarity index 100% rename from src/app/views/statistic/application/application.component.scss rename to src/app/views/statistic/application/statistic-application.view.scss diff --git a/src/app/views/statistic/application/application.component.ts b/src/app/views/statistic/application/statistic-application.view.ts similarity index 98% rename from src/app/views/statistic/application/application.component.ts rename to src/app/views/statistic/application/statistic-application.view.ts index 76b3c69..8b124b5 100644 --- a/src/app/views/statistic/application/application.component.ts +++ b/src/app/views/statistic/application/statistic-application.view.ts @@ -11,10 +11,10 @@ import { FilterService } from "src/app/service/filter.service"; import {EnvRouter} from "../../../service/router.service"; @Component({ - templateUrl: './application.component.html', - styleUrls: ['./application.component.scss'] + templateUrl: './statistic-application.view.html', + styleUrls: ['./statistic-application.view.scss'] }) -export class ApplicationComponent implements OnInit, OnDestroy { +export class StatisticApplicationView implements OnInit, OnDestroy { constants = Constants filterConstants = FilterConstants; private _activatedRoute = inject(ActivatedRoute); diff --git a/src/app/views/statistic/database/database.component.html b/src/app/views/statistic/database/statistic-database.view.html similarity index 100% rename from src/app/views/statistic/database/database.component.html rename to src/app/views/statistic/database/statistic-database.view.html diff --git a/src/app/views/statistic/database/database.component.scss b/src/app/views/statistic/database/statistic-database.view.scss similarity index 100% rename from src/app/views/statistic/database/database.component.scss rename to src/app/views/statistic/database/statistic-database.view.scss diff --git a/src/app/views/statistic/database/database.component.ts b/src/app/views/statistic/database/statistic-database.view.ts similarity index 98% rename from src/app/views/statistic/database/database.component.ts rename to src/app/views/statistic/database/statistic-database.view.ts index 6a88e6c..cfedfd1 100644 --- a/src/app/views/statistic/database/database.component.ts +++ b/src/app/views/statistic/database/statistic-database.view.ts @@ -11,10 +11,10 @@ import { formatters, periodManagement } from 'src/app/shared/util'; import { ChartProvider, field } from '@oneteme/jquery-core'; @Component({ - templateUrl: './database.component.html', - styleUrls: ['./database.component.scss'] + templateUrl: './statistic-database.view.html', + styleUrls: ['./statistic-database.view.scss'] }) -export class DatabaseComponent implements OnInit { +export class StatisticDatabaseView implements OnInit { private _activatedRoute = inject(ActivatedRoute); private _router = inject(Router); private _datePipe = inject(DatePipe); diff --git a/src/app/views/statistic/rest/rest.component.html b/src/app/views/statistic/rest/statistic-rest.view.html similarity index 100% rename from src/app/views/statistic/rest/rest.component.html rename to src/app/views/statistic/rest/statistic-rest.view.html diff --git a/src/app/views/statistic/rest/rest.component.scss b/src/app/views/statistic/rest/statistic-rest.view.scss similarity index 100% rename from src/app/views/statistic/rest/rest.component.scss rename to src/app/views/statistic/rest/statistic-rest.view.scss diff --git a/src/app/views/statistic/rest/rest.component.ts b/src/app/views/statistic/rest/statistic-rest.view.ts similarity index 98% rename from src/app/views/statistic/rest/rest.component.ts rename to src/app/views/statistic/rest/statistic-rest.view.ts index 2e492a0..d1f922c 100644 --- a/src/app/views/statistic/rest/rest.component.ts +++ b/src/app/views/statistic/rest/statistic-rest.view.ts @@ -11,10 +11,10 @@ import { FilterService } from "src/app/service/filter.service"; import {EnvRouter} from "../../../service/router.service"; @Component({ - templateUrl: './rest.component.html', - styleUrls: ['./rest.component.scss'] + templateUrl: './statistic-rest.view.html', + styleUrls: ['./statistic-rest.view.scss'] }) -export class RestComponent implements OnInit, OnDestroy { +export class StatisticRestView implements OnInit, OnDestroy { constants = Constants; filterConstants = FilterConstants; private _activatedRoute = inject(ActivatedRoute); diff --git a/src/app/views/statistic/user/_component/session-table/session-table.component.html b/src/app/views/statistic/user/_component/session-table/statistic-user-session-table.component.html similarity index 100% rename from src/app/views/statistic/user/_component/session-table/session-table.component.html rename to src/app/views/statistic/user/_component/session-table/statistic-user-session-table.component.html diff --git a/src/app/views/statistic/user/_component/session-table/session-table.component.scss b/src/app/views/statistic/user/_component/session-table/statistic-user-session-table.component.scss similarity index 100% rename from src/app/views/statistic/user/_component/session-table/session-table.component.scss rename to src/app/views/statistic/user/_component/session-table/statistic-user-session-table.component.scss diff --git a/src/app/views/statistic/user/_component/session-table/session-table.component.ts b/src/app/views/statistic/user/_component/session-table/statistic-user-session-table.component.ts similarity index 84% rename from src/app/views/statistic/user/_component/session-table/session-table.component.ts rename to src/app/views/statistic/user/_component/session-table/statistic-user-session-table.component.ts index 274b27f..cb13e59 100644 --- a/src/app/views/statistic/user/_component/session-table/session-table.component.ts +++ b/src/app/views/statistic/user/_component/session-table/statistic-user-session-table.component.ts @@ -4,10 +4,10 @@ import { MatTableDataSource } from "@angular/material/table"; @Component({ selector: 'session-table', - styleUrls: ['./session-table.component.scss'], - templateUrl: './session-table.component.html', + styleUrls: ['./statistic-user-session-table.component.scss'], + templateUrl: './statistic-user-session-table.component.html', }) -export class SessionTableComponent { +export class StatisticUserSessionTableComponent { displayedColumns: string[] = ['appName', 'name', 'location', 'start']; dataSource: MatTableDataSource<{ name: string, start: number, elapsedtime: number, location: string, appName: string }> = new MatTableDataSource([]); diff --git a/src/app/views/statistic/user/user.component.html b/src/app/views/statistic/user/statistic-user.view.html similarity index 100% rename from src/app/views/statistic/user/user.component.html rename to src/app/views/statistic/user/statistic-user.view.html diff --git a/src/app/views/statistic/user/user.component.scss b/src/app/views/statistic/user/statistic-user.view.scss similarity index 100% rename from src/app/views/statistic/user/user.component.scss rename to src/app/views/statistic/user/statistic-user.view.scss diff --git a/src/app/views/statistic/user/user.component.ts b/src/app/views/statistic/user/statistic-user.view.ts similarity index 98% rename from src/app/views/statistic/user/user.component.ts rename to src/app/views/statistic/user/statistic-user.view.ts index 18d3a68..a8a26b6 100644 --- a/src/app/views/statistic/user/user.component.ts +++ b/src/app/views/statistic/user/statistic-user.view.ts @@ -11,10 +11,10 @@ import { mapParams, formatters, periodManagement } from "src/app/shared/util"; import {EnvRouter} from "../../../service/router.service"; @Component({ - templateUrl: './user.component.html', - styleUrls: ['./user.component.scss'] + templateUrl: './statistic-user.view.html', + styleUrls: ['./statistic-user.view.scss'] }) -export class UserComponent implements OnInit, OnDestroy { +export class StatisticUserView implements OnInit, OnDestroy { constants = Constants; filterConstants = FilterConstants; diff --git a/src/app/views/tree/tree.component.html b/src/app/views/tree/tree.view.html similarity index 100% rename from src/app/views/tree/tree.component.html rename to src/app/views/tree/tree.view.html diff --git a/src/app/views/tree/tree.component.scss b/src/app/views/tree/tree.view.scss similarity index 100% rename from src/app/views/tree/tree.component.scss rename to src/app/views/tree/tree.view.scss diff --git a/src/app/views/tree/tree.component.ts b/src/app/views/tree/tree.view.ts similarity index 99% rename from src/app/views/tree/tree.component.ts rename to src/app/views/tree/tree.view.ts index 78897b3..fb34ee0 100644 --- a/src/app/views/tree/tree.component.ts +++ b/src/app/views/tree/tree.view.ts @@ -11,11 +11,11 @@ import {EnvRouter} from "../../service/router.service"; @Component({ selector: 'app-tree', - templateUrl: './tree.component.html', - styleUrls: ['./tree.component.scss'], + templateUrl: './tree.view.html', + styleUrls: ['./tree.view.scss'], }) -export class TreeComponent implements OnDestroy { +export class TreeView implements OnDestroy { private _activatedRoute = inject(ActivatedRoute); private _router = inject(EnvRouter); private _traceService = inject(TraceService); @@ -741,7 +741,7 @@ export class TreeComponent implements OnDestroy { vertexIcons: any = { - "WEBAPP": "BROWSER", + "VIEW": "BROWSER", "BATCH": "MICROSERVICE", /* "api": { "200": "MICROSERVICE200", diff --git a/src/app/views/views.module.ts b/src/app/views/views.module.ts index a20d65a..730ef81 100644 --- a/src/app/views/views.module.ts +++ b/src/app/views/views.module.ts @@ -5,31 +5,40 @@ import {FormsModule, ReactiveFormsModule} from '@angular/forms'; import {BrowserModule} from '@angular/platform-browser'; import {BrowserAnimationsModule} from '@angular/platform-browser/animations'; import {SharedModule} from '../shared/shared.module'; -import {MainComponent as SearchMainComponent} from './search/main/main.component'; -import {MainComponent as DetailSessionMainComponent} from './detail/session/main/main.component'; -import {TreeComponent} from './tree/tree.component'; -import {DependenciesTableComponent} from './statistic/_component/dependencies-table/dependencies-table.component'; -import {DependentsTableComponent} from './statistic/_component/dependents-table/dependents-table.component'; -import {SessionTableComponent} from './statistic/user/_component/session-table/session-table.component'; -import {ApplicationComponent} from './statistic/application/application.component'; -import {RestComponent as SearchRestComponent} from './search/rest/rest.component'; -import {RestComponent as StatisticRestComponent} from './statistic/rest/rest.component'; -import {RestComponent as DetailSessionRestComponent} from './detail/session/rest/rest.component'; -import {UserComponent} from './statistic/user/user.component'; -import {ExceptionTableComponent} from './statistic/_component/exception-table/exception-table.component'; +import {SearchMainView} from './search/main/search-main.view'; +import {DetailSessionMainView} from './detail/session/main/detail-session-main.view'; +import {TreeView} from './tree/tree.view'; +import { + StatisticDependenciesTableComponent +} from './statistic/_component/dependencies-table/statistic-dependencies-table.component'; +import { + StatisticDependentsTableComponent +} from './statistic/_component/dependents-table/statistic-dependents-table.component'; +import { + StatisticUserSessionTableComponent +} from './statistic/user/_component/session-table/statistic-user-session-table.component'; +import {StatisticApplicationView} from './statistic/application/statistic-application.view'; +import {SearchRestView} from './search/rest/search-rest.view'; +import {StatisticRestView} from './statistic/rest/statistic-rest.view'; +import {DetailSessionRestView} from './detail/session/rest/detail-session-rest.view'; +import {StatisticUserView} from './statistic/user/statistic-user.view'; +import { + StatisticExceptionTableComponent +} from './statistic/_component/exception-table/statistic-exception-table.component'; import {ChartComponent} from '@oneteme/jquery-apexcharts'; -import {DatabaseComponent as StatisticDatabaseComponent} from './statistic/database/database.component'; -import {DatabaseComponent as DetailDatabaseComponent} from './detail/database/database.component'; -import {RestTableComponent} from './detail/session/_component/rest-table/rest-table.component'; -import {DatabaseTableComponent} from './detail/session/_component/database-table/database-table.component'; -import {TimelineComponent} from './detail/session/_component/timeline/timeline.component'; +import {StatisticDatabaseView} from './statistic/database/statistic-database.view'; +import {DetailDatabaseView} from './detail/database/detail-database.view'; +import {DetailRestTableComponent} from './detail/session/_component/rest-table/detail-rest-table.component'; +import {DetailDatabaseTableComponent} from './detail/session/_component/database-table/detail-database-table.component'; +import {DetailTimelineComponent} from './detail/session/_component/timeline/detail-timeline.component'; import {DashboardComponent} from './dashboard/dashboard.component'; -import {FtpTableComponent} from "./detail/session/_component/ftp-table/ftp-table.component"; -import {SmtpTableComponent} from "./detail/session/_component/smtp-table/smtp-table.component"; -import {LdapTableComponent} from "./detail/session/_component/ldap-table/ldap-table.component"; -import {FtpComponent as DetailFtpComponent} from "./detail/ftp/ftp.component"; -import {LdapComponent as DetailLdapComponent} from "./detail/ldap/ldap.component"; -import {SmtpComponent as DetailSmtpComponent} from "./detail/smtp/smtp.component"; +import {DetailFtpTableComponent} from "./detail/session/_component/ftp-table/detail-ftp-table.component"; +import {DetailSmtpTableComponent} from "./detail/session/_component/smtp-table/detail-smtp-table.component"; +import {DetailLdapTableComponent} from "./detail/session/_component/ldap-table/detail-ldap-table.component"; +import {DetailFtpView} from "./detail/ftp/detail-ftp.view"; +import {DetailLdapView} from "./detail/ldap/detail-ldap.view"; +import {DetailSmtpView} from "./detail/smtp/detail-smtp.view"; +import {DetailSessionComponent} from "./detail/session/_component/detail-session.component"; @NgModule({ imports: [ @@ -43,29 +52,30 @@ import {SmtpComponent as DetailSmtpComponent} from "./detail/smtp/smtp.component ChartComponent ], declarations: [ - SearchRestComponent, - SearchMainComponent, - StatisticRestComponent, - StatisticDatabaseComponent, - DetailSessionRestComponent, - DetailSessionMainComponent, - DetailDatabaseComponent, - DetailFtpComponent, - DetailLdapComponent, - DetailSmtpComponent, - RestTableComponent, - DatabaseTableComponent, - FtpTableComponent, - SmtpTableComponent, - LdapTableComponent, - TimelineComponent, - ApplicationComponent, - UserComponent, - TreeComponent, - DependentsTableComponent, - DependenciesTableComponent, - ExceptionTableComponent, - SessionTableComponent, + SearchRestView, + SearchMainView, + StatisticRestView, + StatisticDatabaseView, + DetailSessionRestView, + DetailSessionMainView, + DetailDatabaseView, + DetailFtpView, + DetailLdapView, + DetailSmtpView, + DetailRestTableComponent, + DetailDatabaseTableComponent, + DetailFtpTableComponent, + DetailSmtpTableComponent, + DetailLdapTableComponent, + DetailTimelineComponent, + DetailSessionComponent, + StatisticApplicationView, + StatisticUserView, + TreeView, + StatisticDependentsTableComponent, + StatisticDependenciesTableComponent, + StatisticExceptionTableComponent, + StatisticUserSessionTableComponent, DashboardComponent ] }) diff --git a/src/index.html b/src/index.html index 7b0d28e..f6a4048 100644 --- a/src/index.html +++ b/src/index.html @@ -2,7 +2,7 @@ - TraceAPI + INSPECT From 0aee298231c35288d467c4f69fd5f762a5fffdbf Mon Sep 17 00:00:00 2001 From: fufuu Date: Wed, 14 Aug 2024 16:33:02 +0200 Subject: [PATCH 055/126] edit --- src/app/app.module.ts | 23 ++++++++------ src/app/views/views.module.ts | 58 +++++++++++++++++------------------ 2 files changed, 42 insertions(+), 39 deletions(-) diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 3b375ed..d93e32d 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -13,21 +13,23 @@ import {HttpClientModule} from '@angular/common/http'; import {DatePipe, DecimalPipe, registerLocaleData} from '@angular/common'; import localeFr from '@angular/common/locales/fr'; -import {TreeView} from './views/tree/tree.view'; -import {DetailDatabaseView} from './views/detail/database/detail-database.view'; -import {DashboardComponent} from './views/dashboard/dashboard.component'; import {SearchRestView} from "./views/search/rest/search-rest.view"; -import {SearchMainView} from './views/search/main/search-main.view'; -import {EnvRouter} from "./service/router.service"; +import {DetailSessionRestView} from "./views/detail/session/rest/detail-session-rest.view"; +import {DetailDatabaseView} from "./views/detail/database/detail-database.view"; import {DetailFtpView} from "./views/detail/ftp/detail-ftp.view"; import {DetailLdapView} from "./views/detail/ldap/detail-ldap.view"; -import {DetailSmtpView as DetailSmtpComponent} from "./views/detail/smtp/detail-smtp.view"; -import {DetailSessionRestView} from "./views/detail/session/rest/detail-session-rest.view"; +import {DetailSmtpView} from "./views/detail/smtp/detail-smtp.view"; +import {TreeView} from "./views/tree/tree.view"; +import {SearchMainView} from "./views/search/main/search-main.view"; import {DetailSessionMainView} from "./views/detail/session/main/detail-session-main.view"; import {StatisticApplicationView} from "./views/statistic/application/statistic-application.view"; import {StatisticRestView} from "./views/statistic/rest/statistic-rest.view"; import {StatisticUserView} from "./views/statistic/user/statistic-user.view"; import {StatisticDatabaseView} from "./views/statistic/database/statistic-database.view"; +import {DashboardComponent} from "./views/dashboard/dashboard.component"; +import {EnvRouter} from "./service/router.service"; +import {DurationPipe} from "./shared/pipe/duration.pipe"; + registerLocaleData(localeFr, 'fr-FR'); const routes: Route[] = [ @@ -70,7 +72,7 @@ const routes: Route[] = [ { path: 'smtp/:id_smtp', data: { type: 'rest' }, - component: DetailSmtpComponent, + component: DetailSmtpView, title: 'Detail Smtp' }, { @@ -136,7 +138,7 @@ const routes: Route[] = [ { path: 'smtp/:id_smtp', data: { type: 'main' }, - component: DetailSmtpComponent, + component: DetailSmtpView, title: 'Detail Smtp' }, { @@ -182,7 +184,7 @@ const routes: Route[] = [ }, { path: 'dashboard', - component: DashboardComponent, + component: DashboardComponent, title: 'Dashboard' }, { path: '**', pathMatch: 'full', redirectTo: `/session/rest` } @@ -205,6 +207,7 @@ const routes: Route[] = [ providers: [ DatePipe, DecimalPipe, + DurationPipe, EnvRouter, { provide: LOCALE_ID, useValue: 'fr-FR' } ], diff --git a/src/app/views/views.module.ts b/src/app/views/views.module.ts index 730ef81..ac585ff 100644 --- a/src/app/views/views.module.ts +++ b/src/app/views/views.module.ts @@ -5,40 +5,40 @@ import {FormsModule, ReactiveFormsModule} from '@angular/forms'; import {BrowserModule} from '@angular/platform-browser'; import {BrowserAnimationsModule} from '@angular/platform-browser/animations'; import {SharedModule} from '../shared/shared.module'; -import {SearchMainView} from './search/main/search-main.view'; -import {DetailSessionMainView} from './detail/session/main/detail-session-main.view'; -import {TreeView} from './tree/tree.view'; -import { - StatisticDependenciesTableComponent -} from './statistic/_component/dependencies-table/statistic-dependencies-table.component'; +import {ChartComponent} from "@oneteme/jquery-apexcharts"; +import {SearchRestView} from "./search/rest/search-rest.view"; +import {SearchMainView} from "./search/main/search-main.view"; +import {StatisticRestView} from "./statistic/rest/statistic-rest.view"; +import {StatisticDatabaseView} from "./statistic/database/statistic-database.view"; +import {DetailSessionRestView} from "./detail/session/rest/detail-session-rest.view"; +import {DetailSessionMainView} from "./detail/session/main/detail-session-main.view"; +import {DetailDatabaseView} from "./detail/database/detail-database.view"; +import {DetailFtpView} from "./detail/ftp/detail-ftp.view"; +import {DetailLdapView} from "./detail/ldap/detail-ldap.view"; +import {DetailSmtpView} from "./detail/smtp/detail-smtp.view"; +import {DetailRestTableComponent} from "./detail/session/_component/rest-table/detail-rest-table.component"; +import {DetailDatabaseTableComponent} from "./detail/session/_component/database-table/detail-database-table.component"; +import {DetailFtpTableComponent} from "./detail/session/_component/ftp-table/detail-ftp-table.component"; +import {DetailSmtpTableComponent} from "./detail/session/_component/smtp-table/detail-smtp-table.component"; +import {DetailLdapTableComponent} from "./detail/session/_component/ldap-table/detail-ldap-table.component"; +import {DetailTimelineComponent} from "./detail/session/_component/timeline/detail-timeline.component"; +import {DetailSessionComponent} from "./detail/session/_component/detail-session.component"; +import {StatisticApplicationView} from "./statistic/application/statistic-application.view"; +import {StatisticUserView} from "./statistic/user/statistic-user.view"; +import {TreeView} from "./tree/tree.view"; import { StatisticDependentsTableComponent -} from './statistic/_component/dependents-table/statistic-dependents-table.component'; +} from "./statistic/_component/dependents-table/statistic-dependents-table.component"; import { - StatisticUserSessionTableComponent -} from './statistic/user/_component/session-table/statistic-user-session-table.component'; -import {StatisticApplicationView} from './statistic/application/statistic-application.view'; -import {SearchRestView} from './search/rest/search-rest.view'; -import {StatisticRestView} from './statistic/rest/statistic-rest.view'; -import {DetailSessionRestView} from './detail/session/rest/detail-session-rest.view'; -import {StatisticUserView} from './statistic/user/statistic-user.view'; + StatisticDependenciesTableComponent +} from "./statistic/_component/dependencies-table/statistic-dependencies-table.component"; import { StatisticExceptionTableComponent -} from './statistic/_component/exception-table/statistic-exception-table.component'; -import {ChartComponent} from '@oneteme/jquery-apexcharts'; -import {StatisticDatabaseView} from './statistic/database/statistic-database.view'; -import {DetailDatabaseView} from './detail/database/detail-database.view'; -import {DetailRestTableComponent} from './detail/session/_component/rest-table/detail-rest-table.component'; -import {DetailDatabaseTableComponent} from './detail/session/_component/database-table/detail-database-table.component'; -import {DetailTimelineComponent} from './detail/session/_component/timeline/detail-timeline.component'; -import {DashboardComponent} from './dashboard/dashboard.component'; -import {DetailFtpTableComponent} from "./detail/session/_component/ftp-table/detail-ftp-table.component"; -import {DetailSmtpTableComponent} from "./detail/session/_component/smtp-table/detail-smtp-table.component"; -import {DetailLdapTableComponent} from "./detail/session/_component/ldap-table/detail-ldap-table.component"; -import {DetailFtpView} from "./detail/ftp/detail-ftp.view"; -import {DetailLdapView} from "./detail/ldap/detail-ldap.view"; -import {DetailSmtpView} from "./detail/smtp/detail-smtp.view"; -import {DetailSessionComponent} from "./detail/session/_component/detail-session.component"; +} from "./statistic/_component/exception-table/statistic-exception-table.component"; +import { + StatisticUserSessionTableComponent +} from "./statistic/user/_component/session-table/statistic-user-session-table.component"; +import {DashboardComponent} from "./dashboard/dashboard.component"; @NgModule({ imports: [ From c5627d218cb02db614c59e7b74ddfd5c47c66cc4 Mon Sep 17 00:00:00 2001 From: fufuu Date: Wed, 14 Aug 2024 16:39:49 +0200 Subject: [PATCH 056/126] hotfix --- .../detail/session/_component/detail-session.component.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/views/detail/session/_component/detail-session.component.ts b/src/app/views/detail/session/_component/detail-session.component.ts index ee00de9..879506c 100644 --- a/src/app/views/detail/session/_component/detail-session.component.ts +++ b/src/app/views/detail/session/_component/detail-session.component.ts @@ -1,5 +1,5 @@ import {Component, inject, Input, OnInit} from "@angular/core"; -import {InstanceEnvironment, InstanceMainSession} from "../../../../model/trace.model"; +import {InstanceEnvironment, InstanceMainSession, InstanceRestSession} from "../../../../model/trace.model"; import {EnvRouter} from "../../../../service/router.service"; @Component({ @@ -10,7 +10,7 @@ import {EnvRouter} from "../../../../service/router.service"; export class DetailSessionComponent { private _router: EnvRouter = inject(EnvRouter); - @Input() session: InstanceMainSession; + @Input() session: InstanceMainSession | InstanceRestSession; @Input() instance: InstanceEnvironment; selectedRequest(event: { event: MouseEvent, row: any }) { From 263dc1e2d728ec236fb6a317eb539ecf5056cab9 Mon Sep 17 00:00:00 2001 From: fufuu Date: Wed, 14 Aug 2024 17:27:04 +0200 Subject: [PATCH 057/126] hotfix --- .../_component/detail-session.component.ts | 28 ++++++++++++------- .../views/search/main/search-main.view.html | 2 +- src/app/views/search/main/search-main.view.ts | 4 +-- 3 files changed, 21 insertions(+), 13 deletions(-) diff --git a/src/app/views/detail/session/_component/detail-session.component.ts b/src/app/views/detail/session/_component/detail-session.component.ts index 879506c..281ac7d 100644 --- a/src/app/views/detail/session/_component/detail-session.component.ts +++ b/src/app/views/detail/session/_component/detail-session.component.ts @@ -16,19 +16,21 @@ export class DetailSessionComponent { selectedRequest(event: { event: MouseEvent, row: any }) { if (event.row) { if (event.event.ctrlKey) { - this._router.open(`#/session/main/${event.row}`, '_blank',) + this._router.open(`#/session/rest/${event.row}`, '_blank',) } else { - this._router.navigate(['/session', 'main', event.row], { queryParams: { env: this.instance.env } }); // TODO remove env FIX BUG + this._router.navigate(['/session', 'rest', event.row], { queryParams: { env: this.instance.env } }); // TODO remove env FIX BUG } } } selectedFtp(event: { event: MouseEvent, row: any }) { // TODO finish this if (event.row) { + let segment = 'rest'; + if(this.session.type) segment = `main/${this.session.type.toLowerCase()}`; if (event.event.ctrlKey) { - this._router.open(`#/session/main/${this.session.id}/ftp/${event.row}`, '_blank',) + this._router.open(`#/session/${segment}/${this.session.id}/ftp/${event.row}`, '_blank',) } else { - this._router.navigate(['/session/main', this.session.id, 'ftp', event.row], { + this._router.navigate([`/session/${segment}`, this.session.id, 'ftp', event.row], { queryParams: { env: this.instance.env } }); } @@ -37,10 +39,12 @@ export class DetailSessionComponent { selectedLdap(event: { event: MouseEvent, row: any }) { // TODO finish this if (event.row) { + let segment = 'rest'; + if(this.session.type) segment = `main/${this.session.type.toLowerCase()}`; if (event.event.ctrlKey) { - this._router.open(`#/session/main/${this.session.id}/ldap/${event.row}`, '_blank',) + this._router.open(`#/session/${segment}/${this.session.id}/ldap/${event.row}`, '_blank',) } else { - this._router.navigate(['/session/main', this.session.id, 'ldap', event.row], { + this._router.navigate([`/session/${segment}`, this.session.id, 'ldap', event.row], { queryParams: { env: this.instance.env } }); } @@ -49,10 +53,12 @@ export class DetailSessionComponent { selectedSmtp(event: { event: MouseEvent, row: any }) { // TODO finish this if (event.row) { + let segment = 'rest'; + if(this.session.type) segment = `main/${this.session.type.toLowerCase()}`; if (event.event.ctrlKey) { - this._router.open(`#/session/main/${this.session.id}/smtp/${event.row}`, '_blank',) + this._router.open(`#/session/${segment}/${this.session.id}/smtp/${event.row}`, '_blank',) } else { - this._router.navigate(['/session/main', this.session.id, 'smtp', event.row], { + this._router.navigate([`/session/${segment}`, this.session.id, 'smtp', event.row], { queryParams: { env: this.instance.env } }); } @@ -61,10 +67,12 @@ export class DetailSessionComponent { selectedQuery(event: { event: MouseEvent, row: any }) { // TODO finish this if (event.row) { + let segment = 'rest'; + if(this.session.type) segment = `main/${this.session.type.toLowerCase()}`; if (event.event.ctrlKey) { - this._router.open(`#/session/main/${this.session.type}/${this.session.id}/database/${event.row}`, '_blank',) + this._router.open(`#/session/${segment}/${this.session.id}/database/${event.row}`, '_blank',) } else { - this._router.navigate(['/session/main', this.session.type, this.session.id, 'database', event.row], { + this._router.navigate([`/session/${segment}`, this.session.id, 'database', event.row], { queryParams: { env: this.instance.env } }); } diff --git a/src/app/views/search/main/search-main.view.html b/src/app/views/search/main/search-main.view.html index 0686838..83eabdd 100644 --- a/src/app/views/search/main/search-main.view.html +++ b/src/app/views/search/main/search-main.view.html @@ -1,4 +1,4 @@ - +
diff --git a/src/app/views/search/main/search-main.view.ts b/src/app/views/search/main/search-main.view.ts index 86f48b0..2b3dcac 100644 --- a/src/app/views/search/main/search-main.view.ts +++ b/src/app/views/search/main/search-main.view.ts @@ -53,9 +53,9 @@ export class SearchMainView implements OnInit, OnDestroy { this._activatedRoute.queryParams ]).subscribe({ next: ([params, queryParams]) => { + console.log(params.type_main, 'test') this.params.env = queryParams['env'] || application.default_env; - - this.params.type = params.type; + this.params.type = params.type_main; this.params.start = queryParams['start'] ? new Date(queryParams['start']) : (application.session.main.default_period || makePeriod(0, 1)).start; this.params.end = queryParams['end'] ? new Date(queryParams['end']) : (application.session.main.default_period || makePeriod(0, 1)).end; this.patchDateValue(this.params.start, new Date(this.params.end.getFullYear(), this.params.end.getMonth(), this.params.end.getDate() - 1)); From 65198fd2d9fda3d52308653bc5adc9d78309ec7e Mon Sep 17 00:00:00 2001 From: fufuu Date: Wed, 14 Aug 2024 17:46:31 +0200 Subject: [PATCH 058/126] evols duration --- .../views/detail/session/main/detail-session-main.view.html | 3 +++ .../views/detail/session/rest/detail-session-rest.view.html | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/app/views/detail/session/main/detail-session-main.view.html b/src/app/views/detail/session/main/detail-session-main.view.html index 9e342bf..653f6b3 100644 --- a/src/app/views/detail/session/main/detail-session-main.view.html +++ b/src/app/views/detail/session/main/detail-session-main.view.html @@ -37,6 +37,9 @@ le {{ (session.start * 1000) | date: 'dd/MM/yyyy à HH:mm:ss.SSS': 'fr' }}
+
+ en {{{ start: session.start, end: session.end } | duration}} +
diff --git a/src/app/views/detail/session/rest/detail-session-rest.view.html b/src/app/views/detail/session/rest/detail-session-rest.view.html index 7890f53..9254323 100644 --- a/src/app/views/detail/session/rest/detail-session-rest.view.html +++ b/src/app/views/detail/session/rest/detail-session-rest.view.html @@ -48,7 +48,7 @@
{{ session.inDataSize || 0 }}o swap_vert - {{ session.outDataSize }}o en {{ session.end - session.start | number :'1.2-3' }}s + {{ session.outDataSize }}o en {{{ start: session.start, end: session.end } | duration}}
From 9290dd9d97613919cc1fb45406cee77e95f28844 Mon Sep 17 00:00:00 2001 From: fufuu Date: Mon, 2 Sep 2024 17:13:06 +0200 Subject: [PATCH 059/126] env local --- angular.json | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/angular.json b/angular.json index 300f64c..1b0196a 100644 --- a/angular.json +++ b/angular.json @@ -53,6 +53,21 @@ "namedChunks": true }, "configurations": { + "local": { + "optimization": false, + "sourceMap": true, + "aot": true, + "extractLicenses": false, + "namedChunks": false, + "vendorChunk": false, + "buildOptimizer": false, + "fileReplacements": [ + { + "replace": "src/environments/environment.ts", + "with": "src/environments/environment.ts" + } + ] + }, "production": { "fileReplacements": [ { @@ -82,7 +97,7 @@ ] } }, - "defaultConfiguration": "" + "defaultConfiguration": "local" }, "serve": { "builder": "@angular-devkit/build-angular:dev-server", @@ -90,6 +105,9 @@ "browserTarget": "ng-admin-free:build" }, "configurations": { + "local": { + "browserTarget": "smart-ihm:build:local" + }, "production": { "browserTarget": "ng-admin-free:build:production" } From b47c1228b1bd6147a95c1a8b089a98de689fcf55 Mon Sep 17 00:00:00 2001 From: fufuu Date: Mon, 16 Sep 2024 09:38:44 +0200 Subject: [PATCH 060/126] refacto && v4 jquery --- src/app/app.component.ts | 12 +- src/app/app.module.ts | 14 +- src/app/model/jquery.model.ts | 7 + src/app/model/trace.model.ts | 6 + src/app/service/jquery.service.ts | 39 --- .../jquery/database-request.service.ts | 65 +++++ src/app/service/jquery/exception.service.ts | 33 +++ src/app/service/jquery/instance.service.ts | 42 ++++ src/app/service/jquery/jquery.service.ts | 14 ++ .../service/jquery/main-session.service.ts | 31 +++ .../service/jquery/rest-session.service.ts | 236 ++++++++++++++++++ src/app/service/trace.service.ts | 19 +- .../advanced-filter-modal.component.ts | 2 +- src/app/views/constants.ts | 12 +- .../detail/database/detail-database.view.ts | 15 +- src/app/views/detail/ldap/detail-ldap.view.ts | 8 +- .../detail-smtp-table.component.html | 4 +- .../main/detail-session-main.view.html | 8 +- .../rest/detail-session-rest.view.html | 8 +- src/app/views/detail/smtp/detail-smtp.view.ts | 8 +- src/app/views/search/main/search-main.view.ts | 15 +- src/app/views/search/rest/search-rest.view.ts | 25 +- .../statistic-exception-table.component.ts | 12 +- .../statistic-application.view.html | 30 +-- .../application/statistic-application.view.ts | 129 +++++----- .../database/statistic-database.view.html | 26 +- .../database/statistic-database.view.ts | 54 +--- .../statistic/rest/statistic-rest.view.html | 32 +-- .../statistic/rest/statistic-rest.view.ts | 145 ++++++----- .../statistic/user/statistic-user.view.ts | 32 +-- 30 files changed, 715 insertions(+), 368 deletions(-) create mode 100644 src/app/model/jquery.model.ts delete mode 100644 src/app/service/jquery.service.ts create mode 100644 src/app/service/jquery/database-request.service.ts create mode 100644 src/app/service/jquery/exception.service.ts create mode 100644 src/app/service/jquery/instance.service.ts create mode 100644 src/app/service/jquery/jquery.service.ts create mode 100644 src/app/service/jquery/main-session.service.ts create mode 100644 src/app/service/jquery/rest-session.service.ts diff --git a/src/app/app.component.ts b/src/app/app.component.ts index f01a99c..633317c 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -3,9 +3,9 @@ import {FormControl} from '@angular/forms'; import {ActivatedRoute} from '@angular/router'; import {distinctUntilChanged, finalize, Subscription} from 'rxjs'; import {application, environment} from 'src/environments/environment'; -import {JQueryService} from './service/jquery.service'; import {EnvRouter} from "./service/router.service"; import {Constants} from "./views/constants"; +import {InstanceService} from "./service/jquery/instance.service"; @Component({ @@ -15,7 +15,7 @@ import {Constants} from "./views/constants"; }) export class AppComponent implements OnInit, OnDestroy { private _activatedRoute: ActivatedRoute = inject(ActivatedRoute); - private _service: JQueryService = inject(JQueryService); + private _service: InstanceService = inject(InstanceService); private _router: EnvRouter = inject(EnvRouter); MAPPING_TYPE = Constants.MAPPING_TYPE; @@ -27,14 +27,10 @@ export class AppComponent implements OnInit, OnDestroy { constructor() { this.isLoadingEnv = true; - this.subscriptions.push(this._service.getInstance({ - 'column.distinct': 'environement', - 'environement.not': 'null', - 'order': 'environement.asc' - }) + this.subscriptions.push(this._service.getEnvironments() .pipe(finalize(() => this.isLoadingEnv = false)) .subscribe({ - next: (res: { environement: string }[]) => { + next: res => { this.envs = res.map(r => r.environement); } })); diff --git a/src/app/app.module.ts b/src/app/app.module.ts index d93e32d..7f4fcc3 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -157,36 +157,36 @@ const routes: Route[] = [ ] }, { - path: 'statistic', + path: 'dashboard', children: [ { - path: 'app/:name', + path: 'server/:server_name', component: StatisticApplicationView, title: 'Statistiques Serveur' }, { - path: 'rest/:name', + path: 'server/:server_name/rest/:rest_name', component: StatisticRestView, title: 'Statistiques API' }, { - path: 'user/:name', + path: 'user/:user_name', component: StatisticUserView, title: 'Statistiques Utilisateur' }, { - path: 'database/:name', + path: 'database/:database_name', component: StatisticDatabaseView, title: 'Statistiques Base de Donnée' }, { path: '**', pathMatch: 'full', redirectTo: `/session/rest` } ] }, - { + /*{ path: 'dashboard', component: DashboardComponent, title: 'Dashboard' - }, + },*/ { path: '**', pathMatch: 'full', redirectTo: `/session/rest` } ]; diff --git a/src/app/model/jquery.model.ts b/src/app/model/jquery.model.ts new file mode 100644 index 0000000..be9caca --- /dev/null +++ b/src/app/model/jquery.model.ts @@ -0,0 +1,7 @@ +export type RepartitionTimeAndTypeResponse = {elapsedTimeSlowest: number, elapsedTimeSlow: number, elapsedTimeMedium: number, elapsedTimeFast: number, elapsedTimeFastest: number, countSucces: number, countErrorServer: number, countErrorClient: number}[]; +export type RepartitionTimeAndTypeResponseByPeriod = {countSucces: number, countErrorClient: number, countErrorServer: number, elapsedTimeSlowest: number, elapsedTimeSlow: number, elapsedTimeMedium: number, elapsedTimeFast: number, elapsedTimeFastest: number, avg: number, max: number, date: number, year: number}[]; +export type RepartitionRequestByPeriod = {count: number, countErrorServer: number, countSlowest: number, date: number}[]; + + + + diff --git a/src/app/model/trace.model.ts b/src/app/model/trace.model.ts index e64cce3..6f9932f 100644 --- a/src/app/model/trace.model.ts +++ b/src/app/model/trace.model.ts @@ -73,6 +73,8 @@ export interface FtpRequest extends SessionStage { serverVersion: string; clientVersion: string; actions: Array; + + completed: boolean; } export interface MailRequest extends SessionStage { @@ -80,6 +82,8 @@ export interface MailRequest extends SessionStage { port: number; actions: Array; mails: Array; + + completed: boolean; } export interface LocalRequest extends SessionStage { @@ -93,6 +97,8 @@ export interface NamingRequest extends SessionStage { host: string; port: number; actions: Array; + + completed: boolean; } export interface DatabaseRequestStage extends RequestStage { diff --git a/src/app/service/jquery.service.ts b/src/app/service/jquery.service.ts deleted file mode 100644 index 8dc3a98..0000000 --- a/src/app/service/jquery.service.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { HttpClient } from "@angular/common/http"; -import { Injectable } from "@angular/core"; - -@Injectable({ providedIn: 'root' }) -export class JQueryService { - constructor(private http: HttpClient) { - - } - - getJqueryData(endpoint:string, params: any) { - let url = `${localStorage.getItem('server')}/jquery/${endpoint}`; - return this.http.get(url, { params: params }); - } - - getRestSession(params: any) { - let url = `${localStorage.getItem('server')}/jquery/session/rest`; - return this.http.get(url, { params: params }); - } - - getMainSession(params: any) { - let url = `${localStorage.getItem('server')}/jquery/session/main`; - return this.http.get(url, { params: params }); - } - - getDatabaseRequest(params: any) { - let url = `${localStorage.getItem('server')}/jquery/request/database`; - return this.http.get(url, { params: params }); - } - - getException(params: any) { - let url = `${localStorage.getItem('server')}/jquery/exception`; - return this.http.get(url, { params: params }); - } - - getInstance(params: any) { - let url = `${localStorage.getItem('server')}/jquery/instance`; - return this.http.get(url, { params: params }); - } -} \ No newline at end of file diff --git a/src/app/service/jquery/database-request.service.ts b/src/app/service/jquery/database-request.service.ts new file mode 100644 index 0000000..ab1405a --- /dev/null +++ b/src/app/service/jquery/database-request.service.ts @@ -0,0 +1,65 @@ +import {Injectable} from "@angular/core"; +import {HttpClient} from "@angular/common/http"; +import {Observable} from "rxjs"; +import {RepartitionRequestByPeriod} from "../../model/jquery.model"; + +@Injectable({ providedIn: 'root' }) +export class DatabaseRequestService { + constructor(private http: HttpClient) { + + } + + getDatabaseRequest(params: any): Observable { + let url = `${localStorage.getItem('server')}/jquery/request/database`; + return this.http.get(url, { params: params }); + } + + getRepartitionRequestByPeriod(filters: {now: Date, database: string, env: string}): Observable { + let start = new Date(filters.now.getFullYear(), filters.now.getMonth(), filters.now.getDate() - 6).toISOString(); + let end = filters.now.toISOString(); + let args: any = { + 'column': "count:count,count_error_server:countErrorServer,count_slowest:countSlowest,start.date:date", + 'parent': 'rest_session.id', + 'rest_session.start.ge': start, + 'rest_session.start.lt': end, + 'rest_session.instance_env': 'instance.id', + 'instance.environement': filters.env, + 'start.ge': start, + 'start.lt': end, + 'db': filters.database, + 'order': 'date.asc' + } + return this.getDatabaseRequest(args); + } + + getRepartitionTime(filters: {start: Date, end: Date, database: string, env: string}): Observable<{elapsedTimeSlowest: number, elapsedTimeSlow: number, elapsedTimeMedium: number, elapsedTimeFast: number, elapsedTimeFastest: number}[]> { + let args: any = { + 'column': 'count_slowest:elapsedTimeSlowest,count_slow:elapsedTimeSlow,count_medium:elapsedTimeMedium,count_fast:elapsedTimeFast,count_fastest:elapsedTimeFastest', + 'parent': 'rest_session.id', + 'rest_session.start.ge': filters.start, + 'rest_session.start.lt': filters.end, + 'rest_session.instance_env': 'instance.id', + 'instance.environement': filters.env, + 'start.ge': filters.start.toISOString(), + 'start.lt': filters.end.toISOString(), + 'db': filters.database + } + return this.getDatabaseRequest(args); + } + + getRepartitionTimeByPeriod(filters: {start: Date, end: Date, groupedBy: string, database: string, env: string}): Observable<{elapsedTimeSlowest: number, elapsedTimeSlow: number, elapsedTimeMedium: number, elapsedTimeFast: number, elapsedTimeFastest: number, avg: number, max: number, date: number, year: number}[]> { + let args: any = { + 'column': `count_slowest:elapsedTimeSlowest,count_slow:elapsedTimeSlow,count_medium:elapsedTimeMedium,count_fast:elapsedTimeFast,count_fastest:elapsedTimeFastest,elapsedtime.avg:avg,elapsedtime.max:max,start.${filters.groupedBy}:date,start.year:year`, + 'parent': 'rest_session.id', + 'rest_session.start.ge': filters.start, + 'rest_session.start.lt': filters.end, + 'rest_session.instance_env': 'instance.id', + 'instance.environement': filters.env, + 'start.ge': filters.start.toISOString(), + 'start.lt': filters.end.toISOString(), + 'db': filters.database, + 'order': `year.asc,date.asc` + } + return this.getDatabaseRequest(args); + } +} \ No newline at end of file diff --git a/src/app/service/jquery/exception.service.ts b/src/app/service/jquery/exception.service.ts new file mode 100644 index 0000000..d29595e --- /dev/null +++ b/src/app/service/jquery/exception.service.ts @@ -0,0 +1,33 @@ +import {Injectable} from "@angular/core"; +import {HttpClient} from "@angular/common/http"; +import {Observable} from "rxjs"; + +@Injectable({ providedIn: 'root' }) +export class ExceptionService { + constructor(private http: HttpClient) { + + } + + getException(params: any): Observable { + let url = `${localStorage.getItem('server')}/jquery/exception`; + return this.http.get(url, { params: params }); + } + + getDatabaseException(filters: {start: Date, end: Date, database: string, env: string}): Observable<{count: number, errType: string, errMsg: string}[]> { + let args = { + 'column': 'count:count,err_type:errType,err_msg:errMsg', + 'parent': 'database_request.id', + 'database_request.db': filters.database, + 'database_request.start.ge': filters.start.toISOString(), + 'database_request.start.lt': filters.end.toISOString(), + 'database_request.parent': 'rest_session.id', + 'rest_session.start.ge': filters.start.toISOString(), + 'rest_session.start.lt': filters.end.toISOString(), + 'rest_session.instance_env': 'instance.id', + 'instance.environement': filters.env, + 'type': 'JDBC', + 'order': 'count.desc' + } + return this.getException(args); + } +} \ No newline at end of file diff --git a/src/app/service/jquery/instance.service.ts b/src/app/service/jquery/instance.service.ts new file mode 100644 index 0000000..93f548c --- /dev/null +++ b/src/app/service/jquery/instance.service.ts @@ -0,0 +1,42 @@ +import {Injectable} from "@angular/core"; +import {HttpClient} from "@angular/common/http"; +import {Observable} from "rxjs"; + +@Injectable({ providedIn: 'root' }) +export class InstanceService { + constructor(private http: HttpClient) { + + } + + getInstance(params: any): Observable { + let url = `${localStorage.getItem('server')}/jquery/instance`; + return this.http.get(url, { params: params }); + } + + getIds(env: string, end: Date, appName: string): Observable<{id: string}[]> { + let args: any = { + 'column.distinct': 'id', + 'app_name.in': `"${appName}"`, + 'environement': env, + 'start.lt': end.toISOString(), + } + return this.getInstance(args); + } + + getEnvironments(): Observable<{environement: string}[]> { + let args = { + 'column.distinct': 'environement', + 'environement.notNull': '', + 'order': 'environement.asc' + } + return this.getInstance(args); + } + + getApplications(): Observable<{appName: string}[]> { + let args = { + 'column.distinct': 'app_name:appName', + 'order': 'app_name.asc' + } + return this.getInstance(args); + } +} \ No newline at end of file diff --git a/src/app/service/jquery/jquery.service.ts b/src/app/service/jquery/jquery.service.ts new file mode 100644 index 0000000..82cc57c --- /dev/null +++ b/src/app/service/jquery/jquery.service.ts @@ -0,0 +1,14 @@ +import {HttpClient} from "@angular/common/http"; +import {Injectable} from "@angular/core"; + +@Injectable({ providedIn: 'root' }) +export class JQueryService { + constructor(private http: HttpClient) { + + } + + getJqueryData(endpoint:string, params: any) { + let url = `${localStorage.getItem('server')}/jquery/${endpoint}`; + return this.http.get(url, { params: params }); + } +} \ No newline at end of file diff --git a/src/app/service/jquery/main-session.service.ts b/src/app/service/jquery/main-session.service.ts new file mode 100644 index 0000000..e0a3440 --- /dev/null +++ b/src/app/service/jquery/main-session.service.ts @@ -0,0 +1,31 @@ +import {Injectable} from "@angular/core"; +import {HttpClient} from "@angular/common/http"; +import {Observable} from "rxjs"; +import {FilterMap} from "../../views/constants"; + +@Injectable({ providedIn: 'root' }) +export class MainSessionService { + constructor(private http: HttpClient) { + + } + + getMainSession(params: any): Observable { + let url = `${localStorage.getItem('server')}/jquery/session/main`; + return this.http.get(url, { params: params }); + } + + getInfos(filters: {start: Date, end: Date, advancedParams: FilterMap, user: string, env: string}): Observable<{name: string, date: number, elapsedtime: number, location: string, appName: string}[]> { + let args = { + 'column': "name:name,start:date,elapsedtime:elapsedtime,location:location,instance.app_name:appName", + 'main_session.instance_env': 'instance.id', + 'user': filters.user, + 'start.ge': filters.start.toISOString(), + 'start.lt': filters.end.toISOString(), + 'instance.environement': filters.env, + 'type': 'VIEW', + 'order': 'date.desc', + ...filters.advancedParams + } + return this.getMainSession(args) + } +} \ No newline at end of file diff --git a/src/app/service/jquery/rest-session.service.ts b/src/app/service/jquery/rest-session.service.ts new file mode 100644 index 0000000..14a1954 --- /dev/null +++ b/src/app/service/jquery/rest-session.service.ts @@ -0,0 +1,236 @@ +import {Injectable} from "@angular/core"; +import {HttpClient} from "@angular/common/http"; +import {Observable} from "rxjs"; +import {FilterMap} from "../../views/constants"; +import { + RepartitionRequestByPeriod, + RepartitionTimeAndTypeResponse, + RepartitionTimeAndTypeResponseByPeriod +} from "../../model/jquery.model"; + +@Injectable({ providedIn: 'root' }) +export class RestSessionService { + constructor(private http: HttpClient) { + + } + + getRestSession(params: any): Observable { + let url = `${localStorage.getItem('server')}/jquery/session/rest`; + return this.http.get(url, { params: params }); + } + + getRepartitionTimeAndTypeResponse(filters: {start: Date, end: Date, advancedParams: FilterMap, ids: string }): Observable; + getRepartitionTimeAndTypeResponse(filters: {start: Date, end: Date, advancedParams: FilterMap, ids: string, apiName: string}): Observable; + getRepartitionTimeAndTypeResponse(filters: {start: Date, end: Date, advancedParams: FilterMap, user: string, env: string}): Observable; + getRepartitionTimeAndTypeResponse(filters: {start: Date, end: Date, advancedParams: FilterMap, ids: string, apiName: string, user: string, env: string}): Observable { + let args: any = { + 'column': 'count_slowest:elapsedTimeSlowest,count_slow:elapsedTimeSlow,count_medium:elapsedTimeMedium,count_fast:elapsedTimeFast,count_fastest:elapsedTimeFastest,count_succes:countSucces,count_error_server:countErrorServer,count_error_client:countErrorClient', + 'start.ge': filters.start.toISOString(), + 'start.lt': filters.end.toISOString(), + ...filters.advancedParams + } + if(filters.ids) { + args['instance_env.in'] = filters.ids; + if (filters.apiName) { + args['api_name'] = `"${filters.apiName}"`; + } + } else { + args['instance_env'] = 'instance.id'; + args['instance.environement'] = filters.env; + if (filters.user) { + args['user'] = filters.user; + } + } + return this.getRestSession(args); + } + + getRepartitionTimeAndTypeResponseByPeriod(filters: {start: Date, end: Date, groupedBy: string, advancedParams: FilterMap, ids: string}): Observable + getRepartitionTimeAndTypeResponseByPeriod(filters: {start: Date, end: Date, groupedBy: string, advancedParams: FilterMap, ids: string, apiName: string}): Observable + getRepartitionTimeAndTypeResponseByPeriod(filters: {start: Date, end: Date, groupedBy: string, advancedParams: FilterMap, user: string, env: string}): Observable + getRepartitionTimeAndTypeResponseByPeriod(filters: {start: Date, end: Date, groupedBy: string, advancedParams: FilterMap, ids: string, apiName: string, user: string, env: string}): Observable { + let args: any = { + 'column': `count_succes:countSucces,count_error_client:countErrorClient,count_error_server:countErrorServer,count_slowest:elapsedTimeSlowest,count_slow:elapsedTimeSlow,count_medium:elapsedTimeMedium,count_fast:elapsedTimeFast,count_fastest:elapsedTimeFastest,elapsedtime.avg:avg,elapsedtime.max:max,start.${filters.groupedBy}:date,start.year:year`, + 'start.ge': filters.start.toISOString(), + 'start.lt': filters.end.toISOString(), + 'order': `year.asc,date.asc`, + ...filters.advancedParams + } + if(filters.ids) { + args['instance_env.in'] = filters.ids; + if (filters.apiName) { + args['api_name'] = `"${filters.apiName}"`; + } + } else { + args['instance_env'] = 'instance.id'; + args['instance.environement'] = filters.env; + if (filters.user) { + args['user'] = filters.user; + } + } + return this.getRestSession(args); + } + + getRepartitionRequestByPeriod(filters: {now: Date, advancedParams: FilterMap, ids: string}): Observable; + getRepartitionRequestByPeriod(filters: {now: Date, advancedParams: FilterMap, ids: string, apiName: string}): Observable; + getRepartitionRequestByPeriod(filters: {now: Date, advancedParams: FilterMap, user: string, env: string}): Observable; + getRepartitionRequestByPeriod(filters: {now: Date, advancedParams: FilterMap, ids: string, apiName: string, user: string, env: string}): Observable { + let args: any = { + 'column': "count:count,count_error_server:countErrorServer,count_slowest:countSlowest,start.date:date", + 'start.ge': new Date(filters.now.getFullYear(), filters.now.getMonth(), filters.now.getDate() - 6).toISOString(), + 'start.lt': filters.now.toISOString(), + 'order': 'date.asc', + ...filters.advancedParams + } + if(filters.ids) { + args['instance_env.in'] = filters.ids; + if (filters.apiName) { + args['api_name'] = `"${filters.apiName}"`; + } + } else { + args['instance_env'] = 'instance.id'; + args['instance.environement'] = filters.env; + if (filters.user) { + args['user'] = filters.user; + } + } + return this.getRestSession(args); + } + + getRepartitionUser(filters: {start: Date, end: Date, advancedParams: FilterMap, ids: string}): Observable<{count: number, user: string}[]>; + getRepartitionUser(filters: {start: Date, end: Date, advancedParams: FilterMap, ids: string, apiName: string}): Observable<{count: number, user: string}[]>; + getRepartitionUser(filters: {start: Date, end: Date, advancedParams: FilterMap, ids: string, apiName: string}): Observable<{count: number, user: string}[]> { + let args: any = { + 'column': 'count:count,user', + 'instance_env.in': filters.ids, + 'start.ge': filters.start.toISOString(), + 'start.lt': filters.end.toISOString(), + 'user.notNull': '', + 'order': 'count.desc', + 'fetch': 5, + ...filters.advancedParams + } + if (filters.apiName) { + args['api_name'] = `"${filters.apiName}"`; + } + return this.getRestSession(args); + } + + getRepartitionUserByPeriod(filters: {users: string, start: Date, end: Date, groupedBy: string, advancedParams: FilterMap, ids: string}): Observable<{count: number, date: number, year: number, user: string}[]>; + getRepartitionUserByPeriod(filters: {users: string, start: Date, end: Date, groupedBy: string, advancedParams: FilterMap, ids: string, apiName: string}): Observable<{count: number, date: number, year: number, user: string}[]>; + getRepartitionUserByPeriod(filters: {users: string, start: Date, end: Date, groupedBy: string, advancedParams: FilterMap, ids: string, apiName: string}): Observable<{count: number, date: number, year: number, user: string}[]> { + let args: any = { + 'column': `count:count,start.${filters.groupedBy}:date,start.year:year,user`, + 'instance_env.in': filters.ids, + 'start.ge': filters.start.toISOString(), + 'start.lt': filters.end.toISOString(), + 'user.notNull': '', + 'order': `year.asc,date.asc`, + ...filters.advancedParams + } + if(filters.apiName) { + args['api_name'] = `"${filters.apiName}"`; + } + if(filters.users) { + args['user.in'] = filters.users; + } + return this.getRestSession(args); + } + + getRepartitionApi(filters: {start: Date, end: Date, advancedParams: FilterMap, ids: string}): Observable<{countSucces: number, countErrorClient: number, countErrorServer: number, apiName: string}[]>; + getRepartitionApi(filters: {start: Date, end: Date, advancedParams: FilterMap, user: string, env: string}): Observable<{countSucces: number, countErrorClient: number, countErrorServer: number, apiName: string}[]>; + getRepartitionApi(filters: {start: Date, end: Date, advancedParams: FilterMap, ids: string, user: string, env: string}): Observable<{countSucces: number, countErrorClient: number, countErrorServer: number, apiName: string}[]> { + let args: any = { + 'column': 'count_succes:countSucces,count_error_client:countErrorClient,count_error_server:countErrorServer,api_name', + 'start.ge': filters.start.toISOString(), + 'start.lt': filters.end.toISOString(), + 'api_name.notNull': '', + 'order': 'count.desc', + 'fetch': 5, + ...filters.advancedParams + } + if(filters.ids) { + args['instance_env.in'] = filters.ids; + } else { + args['instance_env'] = 'instance.id'; + args['instance.environement'] = filters.env; + if (filters.user) { + args['user'] = filters.user; + } + } + return this.getRestSession(args); + } + + getDependencies(filters: {start: Date, end: Date, advancedParams: FilterMap, ids: string}): Observable<{count: number, countSucces: number, countErrClient: number, countErrServer: number, name: string}[]>; + getDependencies(filters: {start: Date, end: Date, advancedParams: FilterMap, ids: string, apiName: string}): Observable<{count: number, countSucces: number, countErrClient: number, countErrServer: number, name: string}[]> ; + getDependencies(filters: {start: Date, end: Date, advancedParams: FilterMap, ids: string, apiName: string}): Observable<{count: number, countSucces: number, countErrClient: number, countErrServer: number, name: string}[]> { + let args: any = { + 'column': 'count:count,count_succes:countSucces,count_error_client:countErrClient,count_error_server:countErrServer,instance.app_name:name', + 'instance.id': 'instance_env', + 'id': 'rest_request.parent', + 'rest_request.remote': 'rest_session_join.id', + 'rest_session_join.start.ge': filters.start.toISOString(), + 'rest_session_join.start.lt': filters.end.toISOString(), + 'rest_session_join.instance_env.in': filters.ids, + 'start.ge': filters.start.toISOString(), + 'start.lt': filters.end.toISOString(), + 'view': 'rest_session:rest_session_join', + 'order': 'count.desc', + ...filters.advancedParams + } + if(filters.apiName) { + args['rest_session_join.api_name'] = `"${filters.apiName}"`; + args['rest_session_join.api_name.notNull'] = ``; + } + return this.getRestSession(args); + } + + getDependents(filters: {start: Date, end: Date, advancedParams: FilterMap, ids: string}): Observable<{count: number, countSucces: number, countErrClient: number, countErrServer: number, name: string}[]>; + getDependents(filters: {start: Date, end: Date, advancedParams: FilterMap, ids: string, apiName: string}): Observable<{count: number, countSucces: number, countErrClient: number, countErrServer: number, name: string}[]>; + getDependents(filters: {start: Date, end: Date, advancedParams: FilterMap, ids: string, apiName: string}): Observable<{count: number, countSucces: number, countErrClient: number, countErrServer: number, name: string}[]> { + let args: any = { + 'column': 'rest_session_join.count:count,rest_session_join.count_succes:countSucces,rest_session_join.count_error_client:countErrClient,rest_session_join.count_error_server:countErrServer,instance_join.app_name:name', + 'id': 'rest_request.parent', + 'rest_request.remote': 'rest_session_join.id', + 'rest_session_join.instance_env': 'instance_join.id', + 'rest_session_join.start.ge': filters.start.toISOString(), + 'rest_session_join.start.lt': filters.end.toISOString(), + 'start.ge': filters.start.toISOString(), + 'start.lt': filters.end.toISOString(), + 'instance_env.in': filters.ids, + 'view': 'rest_session:rest_session_join,instance:instance_join', + 'order': 'count.desc', + ...filters.advancedParams + } + if(filters.apiName) { + args['api_name'] = `"${filters.apiName}"`; + args['api_name.notNull'] = ``; + } + return this.getRestSession(args); + } + + getExceptions(filters: {start: Date, end: Date, advancedParams: FilterMap, ids: string}): Observable<{count: number, errType: string, errMsg: string}[]>; + getExceptions(filters: {start: Date, end: Date, advancedParams: FilterMap, ids: string, apiName: string}): Observable<{count: number, errType: string, errMsg: string}[]>; + getExceptions(filters: {start: Date, end: Date, advancedParams: FilterMap, user: string, env: string}): Observable<{count: number, errType: string, errMsg: string}[]>; + getExceptions(filters: {start: Date, end: Date, advancedParams: FilterMap, ids: string, apiName: string, user: string, env: string}): Observable<{count: number, errType: string, errMsg: string}[]> { + let args: any = { + 'column': 'count:count,err_type,err_msg', + 'status.ge': 500, + 'start.ge': filters.start.toISOString(), + 'start.lt': filters.end.toISOString(), + 'order': 'count.desc', + 'fetch': 5, + ...filters.advancedParams + } + if(filters.ids) { + args['instance_env.in'] = filters.ids; + if(filters.apiName) args['api_name'] = `"${filters.apiName}"`; + } else { + args['instance_env'] = 'instance.id'; + args['instance.environement'] = filters.env; + if (filters.user) { + args['user'] = filters.user; + } + } + return this.getRestSession(args); + } +} \ No newline at end of file diff --git a/src/app/service/trace.service.ts b/src/app/service/trace.service.ts index 8e59958..c3fb5ed 100644 --- a/src/app/service/trace.service.ts +++ b/src/app/service/trace.service.ts @@ -1,16 +1,21 @@ -import { HttpClient, HttpErrorResponse } from "@angular/common/http"; -import { Injectable } from "@angular/core"; -import { Observable, catchError, throwError } from "rxjs"; +import {HttpClient} from "@angular/common/http"; +import {Injectable} from "@angular/core"; +import {Observable} from "rxjs"; import { DatabaseRequest, DatabaseRequestStage, - FtpRequest, FtpRequestStage, + FtpRequest, + FtpRequestStage, InstanceEnvironment, InstanceMainSession, InstanceRestSession, - LocalRequest, Mail, MailRequest, MailRequestStage, NamingRequest, NamingRequestStage, - RestRequest, - RestSession + LocalRequest, + Mail, + MailRequest, + MailRequestStage, + NamingRequest, + NamingRequestStage, + RestRequest } from "../model/trace.model"; @Injectable({ providedIn: 'root' }) diff --git a/src/app/shared/_component/advanced-filter/advanced-filter-modal/advanced-filter-modal.component.ts b/src/app/shared/_component/advanced-filter/advanced-filter-modal/advanced-filter-modal.component.ts index c3a58f3..c7b92dc 100644 --- a/src/app/shared/_component/advanced-filter/advanced-filter-modal/advanced-filter-modal.component.ts +++ b/src/app/shared/_component/advanced-filter/advanced-filter-modal/advanced-filter-modal.component.ts @@ -5,7 +5,7 @@ import { MAT_DIALOG_DATA, MatDialogRef } from "@angular/material/dialog"; import { Filter, FilterMap, FilterPreset } from "src/app/views/constants"; import { COMMA, ENTER } from '@angular/cdk/keycodes'; import { Subscription, catchError, finalize, of } from "rxjs"; -import { JQueryService } from "src/app/service/jquery.service"; +import { JQueryService } from "src/app/service/jquery/jquery.service"; import { MatAutocompleteSelectedEvent } from "@angular/material/autocomplete"; import { FilterService } from "src/app/service/filter.service"; diff --git a/src/app/views/constants.ts b/src/app/views/constants.ts index 6e83540..09fe6f6 100644 --- a/src/app/views/constants.ts +++ b/src/app/views/constants.ts @@ -418,8 +418,8 @@ export class FilterConstants { { key: 'status', label: 'Status', type: 'select', row: 3, col: 1, endpoint: "session/rest", query: { 'column.distinct': 'status:status', 'order': 'status.asc' }, op: Operation.eq }, { key: 'method', label: 'Method', type: 'select', width: 20, row: 1, col: 1, endpoint: "session/rest", query: { 'column.distinct': 'method:method', 'order': 'method.asc' }, op: Operation.eq }, { key: 'path', label: 'Path', type: 'input', row: 1, col: 2, op: Operation.like }, - { key: 'api_name', label: 'Nom API', type: 'select', row: 3, col: 2, endpoint: "session/rest", query: { 'column.distinct': 'api_name.coalesce(null):api_name', 'api_name.not': 'null', 'order': 'api_name.coalesce(null).asc' }, op: Operation.eq }, - { key: 'user', label: 'Utilisateur', type: 'select', row: 3, col: 3, endpoint: "session/rest", query: { 'column.distinct': 'user.coalesce(null)', 'user.not': 'null', 'order': 'user.coalesce(null).asc' }, op: Operation.eq } + { key: 'api_name', label: 'Nom API', type: 'select', row: 3, col: 2, endpoint: "session/rest", query: { 'column.distinct': 'api_name', 'api_name.notNull': '', 'order': 'api_name.asc' }, op: Operation.eq }, + { key: 'user', label: 'Utilisateur', type: 'select', row: 3, col: 3, endpoint: "session/rest", query: { 'column.distinct': 'user', 'user.notNull': '', 'order': 'user.asc' }, op: Operation.eq } // new Filter("err_type", "Exception", 'select', 50, "/stat/apisession", null, null, { 'column.distinct': 'err_type:err_type', 'order': 'err_type.asc' }), // new Filter("address", "adresse", 'input', 50), // new Filter("os", "OS", 'select', 50, "/stat/apisession", null, null, { 'column.distinct': 'os', 'order': 'os.asc' }), @@ -430,9 +430,9 @@ export class FilterConstants { ] static readonly SESSION_MAIN: Filter[] = [ - { key: 'name', label: 'Serveur', type: 'select', row: 2, col: 1, endpoint: 'session/main', query: { 'column.distinct': 'name.coalesce(null)', 'name.not': 'null', 'order': 'name.coalesce(null).asc' }, op: Operation.eq }, + { key: 'name', label: 'Serveur', type: 'select', row: 2, col: 1, endpoint: 'session/main', query: { 'column.distinct': 'name', 'name.notNull': '', 'order': 'name.asc' }, op: Operation.eq }, { key: 'location', label: 'Chemin', type: 'input', row: 1, col: 1, op: Operation.like }, - { key: 'user', label: 'Utilisateur', type: 'select', row: 2, col: 2, endpoint: 'session/main', query: { 'column.distinct': 'user.coalesce(null)', 'user.not': 'null', 'order': 'user.coalesce(null).asc' }, op: Operation.eq } + { key: 'user', label: 'Utilisateur', type: 'select', row: 2, col: 2, endpoint: 'session/main', query: { 'column.distinct': 'user', 'user.notNull': '', 'order': 'user.asc' }, op: Operation.eq } // new Filter("err_type", "Exception", 'select', 50, "/stat/mainsession", null, null, { 'column.distinct': 'err_type:err_type', 'order': 'err_type.asc' }), // new Filter("os", "OS", 'select', 50, "/stat/mainsession", null, null, { 'column.distinct': 'os', 'order': 'os.asc' }), @@ -442,7 +442,7 @@ export class FilterConstants { static readonly STATS_API: Filter[] = [ { key: 'query', label: 'Query params', type: 'input', row: 1, col: 1, op: Operation.like }, { key: 'status', label: 'Status', type: 'select', row: 2, col: 1, options: [{ status: '200' }, { status: '201' }, { status: '202' }, { status: '400' }, { status: '401' }, { status: '403' }, { status: '404' }, { status: '405' }, { status: '409' }, { status: '415' }, { status: '500' }, { status: '503' }], op: Operation.eq }, - { key: 'user', label: 'Utilisateur', type: 'select', row: 2, col: 2, endpoint: 'session/rest', query: { 'column.distinct': 'user.coalesce(null)', 'user.not': 'null', 'order': 'user.coalesce(null).asc' }, op: Operation.eq }, + { key: 'user', label: 'Utilisateur', type: 'select', row: 2, col: 2, endpoint: 'session/rest', query: { 'column.distinct': 'user', 'user.notNull': '', 'order': 'user.asc' }, op: Operation.eq }, //new Filter("os", "OS", 'select', 50, "/stat/apisession", null, null, { 'column.distinct': 'os', 'order': 'os.asc' }), //new Filter("re", "RE", 'select', 50, "/stat/apisession", null, null, { 'column.distinct': 're', 'order': 're.asc' }), //new Filter("err_type", "Exception", 'select', 50, "/stat/apisession", null, null, { 'column.distinct': 'err_type:err_type', 'order': 'err_type.asc' }), @@ -453,7 +453,7 @@ export class FilterConstants { { key: 'query', label: 'Query params', type: 'input', row: 1, col: 2, op: Operation.like }, { key: 'method', label: 'Method', type: 'select', width: 20, row: 1, col: 1, options: [{ method: 'GET' }, { method: 'PUT' }, { method: 'POST' }, { method: 'DELETE' }, { method: 'OPTIONS' }], op: Operation.eq }, { key: 'status', label: 'Status', type: 'select', row: 3, col: 1, options: [{ status: '200' }, { status: '201' }, { status: '202' }, { status: '400' }, { status: '401' }, { status: '403' }, { status: '404' }, { status: '405' }, { status: '409' }, { status: '415' }, { status: '500' }, { status: '503' }], op: Operation.eq }, - { key: 'user', label: 'Utilisateur', type: 'select', row: 3, col: 2, endpoint: 'session/rest', query: { 'column.distinct': 'user.coalesce(null)', 'user.not': 'null', 'order': 'user.coalesce(null).asc' }, op: Operation.eq }, + { key: 'user', label: 'Utilisateur', type: 'select', row: 3, col: 2, endpoint: 'session/rest', query: { 'column.distinct': 'user', 'user.notNull': '', 'order': 'user.asc' }, op: Operation.eq }, { key: 'path', label: 'Path', type: 'input', row: 2, col: 1, op: Operation.like } //new Filter("os", "OS", 'select', 50, "/stat/apisession", null, null, { 'column.distinct': 'os', 'order': 'os.asc' }), diff --git a/src/app/views/detail/database/detail-database.view.ts b/src/app/views/detail/database/detail-database.view.ts index 0df574d..0132b0c 100644 --- a/src/app/views/detail/database/detail-database.view.ts +++ b/src/app/views/detail/database/detail-database.view.ts @@ -1,22 +1,13 @@ -import {Component, ElementRef, inject, NgZone, OnDestroy, OnInit, ViewChild} from '@angular/core'; +import {Component, ElementRef, inject, OnDestroy, OnInit, ViewChild} from '@angular/core'; import {ActivatedRoute} from '@angular/router'; import {combineLatest, finalize, forkJoin, Subscription} from "rxjs"; import {DataItem, Timeline} from 'vis-timeline'; -import {Utils} from 'src/app/shared/util'; -import {DatePipe, Location} from '@angular/common'; +import {DatePipe} from '@angular/common'; import {TraceService} from 'src/app/service/trace.service'; import {application} from 'src/environments/environment'; -import { - DatabaseRequest, - DatabaseRequestStage, - ExceptionInfo, - Mail, - MailRequest, - MailRequestStage -} from 'src/app/model/trace.model'; +import {DatabaseRequest, DatabaseRequestStage, ExceptionInfo} from 'src/app/model/trace.model'; import {EnvRouter} from "../../../service/router.service"; -import {MatTableDataSource} from "@angular/material/table"; import {DurationPipe} from "../../../shared/pipe/duration.pipe"; @Component({ diff --git a/src/app/views/detail/ldap/detail-ldap.view.ts b/src/app/views/detail/ldap/detail-ldap.view.ts index f097b2d..e808a92 100644 --- a/src/app/views/detail/ldap/detail-ldap.view.ts +++ b/src/app/views/detail/ldap/detail-ldap.view.ts @@ -3,13 +3,7 @@ import {ActivatedRoute} from "@angular/router"; import {TraceService} from "../../../service/trace.service"; import {DataItem, Timeline} from "vis-timeline"; import {combineLatest, finalize, forkJoin, Subscription} from "rxjs"; -import { - ExceptionInfo, - FtpRequest, - FtpRequestStage, - NamingRequest, - NamingRequestStage -} from "../../../model/trace.model"; +import {ExceptionInfo, NamingRequest, NamingRequestStage} from "../../../model/trace.model"; import {DatePipe} from "@angular/common"; import {application} from "../../../../environments/environment"; import {DurationPipe} from "../../../shared/pipe/duration.pipe"; diff --git a/src/app/views/detail/session/_component/smtp-table/detail-smtp-table.component.html b/src/app/views/detail/session/_component/smtp-table/detail-smtp-table.component.html index 72afa70..16540b9 100644 --- a/src/app/views/detail/session/_component/smtp-table/detail-smtp-table.component.html +++ b/src/app/views/detail/session/_component/smtp-table/detail-smtp-table.component.html @@ -6,7 +6,9 @@ - + diff --git a/src/app/views/detail/session/main/detail-session-main.view.html b/src/app/views/detail/session/main/detail-session-main.view.html index 653f6b3..216a524 100644 --- a/src/app/views/detail/session/main/detail-session-main.view.html +++ b/src/app/views/detail/session/main/detail-session-main.view.html @@ -31,21 +31,21 @@ person
{{ session.user || "N/A" }} le {{ (session.start * 1000) | date: 'dd/MM/yyyy à HH:mm:ss.SSS': 'fr' }}
- en {{{ start: session.start, end: session.end } | duration}} + en {{ { start: session.start, end: session.end } | duration }}
storage
{{instance.name}} {{instance.version}}
@@ -61,7 +61,7 @@
{{ item.key }} diff --git a/src/app/views/detail/session/rest/detail-session-rest.view.html b/src/app/views/detail/session/rest/detail-session-rest.view.html index 9254323..08086f5 100644 --- a/src/app/views/detail/session/rest/detail-session-rest.view.html +++ b/src/app/views/detail/session/rest/detail-session-rest.view.html @@ -5,7 +5,7 @@ session.status >= 300 && session.status < 500 ? '4px solid orange' : '4px solid red'}"> settings_suggest @@ -39,7 +39,7 @@ person
{{ item.key }} diff --git a/src/app/views/detail/smtp/detail-smtp.view.ts b/src/app/views/detail/smtp/detail-smtp.view.ts index 4b57783..c301769 100644 --- a/src/app/views/detail/smtp/detail-smtp.view.ts +++ b/src/app/views/detail/smtp/detail-smtp.view.ts @@ -3,13 +3,7 @@ import {ActivatedRoute} from "@angular/router"; import {TraceService} from "../../../service/trace.service"; import {DataItem, Timeline} from "vis-timeline"; import {combineLatest, finalize, forkJoin, Subscription} from "rxjs"; -import { - ExceptionInfo, Mail, - MailRequest, - MailRequestStage, - NamingRequest, - NamingRequestStage -} from "../../../model/trace.model"; +import {ExceptionInfo, Mail, MailRequest, MailRequestStage} from "../../../model/trace.model"; import {DatePipe} from "@angular/common"; import {application} from "../../../../environments/environment"; import {EnvRouter} from "../../../service/router.service"; diff --git a/src/app/views/search/main/search-main.view.ts b/src/app/views/search/main/search-main.view.ts index 2b3dcac..f981a75 100644 --- a/src/app/views/search/main/search-main.view.ts +++ b/src/app/views/search/main/search-main.view.ts @@ -1,4 +1,4 @@ -import {Component, OnDestroy, OnInit, ViewChild} from '@angular/core'; +import {Component, inject, OnDestroy, OnInit, ViewChild} from '@angular/core'; import {FormControl, FormGroup, Validators} from '@angular/forms'; import {MatPaginator} from '@angular/material/paginator'; import {MatSort} from '@angular/material/sort'; @@ -13,6 +13,7 @@ import {Constants, FilterConstants, FilterMap, FilterPreset} from '../../constan import {FilterService} from 'src/app/service/filter.service'; import {InstanceMainSession} from 'src/app/model/trace.model'; import {EnvRouter} from "../../../service/router.service"; +import {InstanceService} from "../../../service/jquery/instance.service"; @Component({ @@ -20,6 +21,12 @@ import {EnvRouter} from "../../../service/router.service"; styleUrls: ['./search-main.view.scss'], }) export class SearchMainView implements OnInit, OnDestroy { + private _router = inject(EnvRouter); + private _traceService = inject(TraceService); + private _activatedRoute = inject(ActivatedRoute); + private _location = inject(Location); + private _filter = inject(FilterService); + MAPPING_TYPE = Constants.MAPPING_TYPE; filterConstants = FilterConstants; utils: Utils = new Utils(); @@ -42,11 +49,7 @@ export class SearchMainView implements OnInit, OnDestroy { @ViewChild(MatPaginator) paginator: MatPaginator; @ViewChild(MatSort) sort: MatSort; - constructor(private _router: EnvRouter, - private _traceService: TraceService, - private _activatedRoute: ActivatedRoute, - private _location: Location, - private _filter: FilterService) { + constructor() { combineLatest([ this._activatedRoute.params, diff --git a/src/app/views/search/rest/search-rest.view.ts b/src/app/views/search/rest/search-rest.view.ts index 38fd4ba..256cb00 100644 --- a/src/app/views/search/rest/search-rest.view.ts +++ b/src/app/views/search/rest/search-rest.view.ts @@ -1,4 +1,4 @@ -import {Component, OnDestroy, OnInit, ViewChild} from '@angular/core'; +import {Component, inject, OnDestroy, OnInit, ViewChild} from '@angular/core'; import {FormControl, FormGroup, Validators} from '@angular/forms'; import {MatPaginator} from '@angular/material/paginator'; import {MatSort} from '@angular/material/sort'; @@ -7,13 +7,14 @@ import {Location} from '@angular/common'; import {ActivatedRoute, Params} from '@angular/router'; import {BehaviorSubject, finalize, Subscription} from 'rxjs'; import {Utils} from 'src/app/shared/util'; -import {JQueryService} from 'src/app/service/jquery.service'; +import {JQueryService} from 'src/app/service/jquery/jquery.service'; import {TraceService} from 'src/app/service/trace.service'; import {application, makePeriod} from 'src/environments/environment'; import {Constants, FilterConstants, FilterMap, FilterPreset} from '../../constants'; import {FilterService} from 'src/app/service/filter.service'; import {InstanceRestSession} from 'src/app/model/trace.model'; import {EnvRouter} from "../../../service/router.service"; +import {InstanceService} from "../../../service/jquery/instance.service"; @Component({ @@ -21,6 +22,13 @@ import {EnvRouter} from "../../../service/router.service"; styleUrls: ['./search-rest.view.scss'], }) export class SearchRestView implements OnInit, OnDestroy { + private _router = inject(EnvRouter); + private _instanceService = inject(InstanceService); + private _traceService = inject(TraceService); + private _activatedRoute = inject(ActivatedRoute); + private _location = inject(Location); + private _filter = inject(FilterService); + MAPPING_TYPE = Constants.MAPPING_TYPE; filterConstants = FilterConstants; nameDataList: any[]; @@ -46,12 +54,7 @@ export class SearchRestView implements OnInit, OnDestroy { @ViewChild(MatPaginator) paginator: MatPaginator; @ViewChild(MatSort, { static: true }) sort: MatSort; - constructor(private _router: EnvRouter, - private _statsService: JQueryService, - private _traceService: TraceService, - private _activatedRoute: ActivatedRoute, - private _location: Location, - private _filter: FilterService) { + constructor() { this._activatedRoute.queryParams .subscribe({ @@ -66,11 +69,11 @@ export class SearchRestView implements OnInit, OnDestroy { } this.patchDateValue(this.params.start, new Date(this.params.end.getFullYear(), this.params.end.getMonth(), this.params.end.getDate() - 1)); - this.subscriptions.push(this._statsService.getInstance( { 'column.distinct': 'app_name', 'order': 'app_name.asc' }) + this.subscriptions.push(this._instanceService.getApplications() .pipe(finalize(()=> this.serverNameIsLoading = false)) .subscribe({ - next: (appNames: { appName: string }[]) => { - this.nameDataList = appNames.map(r => r.appName); + next: res => { + this.nameDataList = res.map(r => r.appName); this.patchServerValue(this.params.serveurs); }, error: (e) => { console.log(e) diff --git a/src/app/views/statistic/_component/exception-table/statistic-exception-table.component.ts b/src/app/views/statistic/_component/exception-table/statistic-exception-table.component.ts index 12a3da5..111e02d 100644 --- a/src/app/views/statistic/_component/exception-table/statistic-exception-table.component.ts +++ b/src/app/views/statistic/_component/exception-table/statistic-exception-table.component.ts @@ -15,18 +15,10 @@ export class StatisticExceptionTableComponent { @Input() set data(objects: any) { if (objects?.length) { //.pipe(map((d: any) => d.slice(0, 5))) - this.dataSource = new MatTableDataSource(objects.slice(0, 5).map((r: {COUNT: number, errorMessage: string, errorType: string}) => { + this.dataSource = new MatTableDataSource(objects.slice(0, 5).map((r: {count: number, errorMessage: string, errorType: string}) => { const index = r?.errorType.lastIndexOf('.') + 1; - return { count: r.COUNT, message: r?.errorMessage, class: r?.errorType?.substring(index) }; + return { count: r.count, message: r?.errorMessage, class: r?.errorType?.substring(index) }; })); - if (objects.length > 5) { - this.addExceptionCount = objects.reduce((acc: number, curr: any, i: number) => { - if (i >= 5 ) { - acc += curr['COUNT']; - } - return acc; - } , 0); - } } else { this.dataSource = new MatTableDataSource([]); } diff --git a/src/app/views/statistic/application/statistic-application.view.html b/src/app/views/statistic/application/statistic-application.view.html index 1099994..c459b89 100644 --- a/src/app/views/statistic/application/statistic-application.view.html +++ b/src/app/views/statistic/application/statistic-application.view.html @@ -19,60 +19,60 @@
+ [data]="requests.repartitionTimeAndTypeResponseByPeriod?.data || []" [isLoading]="requests.repartitionTimeAndTypeResponseByPeriod?.isLoading" /> + [data]="requests.repartitionTimeAndTypeResponse?.data || []" [isLoading]="requests.repartitionTimeAndTypeResponse?.isLoading" />
+ [data]="requests.repartitionUser?.data?.polar || []" [isLoading]="requests.repartitionUser?.isLoading" /> + [data]="requests.repartitionUser?.data?.bar || []" [isLoading]="requests.repartitionUser?.isLoading" />
+ [data]="requests.repartitionApiBar?.data || []" [isLoading]="requests.repartitionApiBar?.isLoading" />
- -
- +
\ No newline at end of file diff --git a/src/app/views/statistic/application/statistic-application.view.ts b/src/app/views/statistic/application/statistic-application.view.ts index 8b124b5..31e56b3 100644 --- a/src/app/views/statistic/application/statistic-application.view.ts +++ b/src/app/views/statistic/application/statistic-application.view.ts @@ -1,29 +1,31 @@ -import { Component, OnDestroy, OnInit, inject } from "@angular/core"; -import { DatePipe, Location } from '@angular/common'; -import { JQueryService } from "src/app/service/jquery.service"; -import { ActivatedRoute, Params } from "@angular/router"; -import { FormControl, FormGroup, Validators } from "@angular/forms"; -import { BehaviorSubject, Observable, Subscription, combineLatest, finalize, map } from "rxjs"; -import { Constants, FilterConstants, FilterMap, FilterPreset } from "../../constants"; -import { mapParams, formatters, groupingBy, periodManagement } from "src/app/shared/util"; -import { application, makePeriod } from "src/environments/environment"; -import { FilterService } from "src/app/service/filter.service"; +import {Component, inject, OnDestroy, OnInit} from "@angular/core"; +import {DatePipe, Location} from '@angular/common'; +import {ActivatedRoute, Params} from "@angular/router"; +import {FormControl, FormGroup, Validators} from "@angular/forms"; +import {BehaviorSubject, combineLatest, finalize, forkJoin, map, Observable, of, Subscription, switchMap} from "rxjs"; +import {Constants, FilterConstants, FilterMap, FilterPreset} from "../../constants"; +import {formatters, mapParams, periodManagement} from "src/app/shared/util"; +import {application, makePeriod} from "src/environments/environment"; +import {FilterService} from "src/app/service/filter.service"; import {EnvRouter} from "../../../service/router.service"; +import {InstanceService} from "../../../service/jquery/instance.service"; +import {RestSessionService} from "../../../service/jquery/rest-session.service"; @Component({ templateUrl: './statistic-application.view.html', styleUrls: ['./statistic-application.view.scss'] }) export class StatisticApplicationView implements OnInit, OnDestroy { - constants = Constants - filterConstants = FilterConstants; private _activatedRoute = inject(ActivatedRoute); - private _statsService = inject(JQueryService); + private _restSessionService = inject(RestSessionService); + private _instanceService = inject(InstanceService); private _router = inject(EnvRouter); private _location = inject(Location); private _datePipe = inject(DatePipe); private _filter = inject(FilterService); + constants = Constants + filterConstants = FilterConstants; serverFilterForm = new FormGroup({ dateRangePicker: new FormGroup({ @@ -41,7 +43,7 @@ export class StatisticApplicationView implements OnInit, OnDestroy { advancedParams: Partial<{ [key: string]: any }> = {} focusFieldName: any; - requests: { [key: string]: { observable: Observable, data?: any[], isLoading?: boolean } } = {}; + requests: { [key: string]: { observable: Observable, data?: any, isLoading?: boolean } } = {}; constructor() { combineLatest({ @@ -49,8 +51,7 @@ export class StatisticApplicationView implements OnInit, OnDestroy { queryParams: this._activatedRoute.queryParams }).subscribe({ next: (v: { params: Params, queryParams: Params }) => { - - this.name = v.params.name; + this.name = v.params.server_name; this.env = v.queryParams.env || application.default_env; this.start = v.queryParams.start ? new Date(v.queryParams.start) : (application.dashboard.app.default_period || application.dashboard.default_period || makePeriod(6)).start; this.end = v.queryParams.end ? new Date(v.queryParams.end) : (application.dashboard.app.default_period || application.dashboard.default_period || makePeriod(6, 1)).end; @@ -76,18 +77,22 @@ export class StatisticApplicationView implements OnInit, OnDestroy { if (advancedParams) { advancedParams = mapParams(this.filterConstants.STATS_APP, advancedParams); } - this.requests = this.APP_REQUEST(this.name, this.env, this.start, this.end, advancedParams); - Object.keys(this.requests).forEach(k => { - this.requests[k].data = []; - this.requests[k].isLoading = true; - this.subscriptions.push(this.requests[k].observable - .pipe(finalize(() => this.requests[k].isLoading = false)) - .subscribe({ - next: (res: any) => { - this.requests[k].data = res; - } - })); + this.APP_REQUEST(this.name, this.env, this.start, this.end, advancedParams).subscribe({ + next: obs => { + this.requests = obs; + Object.keys(this.requests).forEach(k => { + this.requests[k].isLoading = true; + this.subscriptions.push(this.requests[k].observable + .pipe(finalize(() => this.requests[k].isLoading = false)) + .subscribe({ + next: (res: any) => { + this.requests[k].data = res; + } + })); + }); + } }); + } search() { @@ -118,9 +123,9 @@ export class StatisticApplicationView implements OnInit, OnDestroy { onClickRow(event: MouseEvent, row: any) { if (event.ctrlKey) { - this._router.open(`#/statistic/app/${row.name}?env=${this.env}&start=${this.start.toISOString()}&end=${this.end.toISOString()}`, '_blank') + this._router.open(`#/dashboard/server/${row.name}?env=${this.env}&start=${this.start.toISOString()}&end=${this.end.toISOString()}`, '_blank') } else { - this._router.navigate(['/statistic/app', row.name], { + this._router.navigate(['/dashboard/server', row.name], { queryParamsHandling: 'preserve' }); } @@ -128,44 +133,36 @@ export class StatisticApplicationView implements OnInit, OnDestroy { APP_REQUEST = (name: string, env: string, start: Date, end: Date, advancedParams: FilterMap) => { let now = new Date(); - var groupedBy = periodManagement(start, end); - return { - repartitionTimeAndTypeResponse: { observable: this._statsService.getRestSession({ "column": "count_slowest:elapsedTimeSlowest,count_slow:elapsedTimeSlow,count_medium:elapsedTimeMedium,count_fast:elapsedTimeFast,count_fastest:elapsedTimeFastest,count_succes:countSucces,count_error_server:countErrorServer,count_error_client:countErrorClient", 'rest_session.instance_env': 'instance.id', 'instance.app_name': name, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'instance.environement': env, ...advancedParams }) }, - repartitionTimeAndTypeResponseByPeriod: { - observable: this._statsService.getRestSession({ 'column': `count_succes:countSucces,count_error_client:countErrorClient,count_error_server:countErrorServer,count_slowest:elapsedTimeSlowest,count_slow:elapsedTimeSlow,count_medium:elapsedTimeMedium,count_fast:elapsedTimeFast,count_fastest:elapsedTimeFastest,elapsedtime.avg:avg,elapsedtime.max:max,start.${groupedBy}:date,start.year:year`, 'rest_session.instance_env': 'instance.id', 'instance.app_name': name, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'instance.environement': env, 'order': `start.year.asc,start.${groupedBy}.asc`, ...advancedParams }).pipe(map(((r: any[]) => { - formatters[groupedBy](r, this._datePipe); - return r; - }))) - }, - repartitionRequestByPeriodLine: { observable: this._statsService.getRestSession({ 'column': "count:count,count_error_server:countErrorServer,count_slowest:countSlowest,rest_session.start.date:date", 'rest_session.instance_env': 'instance.id', 'instance.app_name': name, 'rest_session.start.ge': new Date(now.getFullYear(), now.getMonth(), now.getDate() - 6).toISOString(), 'rest_session.start.lt': now.toISOString(), 'instance.environement': env, 'order': 'rest_session.start.date.asc', ...advancedParams }) }, - repartitionUserPolar: { observable: this._statsService.getRestSession({ 'column': "count:count,user:user", 'instance_env': 'instance.id', 'instance.app_name': name, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'instance.environement': env, 'user.not': 'null', 'order': 'count.desc', ...advancedParams }).pipe(map((r: any[]) => r.slice(0, 5))) }, - repartitionUserBar: { - observable: this._statsService.getRestSession({ 'column': `count:count,start.${groupedBy}:date,start.year:year,user:user`, 'instance_env': 'instance.id', 'instance.app_name': name, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'instance.environement': env, 'user.not': 'null', 'order': `start.year.asc,start.${groupedBy}.asc`, ...advancedParams }).pipe(map((r: {count: number, date: number, year: number, user: string}[]) => { - let groupBy = groupingBy(r, 'user'); - let results: { count: number, user: string, date: any, year: any }[] = Object.entries(groupBy).map((value: [string, any[]]) => { - return { - totalCount: value[1].reduce((acc: number, o) => { - return acc + o['count']; - }, 0), - user: value[0], - data: value[1] - } - }).sort((a, b) => { - return b.totalCount - a.totalCount - }).slice(0, 5).flatMap(r => r.data); - - return results; - }), - map((r: any[]) => { - formatters[groupedBy](r, this._datePipe); - return r; + let groupedBy = periodManagement(start, end); + return this._instanceService.getIds(env, end, name).pipe(map(data => { + let ids = data.map(d => `"${d.id}"`).join(','); + return { + repartitionTimeAndTypeResponse: { observable: this._restSessionService.getRepartitionTimeAndTypeResponse({start: start, end: end, advancedParams: advancedParams, ids: ids}) }, + repartitionTimeAndTypeResponseByPeriod: { + observable: this._restSessionService.getRepartitionTimeAndTypeResponseByPeriod({start: start, end: end, groupedBy: groupedBy, advancedParams: advancedParams, ids: ids}).pipe(map(r => { + formatters[groupedBy](r, this._datePipe); + return r; })) - }, - repartitionApiBar: { observable: this._statsService.getRestSession({ 'column': "count_succes:countSucces,count_error_client:countErrorClient,count_error_server:countErrorServer,api_name", 'rest_session.instance_env': 'instance.id', 'instance.app_name': name, 'rest_session.start.ge': start.toISOString(), 'rest_session.start.lt': end.toISOString(), 'instance.environement': env, 'api_name.not': 'null', 'order': 'count.desc', ...advancedParams }).pipe(map((d: any) => d.slice(0, 5))) }, - dependenciesTable: { observable: this._statsService.getRestSession({ 'column': "count:count,count_succes:countSucces,count_error_client:countErrClient,count_error_server:countErrServer,instance.app_name:name", 'instance_env': 'instance.id', 'id': 'rest_request.parent', 'rest_request.remote': 'rest_session_join.id', 'rest_session_join.instance_env': 'instance_join.id', 'instance_join.app_name': name, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'rest_session_join.start.ge': start.toISOString(), 'rest_session_join.start.lt': end.toISOString(), 'instance_join.environement': env, 'instance_join.app_name.not': 'null', 'order': 'count.desc', ...advancedParams }) }, - dependentsTable: { observable: this._statsService.getRestSession({ 'column': "rest_session_join.count:count,rest_session_join.count_succes:countSucces,rest_session_join.count_error_client:countErrClient,rest_session_join.count_error_server:countErrServer,instance_join.app_name:name", 'instance_env': 'instance.id', 'id': 'rest_request.parent', 'rest_request.remote': 'rest_session_join.id', 'rest_session_join.instance_env': 'instance_join.id', 'instance.app_name': name, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'rest_session_join.start.ge': start.toISOString(), 'rest_session_join.start.lt': end.toISOString(), 'instance.environement': env, 'instance.app_name.not': 'null', 'order': 'count.desc', ...advancedParams }) }, - exceptionsTable: { observable: this._statsService.getRestSession({ 'column': 'count,err_type,err_msg', 'err.group': '', 'rest_session.instance_env': 'instance.id', "status.ge": 500, "instance.environement": env, "instance.app_name": name, 'rest_session.start.ge': start.toISOString(), 'rest_session.start.lt': end.toISOString(), 'order': 'count.desc', ...advancedParams })} - }; + }, + repartitionRequestByPeriodLine: { observable: this._restSessionService.getRepartitionRequestByPeriod({now: now, advancedParams: advancedParams, ids: ids}) }, + repartitionUser: { observable: + this._restSessionService.getRepartitionUser({start: start, end: end, advancedParams: advancedParams, ids: ids}) + .pipe(switchMap(res => { + return forkJoin({ + polar: of(res), + bar: this._restSessionService.getRepartitionUserByPeriod({users: res.map(d => `"${d.user}"`).join(','), start: start, end: end, groupedBy: groupedBy, advancedParams: advancedParams, ids: ids}).pipe(map(r => { + formatters[groupedBy](r, this._datePipe); + return r; + })) + }) + })) + }, + repartitionApiBar: { observable: this._restSessionService.getRepartitionApi({start: start, end: end, advancedParams: advancedParams, ids: ids}) }, + dependenciesTable: { observable: this._restSessionService.getDependencies({start: start, end: end, advancedParams: advancedParams, ids: ids}) }, + dependentsTable: { observable: this._restSessionService.getDependents({start: start, end: end, advancedParams: advancedParams, ids: ids}) }, + exceptionsTable: { observable: this._restSessionService.getExceptions({start: start, end: end, advancedParams: advancedParams, ids: ids})} + } + })); }; resetFilters() { diff --git a/src/app/views/statistic/database/statistic-database.view.html b/src/app/views/statistic/database/statistic-database.view.html index b76ee8b..9df0d7f 100644 --- a/src/app/views/statistic/database/statistic-database.view.html +++ b/src/app/views/statistic/database/statistic-database.view.html @@ -1,4 +1,4 @@ - + @@ -23,29 +23,29 @@
- - - + + +
+ [data]="requests.repartitionTimeByPeriodBar?.data" [isLoading]="requests.repartitionTimeByPeriodBar?.isLoading" /> + [data]="requests.repartitionTimePie?.data" [isLoading]="requests.repartitionTimePie?.isLoading" />
- - + +
diff --git a/src/app/views/statistic/database/statistic-database.view.ts b/src/app/views/statistic/database/statistic-database.view.ts index cfedfd1..4e94f6d 100644 --- a/src/app/views/statistic/database/statistic-database.view.ts +++ b/src/app/views/statistic/database/statistic-database.view.ts @@ -3,12 +3,14 @@ import { ActivatedRoute, Params, Router } from '@angular/router'; import { Observable, Subscription, catchError, combineLatest, finalize, map, of } from 'rxjs'; import { DatePipe, Location } from '@angular/common'; import { FormControl, FormGroup, Validators } from '@angular/forms'; -import { JQueryService } from 'src/app/service/jquery.service'; +import { JQueryService } from 'src/app/service/jquery/jquery.service'; import { MatTableDataSource } from '@angular/material/table'; import { Constants } from '../../constants'; import { application, makePeriod } from 'src/environments/environment'; import { formatters, periodManagement } from 'src/app/shared/util'; import { ChartProvider, field } from '@oneteme/jquery-core'; +import {DatabaseRequestService} from "../../../service/jquery/database-request.service"; +import {ExceptionService} from "../../../service/jquery/exception.service"; @Component({ templateUrl: './statistic-database.view.html', @@ -18,7 +20,8 @@ export class StatisticDatabaseView implements OnInit { private _activatedRoute = inject(ActivatedRoute); private _router = inject(Router); private _datePipe = inject(DatePipe); - private _statsService = inject(JQueryService); + private _databaseService = inject(DatabaseRequestService); + private _exceptionService = inject(ExceptionService); private _location = inject(Location); constants = Constants; @@ -32,18 +35,9 @@ export class StatisticDatabaseView implements OnInit { }); env: any; - dbNameDataList: any[]; db: any; - dbNameListIsLoading: boolean = false - countOkKo: any[]; - countMinMaxAvg: any[]; - countRepartitionBySpeed: any[]; - exceptions: any[]; - dbInfo: any[] = []; - userInfo: any[]; start: Date; end: Date; - doresetServerFormValue: boolean = false; displayedColumns: string[] = ['name']; dataSource: MatTableDataSource<{ name: string }> = new MatTableDataSource([]); @@ -75,26 +69,6 @@ export class StatisticDatabaseView implements OnInit { } - setServerFormValue() { - this.dbNameListIsLoading = true; - this.serverFilterForm.controls.dbnameControl.reset(); - this.serverFilterForm.controls.dbnameControl.disable(); - this._statsService.getRestSession({ 'column.distinct': 'dbquery.db&dbquery.parent=apisession.id&order=dbquery.db.asc', 'apisession.environement': this.env }).pipe(catchError(error => of(error))) - .subscribe({ - next: (res: { db: string }[]) => { - this.dbNameDataList = res.map((s: any) => s.db) - this.serverFilterForm.controls.dbnameControl.enable(); - this.dbNameListIsLoading = false; - this.serverFilterForm.controls.dbnameControl.patchValue(this.db) - }, - error: err => { - this.dbNameListIsLoading = false; - this.serverFilterForm.controls.dbnameControl.enable(); - console.log(err) - } - }); - } - search() { if (this.serverFilterForm.valid) { let start = this.serverFilterForm.getRawValue().dateRangePicker.start; @@ -133,24 +107,16 @@ export class StatisticDatabaseView implements OnInit { DB_REQUEST = (db: string, env: string, start: Date, end: Date) => { let now = new Date(); - var groupedBy = periodManagement(start, end); + let groupedBy = periodManagement(start, end); return { - dbInfo: { observable: this._statsService.getDatabaseRequest({ 'column.distinct': 'host,db,driver,db_name,db_version', 'database_request.parent': 'rest_session.id', 'rest_session.instance_env': 'instance.id', "instance.environement": env, "db": db, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'rest_session.start.ge': start.toISOString(), 'rest_session.start.lt': end.toISOString() }) }, - countOkKoSlowest: { observable: this._statsService.getDatabaseRequest({ 'column': 'count_db_error:countErrorServer,count:count,count_slowest:countSlowest,start.date:date', 'database_request.parent': 'rest_session.id', 'rest_session.instance_env': 'instance.id', "instance.environement": env, "db": db, 'rest_session.start.ge': new Date(now.getFullYear(), now.getMonth(), now.getDate() - 6).toISOString(), 'rest_session.start.lt': now.toISOString(), 'start.ge': new Date(now.getFullYear(), now.getMonth(), now.getDate() - 7).toISOString(), 'start.lt': now.toISOString()}) }, - countMinMaxAvg: { observable: this._statsService.getDatabaseRequest({ 'column': `count_db_succes:countDbSucces,elapsedtime.max:max,elapsedtime.avg:avg,start.${groupedBy}:date,start.year:year`, 'database_request.parent': 'rest_session.id', 'rest_session.instance_env': 'instance.id', "instance.environement": env, "db": db, 'rest_session.start.ge': start.toISOString(), 'rest_session.start.lt': end.toISOString(), 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'order': `start.year.asc,start.${groupedBy}.asc` }).pipe(map(((r: any[]) => { - formatters[groupedBy](r, this._datePipe); - return r; - }))) - }, - countRepartitionBySpeedBar: { - observable: this._statsService.getDatabaseRequest({ 'column': `count_slowest:elapsedTimeSlowest,count_slow:elapsedTimeSlow,count_medium:elapsedTimeMedium,count_fast:elapsedTimeFast,count_fastest:elapsedTimeFastest,start.${groupedBy}:date,start.year:year`, 'database_request.parent': 'rest_session.id', 'rest_session.instance_env': 'instance.id', "instance.environement": env, "db": db, 'rest_session.start.ge': start.toISOString(), 'rest_session.start.lt': end.toISOString(), 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'order': `start.year.asc,start.${groupedBy}.asc` }).pipe(map(((r: any[]) => { + repartitionRequestByPeriodLine: { observable: this._databaseService.getRepartitionRequestByPeriod({now: now, database: db, env: env}) }, + repartitionTimeByPeriodBar: { observable: this._databaseService.getRepartitionTimeByPeriod({start: start, end: end, groupedBy: groupedBy, database: db, env: env}).pipe(map(((r: any[]) => { formatters[groupedBy](r, this._datePipe); return r; }))) }, - countRepartitionBySpeedPie: { observable: this._statsService.getDatabaseRequest({ 'column': 'count_slowest:elapsedTimeSlowest,count_slow:elapsedTimeSlow,count_medium:elapsedTimeMedium,count_fast:elapsedTimeFast,count_fastest:elapsedTimeFastest', 'database_request.parent': 'rest_session.id', 'rest_session.instance_env': 'instance.id', "instance.environement": env, "db": db, 'rest_session.start.ge': start.toISOString(), 'rest_session.start.lt': end.toISOString(), 'start.ge': start.toISOString(), 'start.lt': end.toISOString()}) }, - exceptions: { observable: this._statsService.getException({ 'column': 'count,err_type,err_msg', 'err.group': '', 'exception.parent': 'database_request.id', 'database_request.parent': 'rest_session.id', 'rest_session.instance_env': 'instance.id', "instance.environement": env, "database_request.db": db, 'rest_session.start.ge': start.toISOString(), 'rest_session.start.lt': end.toISOString(), 'database_request.start.ge': start.toISOString(), 'database_request.start.lt': end.toISOString(), 'order': 'count.desc' })} - // usersInfo: { observable: this._statsService.getDatabaseRequest({ 'column': 'count:countRows,dbquery.user', 'dbquery.parent': 'apisession.id', "apisession.environement": env, "dbquery.db": db, 'apisession.start.ge': start.toISOString(), 'apisession.start.lt': end.toISOString(), 'dbquery.start.ge': start.toISOString(), 'dbquery.start.lt': end.toISOString() }) } + repartitionTimePie: { observable: this._databaseService.getRepartitionTime({start: start, end: end, database: db, env: env}) }, + exceptions: { observable: this._exceptionService.getDatabaseException({start: start, end: end, database: db, env: env})} } } diff --git a/src/app/views/statistic/rest/statistic-rest.view.html b/src/app/views/statistic/rest/statistic-rest.view.html index 7901b21..6ce426e 100644 --- a/src/app/views/statistic/rest/statistic-rest.view.html +++ b/src/app/views/statistic/rest/statistic-rest.view.html @@ -1,4 +1,4 @@ - + @@ -18,62 +18,62 @@ - {{requests.infos?.data[0]?.app}} + {{params.serverName}}
+ [data]="requests.repartitionUser?.data?.polar || []" [isLoading]="requests.repartitionUser?.isLoading" /> + [data]="requests.repartitionUser?.data?.bar || []" [isLoading]="requests.repartitionUser?.isLoading" />
- -
- +
\ No newline at end of file diff --git a/src/app/views/statistic/rest/statistic-rest.view.ts b/src/app/views/statistic/rest/statistic-rest.view.ts index d1f922c..219d00b 100644 --- a/src/app/views/statistic/rest/statistic-rest.view.ts +++ b/src/app/views/statistic/rest/statistic-rest.view.ts @@ -1,29 +1,43 @@ import { Component, OnDestroy, OnInit, inject } from "@angular/core"; -import { JQueryService } from "src/app/service/jquery.service"; +import { JQueryService } from "src/app/service/jquery/jquery.service"; import { DatePipe, Location } from '@angular/common'; import { ActivatedRoute, Params } from "@angular/router"; import { FormControl, FormGroup, Validators } from "@angular/forms"; -import { BehaviorSubject, Observable, Subscription, combineLatest, filter, finalize, map } from "rxjs"; +import { + BehaviorSubject, + Observable, + Subscription, + combineLatest, + filter, + finalize, + map, + switchMap, + forkJoin, of +} from "rxjs"; import { Constants, FilterConstants, FilterMap, FilterPreset } from "../../constants"; import { Utils, formatters, groupingBy, periodManagement, mapParams, } from "src/app/shared/util"; import { application, makePeriod } from "src/environments/environment"; import { FilterService } from "src/app/service/filter.service"; import {EnvRouter} from "../../../service/router.service"; +import {InstanceService} from "../../../service/jquery/instance.service"; +import {RestSessionService} from "../../../service/jquery/rest-session.service"; @Component({ templateUrl: './statistic-rest.view.html', styleUrls: ['./statistic-rest.view.scss'] }) export class StatisticRestView implements OnInit, OnDestroy { - constants = Constants; - filterConstants = FilterConstants; private _activatedRoute = inject(ActivatedRoute); - private _statsService = inject(JQueryService); + private _restSessionService = inject(RestSessionService); + private _instanceService = inject(InstanceService); private _router = inject(EnvRouter); private _location = inject(Location); private _datePipe = inject(DatePipe); private _filter = inject(FilterService); + constants = Constants; + filterConstants = FilterConstants; + serverFilterForm = new FormGroup({ dateRangePicker: new FormGroup({ start: new FormControl(null, Validators.required), @@ -32,15 +46,11 @@ export class StatisticRestView implements OnInit, OnDestroy { }); subscriptions: Subscription[] = []; - - env: any; - name: string; - start: Date; - end: Date; advancedParams: Partial<{ [key: string]: any }> = {} + params: Partial<{serverName: string, restName: string, env: string, start: Date, end: Date}> = {}; focusFieldName: any; - requests: { [key: string]: { observable: Observable, data?: any[], isLoading?: boolean } } = {}; + requests: { [key: string]: { observable: Observable, data?: any, isLoading?: boolean } } = {}; constructor() { combineLatest({ @@ -48,13 +58,14 @@ export class StatisticRestView implements OnInit, OnDestroy { queryParams: this._activatedRoute.queryParams }).subscribe({ next: (v: { params: Params, queryParams: Params }) => { - this.name = v.params.name; - this.env = v.queryParams.env || application.default_env; - this.start = v.queryParams.start ? new Date(v.queryParams.start) : (application.dashboard.api.default_period || application.dashboard.default_period || makePeriod(6)).start; - this.end = v.queryParams.end ? new Date(v.queryParams.end) : (application.dashboard.api.default_period || application.dashboard.default_period || makePeriod(6, 1)).end; - this.patchDateValue(this.start, new Date(this.end.getFullYear(), this.end.getMonth(), this.end.getDate() - 1)); + this.params.serverName = v.params.server_name; + this.params.restName = v.params.rest_name; + this.params.env = v.queryParams.env || application.default_env; + this.params.start = v.queryParams.start ? new Date(v.queryParams.start) : (application.dashboard.api.default_period || application.dashboard.default_period || makePeriod(6)).start; + this.params.end = v.queryParams.end ? new Date(v.queryParams.end) : (application.dashboard.api.default_period || application.dashboard.default_period || makePeriod(6, 1)).end; + this.patchDateValue(this.params.start, new Date(this.params.end.getFullYear(), this.params.end.getMonth(), this.params.end.getDate() - 1)); this.init(); - this._location.replaceState(`${this._router.url.split('?')[0]}?env=${this.env}&start=${this.start.toISOString()}&end=${this.end.toISOString()}`); + this._location.replaceState(`${this._router.url.split('?')[0]}?env=${this.params.env}&start=${this.params.start.toISOString()}&end=${this.params.end.toISOString()}`); } }); @@ -74,18 +85,22 @@ export class StatisticRestView implements OnInit, OnDestroy { if (advancedParams) { advancedParams = mapParams(this.filterConstants.STATS_API, advancedParams); } - this.requests = this.API_REQUEST(this.name, this.env, this.start, this.end, advancedParams); - Object.keys(this.requests).forEach(k => { - this.requests[k].data = []; - this.requests[k].isLoading = true; - this.subscriptions.push(this.requests[k].observable - .pipe(finalize(() => this.requests[k].isLoading = false)) - .subscribe({ - next: (res: any) => { - this.requests[k].data = res; - } - })); + this.API_REQUEST(this.params.serverName, this.params.restName, this.params.env, this.params.start, this.params.end, advancedParams).subscribe({ + next: obs => { + this.requests = obs; + Object.keys(this.requests).forEach(k => { + this.requests[k].isLoading = true; + this.subscriptions.push(this.requests[k].observable + .pipe(finalize(() => this.requests[k].isLoading = false)) + .subscribe({ + next: (res: any) => { + this.requests[k].data = res; + } + })); + }); + } }); + } unsubscribe() { @@ -97,7 +112,7 @@ export class StatisticRestView implements OnInit, OnDestroy { let start = this.serverFilterForm.getRawValue().dateRangePicker.start; let end = this.serverFilterForm.getRawValue().dateRangePicker.end; let excludedEnd = new Date(end.getFullYear(), end.getMonth(), end.getDate() + 1) - if (start.toISOString() != this.start.toISOString() || excludedEnd.toISOString() != this.end.toISOString()) { + if (start.toISOString() != this.params.start.toISOString() || excludedEnd.toISOString() != this.params.end.toISOString()) { this._router.navigate([], { relativeTo: this._activatedRoute, queryParamsHandling: 'merge', @@ -120,54 +135,46 @@ export class StatisticRestView implements OnInit, OnDestroy { onClickRow(event: MouseEvent, row: any) { if (event.ctrlKey) { - this._router.open(`#/statistic/rest/${row.name}?env=${this.env}&start=${this.start.toISOString()}&end=${this.end.toISOString()}`, '_blank') + this._router.open(`#/dashboard/server/${this.params.serverName}/rest/${row.name}?env=${this.params.env}&start=${this.params.start.toISOString()}&end=${this.params.end.toISOString()}`, '_blank') } else { - this._router.navigate(['/statistic/rest', row.name], { + this._router.navigate(['/dashboard/server',this.params.serverName, 'rest', row.name], { queryParamsHandling: 'preserve' }); } } - API_REQUEST = (name: string, env: string, start: Date, end: Date, advancedParams: FilterMap) => { + API_REQUEST = (serverName: string, restName: string, env: string, start: Date, end: Date, advancedParams: FilterMap) => { let now = new Date(); const groupedBy = periodManagement(start, end); - return { - infos: { observable: this._statsService.getRestSession({ 'column.distinct': 'instance.app_name:app', 'instance_env': 'instance.id', 'api_name': name, "instance.environement": env, 'start.ge': start.toISOString(), 'start.lt': end.toISOString() }) }, - repartitionTimeAndTypeResponse: { observable: this._statsService.getRestSession({ 'column': "count_slowest:elapsedTimeSlowest,count_slow:elapsedTimeSlow,count_medium:elapsedTimeMedium,count_fast:elapsedTimeFast,count_fastest:elapsedTimeFastest,count_succes:countSucces,count_error_server:countErrorServer,count_error_client:countErrorClient", 'rest_session.instance_env': 'instance.id', 'api_name': name, 'rest_session.start.ge': start.toISOString(), 'rest_session.start.lt': end.toISOString(), 'instance.environement': env, ...advancedParams }) }, - repartitionTimeAndTypeResponseByPeriod: { - observable: this._statsService.getRestSession({ 'column': `count_succes:countSucces,count_error_client:countErrorClient,count_error_server:countErrorServer,count_slowest:elapsedTimeSlowest,count_slow:elapsedTimeSlow,count_medium:elapsedTimeMedium,count_fast:elapsedTimeFast,count_fastest:elapsedTimeFastest,elapsedtime.avg:avg,elapsedtime.max:max,rest_session.start.${groupedBy}:date,rest_session.start.year:year`, 'rest_session.instance_env': 'instance.id', 'api_name': name, 'rest_session.start.ge': start.toISOString(), 'rest_session.start.lt': end.toISOString(), 'instance.environement': env, 'order': `rest_session.start.year.asc,rest_session.start.${groupedBy}.asc`, ...advancedParams }).pipe(map((r: any[]) => { - formatters[groupedBy](r, this._datePipe); - return r; - })) - }, - repartitionRequestByPeriodLine: { observable: this._statsService.getRestSession({ 'column': `count:count,count_error_server:countErrorServer,count_slowest:countSlowest,rest_session.start.date:date`, 'rest_session.instance_env': 'instance.id', 'api_name': name, 'rest_session.start.ge': new Date(now.getFullYear(), now.getMonth(), now.getDate() - 6).toISOString(), 'rest_session.start.lt': now.toISOString(), 'instance.environement': env, 'order': 'rest_session.start.date.asc', ...advancedParams }) }, // 7 derniers jours - repartitionUserPolar: { observable: this._statsService.getRestSession({ 'column': "count:count,user:user", 'rest_session.instance_env': 'instance.id', 'api_name': name, 'rest_session.start.ge': start.toISOString(), 'rest_session.start.lt': end.toISOString(), 'instance.environement': env, 'user.not': 'null', 'order': 'count.desc', ...advancedParams }).pipe(map((r: any[]) => r.slice(0, 5))) }, - repartitionUserBar: { - observable: this._statsService.getRestSession({ 'column': `count:count,start.${groupedBy}:date,start.year:year,user:user`, 'instance_env': 'instance.id', 'api_name': name, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'instance.environement': env, 'user.not': 'null', 'order': `start.year.asc,start.${groupedBy}.asc`, ...advancedParams }).pipe(map((r: any[]) => { - let groupBy = groupingBy(r, 'user'); - let results: { count: number, user: string, date: any, year: any }[] = Object.entries(groupBy).map((value: [string, any[]]) => { - return { - totalCount: value[1].reduce((acc: number, o) => { - return acc + o['count']; - }, 0), - user: value[0], - data: value[1] - } - }).sort((a, b) => { - return b.totalCount - a.totalCount - }).slice(0, 5).flatMap(r => r.data); - return results; - }), - map((r: any[]) => { - formatters[groupedBy](r, this._datePipe); - return r; - })) - }, - dependenciesTable: { observable: this._statsService.getRestSession({ 'column': "count:count,count_succes:countSucces,count_error_client:countErrClient,count_error_server:countErrServer,api_name:name", 'instance_env': 'instance.id', "id": "rest_request.parent", "rest_request.remote": "rest_session_join.id", 'rest_session_join.api_name': name, 'rest_session_join.start.ge': start.toISOString(), 'rest_session_join.start.lt': end.toISOString(), 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'instance.environement': env, 'api_name.not': 'null', 'order': 'count.desc', ...advancedParams }) }, - dependentsTable: { observable: this._statsService.getRestSession({ 'column': "rest_session_join.count:count,rest_session_join.count_succes:countSucces,rest_session_join.count_error_client:countErrClient,rest_session_join.count_error_server:countErrServer,rest_session_join.api_name:name", 'instance_env': 'instance.id', "id": "rest_request.parent", "rest_request.remote": "rest_session_join.id", 'api_name': name, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'rest_session_join.start.ge': start.toISOString(), 'rest_session_join.start.lt': end.toISOString(), 'instance.environement': env, 'rest_session_join.api_name.not': 'null', 'order': 'count.desc', ...advancedParams }) }, - exceptionsTable: { observable: this._statsService.getRestSession({ 'column': 'count,err_type,err_msg', 'instance_env': 'instance.id', 'err.group': '', "status.ge": 500, "instance.environement": env, "api_name": name, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'order': 'count.desc', ...advancedParams })} - }; - } + return this._instanceService.getIds(env, end, serverName).pipe(map((data: {id: string}[]) => { + let ids = data.map(d => `"${d.id}"`).join(','); + return { + repartitionTimeAndTypeResponse: { observable: this._restSessionService.getRepartitionTimeAndTypeResponse({start: start, end: end, advancedParams: advancedParams, ids: ids, apiName: restName}) }, + repartitionTimeAndTypeResponseByPeriod: { + observable: this._restSessionService.getRepartitionTimeAndTypeResponseByPeriod({start: start, end: end, groupedBy: groupedBy, advancedParams: advancedParams, ids: ids, apiName: restName}).pipe(map(r => { + formatters[groupedBy](r, this._datePipe); + return r; + })) + }, + repartitionRequestByPeriodLine: { observable: this._restSessionService.getRepartitionRequestByPeriod({now: now, advancedParams: advancedParams, ids: ids, apiName: restName}) }, // 7 derniers jours + repartitionUser: { observable: + this._restSessionService.getRepartitionUser({start: start, end: end, advancedParams: advancedParams, ids: ids, apiName: restName}) + .pipe(switchMap(res => { + return forkJoin({ + polar: of(res), + bar: this._restSessionService.getRepartitionUserByPeriod({users: res.map(d => `"${d.user}"`).join(','), start: start, end: end, groupedBy: groupedBy, advancedParams: advancedParams, ids: ids, apiName: restName}).pipe(map(r => { + formatters[groupedBy](r, this._datePipe); + return r; + })) + }) + })) + }, + dependenciesTable: { observable: this._restSessionService.getDependencies({start: start, end: end, advancedParams: advancedParams, ids: ids, apiName: restName}) }, + dependentsTable: { observable: this._restSessionService.getDependents({start: start, end: end, advancedParams: advancedParams, ids: ids, apiName: restName}) }, + exceptionsTable: { observable: this._restSessionService.getExceptions({start: start, end: end, advancedParams: advancedParams, ids: ids, apiName: restName}) } + }})) + }; + resetFilters() { this.patchDateValue((application.dashboard.api.default_period || application.dashboard.default_period || makePeriod(6)).start, diff --git a/src/app/views/statistic/user/statistic-user.view.ts b/src/app/views/statistic/user/statistic-user.view.ts index a8a26b6..36cfe7d 100644 --- a/src/app/views/statistic/user/statistic-user.view.ts +++ b/src/app/views/statistic/user/statistic-user.view.ts @@ -1,5 +1,5 @@ import { Component, OnDestroy, OnInit, inject } from "@angular/core"; -import { JQueryService } from "src/app/service/jquery.service"; +import { JQueryService } from "src/app/service/jquery/jquery.service"; import { ActivatedRoute, Params } from "@angular/router"; import { DatePipe, Location } from '@angular/common'; import { FormControl, FormGroup, Validators } from "@angular/forms"; @@ -9,22 +9,25 @@ import { application, makePeriod } from "src/environments/environment"; import { FilterService } from "src/app/service/filter.service"; import { mapParams, formatters, periodManagement } from "src/app/shared/util"; import {EnvRouter} from "../../../service/router.service"; +import {RestSessionService} from "../../../service/jquery/rest-session.service"; +import {MainSessionService} from "../../../service/jquery/main-session.service"; @Component({ templateUrl: './statistic-user.view.html', styleUrls: ['./statistic-user.view.scss'] }) export class StatisticUserView implements OnInit, OnDestroy { - constants = Constants; - filterConstants = FilterConstants; - private _activatedRoute = inject(ActivatedRoute); - private _statsService = inject(JQueryService); + private _restSessionService = inject(RestSessionService); + private _mainSessionService = inject(MainSessionService); private _router = inject(EnvRouter); private _location = inject(Location); private _datePipe = inject(DatePipe); private _filter = inject(FilterService); + constants = Constants; + filterConstants = FilterConstants; + serverFilterForm = new FormGroup({ dateRangePicker: new FormGroup({ start: new FormControl(null, Validators.required), @@ -49,7 +52,7 @@ export class StatisticUserView implements OnInit, OnDestroy { queryParams: this._activatedRoute.queryParams }).subscribe({ next: (v: { params: Params, queryParams: Params }) => { - this.name = v.params.name; + this.name = v.params.user_name; this.env = v.queryParams.env || application.default_env; this.start = v.queryParams.start ? new Date(v.queryParams.start) : (application.dashboard.database.default_period || application.dashboard.default_period || makePeriod(6)).start; this.end = v.queryParams.end ? new Date(v.queryParams.end) : (application.dashboard.database.default_period || application.dashboard.default_period || makePeriod(6, 1)).end; @@ -58,7 +61,6 @@ export class StatisticUserView implements OnInit, OnDestroy { this._location.replaceState(`${this._router.url.split('?')[0]}?env=${this.env}&start=${this.start.toISOString()}&end=${this.end.toISOString()}`) } }); - } ngOnInit() { @@ -118,19 +120,19 @@ export class StatisticUserView implements OnInit, OnDestroy { // Stats en fonction du navigateur et du systeme USER_REQUEST = (name: string, env: string, start: Date, end: Date, advancedParams: FilterMap) => { let now = new Date(); - var groupedBy = periodManagement(start, end); + let groupedBy = periodManagement(start, end); return { - repartitionTimeAndTypeResponse: { observable: this._statsService.getRestSession({ 'column': "count_slowest:elapsedTimeSlowest,count_slow:elapsedTimeSlow,count_medium:elapsedTimeMedium,count_fast:elapsedTimeFast,count_fastest:elapsedTimeFastest,count_succes:countSucces,count_error_server:countErrorServer,count_error_client:countErrorClient", 'rest_session.instance_env': 'instance.id', 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'instance.environement': env, 'rest_session.user': name, ...advancedParams }) }, + repartitionTimeAndTypeResponse: { observable: this._restSessionService.getRepartitionTimeAndTypeResponse({start: start, end: end, advancedParams: advancedParams, user: name, env: env}) }, repartitionTimeAndTypeResponseByPeriod: { - observable: this._statsService.getRestSession({ 'column': `count_succes:countSucces,count_error_client:countErrorClient,count_error_server:countErrorServer,count_slowest:elapsedTimeSlowest,count_slow:elapsedTimeSlow,count_medium:elapsedTimeMedium,count_fast:elapsedTimeFast,count_fastest:elapsedTimeFastest,elapsedtime.avg:avg,elapsedtime.max:max,start.${groupedBy}:date,start.year:year`, 'rest_session.instance_env': 'instance.id', 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'rest_session.user': name, 'instance.environement': env, 'order': `start.year.asc,start.${groupedBy}.asc`, ...advancedParams }).pipe(map(((r: any[]) => { + observable: this._restSessionService.getRepartitionTimeAndTypeResponseByPeriod({start: start, end: end, groupedBy: groupedBy, advancedParams: advancedParams, user: name, env: env}).pipe(map(r => { formatters[groupedBy](r, this._datePipe); return r; - }))) + })) }, - repartitionRequestByPeriodLine: { observable: this._statsService.getRestSession({ 'column': "count:count,count_error_server:countErrorServer,count_slowest:countSlowest,start.date:date", 'rest_session.instance_env': 'instance.id', 'start.ge': new Date(now.getFullYear(), now.getMonth(), now.getDate() - 6).toISOString(), 'start.lt': now.toISOString(), 'instance.environement': env, 'rest_session.user': name, 'order': 'start.date.asc', ...advancedParams }) }, - repartitionApiBar: { observable: this._statsService.getRestSession({ 'column': "count_succes:countSucces,count_error_client:countErrorClient,count_error_server:countErrorServer,api_name", 'rest_session.instance_env': 'instance.id', 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'instance.environement': env, 'rest_session.user': name, 'api_name.not': 'null', 'order': 'count.desc', ...advancedParams }).pipe(map((d: any) => d.slice(0, 5))) }, - // exceptionsTable: { observable: this._statsService.getException({ 'column': 'count,err_type,err_msg', 'err.group': '', "status.ge": 500, "environement": env, 'user': name, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'order': 'count.desc', ...advancedParams })}, - sessionTable: { observable: this._statsService.getMainSession({ 'column': "name,start:date,elapsedtime,location,instance.app_name", 'main_session.instance_env': 'instance.id', 'user': name, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'instance.environement': env, 'type': 'VIEW', 'order': 'start.date.desc' }) } + repartitionRequestByPeriodLine: { observable: this._restSessionService.getRepartitionRequestByPeriod({now: now, advancedParams: advancedParams, user: name, env: env}) }, + repartitionApiBar: { observable: this._restSessionService.getRepartitionApi({start: start, end: end, advancedParams: advancedParams, user: name, env: env}) }, + exceptionsTable: { observable: this._restSessionService.getExceptions({start: start, end: end, advancedParams: advancedParams, user: name, env: env})}, + sessionTable: { observable: this._mainSessionService.getInfos({start: start, end: end, advancedParams: advancedParams, user: name, env: env}) } }; } From aea3c36e06f036b83aa9da39b344a37c3cfeb822 Mon Sep 17 00:00:00 2001 From: YoussefDahi Date: Fri, 20 Sep 2024 15:21:18 +0200 Subject: [PATCH 061/126] dashboard Home Component --- src/app/app.component.ts | 2 +- src/app/model/conf.model.ts | 5 + src/app/service/jquery.service.ts | 20 + src/app/service/trace.service.ts | 1 + src/app/shared/pipe/duration.pipe.ts | 10 +- src/app/views/constants.ts | 242 ++++++++- .../views/dashboard/dashboard.component.html | 330 +++++++++++-- .../views/dashboard/dashboard.component.scss | 22 + .../views/dashboard/dashboard.component.ts | 460 +++++++++++++++++- src/app/views/search/rest/search-rest.view.ts | 1 - src/app/views/views.module.ts | 4 +- src/environments/environment.ts | 3 + src/styles.scss | 8 + 13 files changed, 1037 insertions(+), 71 deletions(-) diff --git a/src/app/app.component.ts b/src/app/app.component.ts index f01a99c..9b415a6 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -29,7 +29,7 @@ export class AppComponent implements OnInit, OnDestroy { this.isLoadingEnv = true; this.subscriptions.push(this._service.getInstance({ 'column.distinct': 'environement', - 'environement.not': 'null', + 'environement.notNull': '', 'order': 'environement.asc' }) .pipe(finalize(() => this.isLoadingEnv = false)) diff --git a/src/app/model/conf.model.ts b/src/app/model/conf.model.ts index 33a5ef6..397f6e3 100644 --- a/src/app/model/conf.model.ts +++ b/src/app/model/conf.model.ts @@ -15,6 +15,7 @@ interface Main { interface Dashboard { default_period: Partial; + home: Partial; api: Partial; app: Partial; database: Partial; @@ -37,6 +38,10 @@ interface User { default_period: Partial; } +interface Home{ + default_period: Partial; +} + interface DefaultPeriod { start: Date; end: Date; diff --git a/src/app/service/jquery.service.ts b/src/app/service/jquery.service.ts index 8dc3a98..9b93efc 100644 --- a/src/app/service/jquery.service.ts +++ b/src/app/service/jquery.service.ts @@ -22,11 +22,31 @@ export class JQueryService { return this.http.get(url, { params: params }); } + getRestRequest(params: any) { + let url = `${localStorage.getItem('server')}/jquery/request/rest`; + return this.http.get(url, { params: params }); + } + getDatabaseRequest(params: any) { let url = `${localStorage.getItem('server')}/jquery/request/database`; return this.http.get(url, { params: params }); } + getFtpRequest(params: any) { + let url = `${localStorage.getItem('server')}/jquery/request/ftp`; + return this.http.get(url, { params: params }); + } + + getSmtpRequest(params: any) { + let url = `${localStorage.getItem('server')}/jquery/request/smtp`; + return this.http.get(url, { params: params }); + } + + getLdapRequest(params: any) { + let url = `${localStorage.getItem('server')}/jquery/request/ldap`; + return this.http.get(url, { params: params }); + } + getException(params: any) { let url = `${localStorage.getItem('server')}/jquery/exception`; return this.http.get(url, { params: params }); diff --git a/src/app/service/trace.service.ts b/src/app/service/trace.service.ts index 8e59958..5570ad7 100644 --- a/src/app/service/trace.service.ts +++ b/src/app/service/trace.service.ts @@ -4,6 +4,7 @@ import { Observable, catchError, throwError } from "rxjs"; import { DatabaseRequest, DatabaseRequestStage, + ExceptionInfo, FtpRequest, FtpRequestStage, InstanceEnvironment, InstanceMainSession, diff --git a/src/app/shared/pipe/duration.pipe.ts b/src/app/shared/pipe/duration.pipe.ts index 3cf02c5..beb3ae9 100644 --- a/src/app/shared/pipe/duration.pipe.ts +++ b/src/app/shared/pipe/duration.pipe.ts @@ -12,17 +12,21 @@ export class DurationPipe implements PipeTransform { transform(value: Period | number, ...args: any[]):string { if(value == null) return 'N/A'; let time = typeof value == "object" ? value.end - value.start : value; - const remainingSeconds = this._decimalPipe.transform(Math.round((time % 60) * 1000) / 1000); const minutes = Math.floor((time % 3600) / 60); const hours = Math.floor(time/3600); + const days = Math.floor(time/86400) + const dayString = days > 0 ? `${days} jour(s)`:'' const hourString = hours > 0 ? `${hours}h` : '' const minuteString = minutes > 0 ? `${minutes}min` : '' const secondString = `${remainingSeconds}s` - + + if(days > 0 ){ + return `${dayString}`; + } if (hours > 0) { - return `${hourString}, ${minuteString || '0 min'} ${secondString && `: ${secondString}`}` + return `${hourString}, ${minuteString || '0 min'}` } else if (!hours && minutes > 0) { return `${minuteString} ${secondString && `: ${secondString}`}` } diff --git a/src/app/views/constants.ts b/src/app/views/constants.ts index 6e83540..d097257 100644 --- a/src/app/views/constants.ts +++ b/src/app/views/constants.ts @@ -1,4 +1,5 @@ import { ChartProvider, field, values } from "@oneteme/jquery-core"; +import { DashboardComponent } from "./dashboard/dashboard.component"; export class Constants { @@ -365,8 +366,247 @@ export class Constants { rest: {title: 'Appel d\'API', icon: 'call_received'}, batch: {title: 'Lancement de Batch', icon: 'manufacturing'}, startup: {title: 'Lancement de Serveur', icon: 'restart_alt'}, - view: {title: 'Navigation', icon: 'ads_click'} + view: {title: 'Navigation', icon: 'ads_click'}, + dashboard: {title:'Dashboard', icon: 'home'} } + + + static REST_REQUEST_EXCEPTION_BY_PERIOD_LINE: ChartProvider = { + + + height: 150, + continue: true, + series: [ + { data: { x: field('date'), y: field('perc') }, name: 'Nombre d\'exceptions REST', color: "#ff0000" }, + ], + options: { + title: { + text: 'REST: ', + }, + chart: { + id: 'sparkline-1', + group: 'sparkline', + data : { + name : "restRequestExceptionsTable", + type : "REST" + }, + sparkline: { + enabled: true + }, + toolbar: { + show: false + } + + }, + stroke: { + curve: 'straight' + }, + xaxis: { + labels: { + datetimeUTC: false + }, + }, + yaxis: { + labels: { + formatter: function (val: any) { + return val.toFixed(2)+"%"; + }, + }, + max: 100 + }, + subtitle: { + offsetY: 20 + } + } + }; + + static DATABASE_REQUEST_EXCEPTION_BY_PERIOD_LINE: ChartProvider = { + + height: 150, + continue: true, + series: [ + { data: { x: field('date'), y: field('perc') }, name: 'Nombre d\'exceptions JDBC', color: "#ff0000" } + ], + options: { + title: { + text: 'JDBC: ', + }, + chart: { + id: 'sparkline-2', + group: 'sparkline', + data : { + name : "databaseRequestExceptionsTable", + type : "JDBC" + }, + sparkline: { + enabled: true + }, + toolbar: { + show: false + } + }, + stroke: { + curve: 'straight' + }, + xaxis: { + labels: { + datetimeUTC: false + }, + }, + yaxis: { + labels: { + formatter: function (val: any) { + return val.toFixed(2)+"%"; + }, + }, + max: 100 + }, + subtitle: { + offsetY: 20 + } + } + }; + + static FTP_REQUEST_EXCEPTION_BY_PERIOD_LINE: ChartProvider = { + + + height: 150, + continue: true, + series: [ + { data: { x: field('date'), y: field('perc') }, name: 'Nombre d\'exceptions FTP', color: "#ff0000"} + ], + options: { + title: { + text: 'FTP: ', + }, + chart: { + id: 'sparkline-3', + group: 'sparkline', + data : { + name : "ftpRequestExceptionsTable", + type : "FTP" + }, + sparkline: { + enabled: true + }, + toolbar: { + show: false + } + }, + stroke: { + curve: 'straight' + }, + xaxis: { + labels: { + datetimeUTC: false + }, + }, + yaxis: { + labels: { + formatter: function (val: any) { + return val.toFixed(2)+"%"; + }, + }, + max: 100 + }, + subtitle: { + offsetY: 20 + } + } + }; + + static SMTP_REQUEST_EXCEPTION_BY_PERIOD_LINE: ChartProvider = { + height: 150, + continue: true, + series: [ + { data: { x: field('date'), y: field('perc') }, name: 'Nombre d\'exceptions SMTP', color: "#ff0000" } + ], + options: { + title: { + text: 'SMTP: ', + }, + chart: { + id: 'sparkline-4', + group: 'sparkline', + data : { + name : "smtpRequestExceptionsTable", + type : "SMTP" + }, + sparkline: { + enabled: true + }, + toolbar: { + show: false + } + }, + stroke: { + curve: 'straight' + }, + xaxis: { + labels: { + datetimeUTC: false + }, + }, + yaxis: { + labels: { + formatter: function (val: any) { + return val.toFixed(2)+"%"; + }, + }, + max: 100 + }, + subtitle: { + offsetY: 20 + } + } + }; + + static LDAP_REQUEST_EXCEPTION_BY_PERIOD_LINE: ChartProvider = { + height: 150, + continue: true, + series: [ + { data: { x: field('date'), y: field('perc') }, name: 'Nombre d\'exceptions LDAP', color: "#ff0000" } + ], + options: { + title: { + text: 'LDAP: ', + }, + chart: { + id: 'sparkline-5', + group: 'sparkline', + data : { + name : "ldapRequestExceptionsTable", + type : "LDAP" + }, + sparkline: { + enabled: true + }, + toolbar: { + show: true, + + } + }, + stroke: { + curve: 'straight' + }, + xaxis: { + labels: { + datetimeUTC: false + }, + }, + yaxis: { + labels: { + formatter: function (val: any) { + return val.toFixed(2)+"%"; + }, + }, + max: 100 + }, + subtitle: { + offsetY: 20 + } + } + }; } export class Filter { diff --git a/src/app/views/dashboard/dashboard.component.html b/src/app/views/dashboard/dashboard.component.html index 32d42ab..6e7b136 100644 --- a/src/app/views/dashboard/dashboard.component.html +++ b/src/app/views/dashboard/dashboard.component.html @@ -1,48 +1,298 @@ -
- + + + + Période + + + + + + + - - - + + Serveur + + + {{s}} + {{d}} + + + + + + + + +
+ + + + + +
+ +
+
+
+
+ +
+ call_received +
Erreurs serveur
+
+ +
+
+
Client {{row.instanceUser || 'N/A'}}
+ + + + + + + + + - - - - - - - - - - - - - - - + + + + + + + + +
Instant + {{ row.date }} + Titre +
+ {{removePackage(row.errorType)}} +
+
Début - {{ row.start*1000 | date:'dd/MM/yyyy' }} -
- {{ row.start*1000 | date:'HH:mm:ss.SSS' }} -
Durée -
{{ getElapsedTime(row.end, row.start) | number :'1.2-3'}}s
-
-
- - info + +
Taux +
+ {{ + (row.count*100)/row.countok | number : '1.0-2' }}% +
+
+
+ + info + + Aucun résultat +
+
+ + Chargement en cours... + + +
+ +
+
+ +
+
+ + + + +
+
+
+ +
+ manufacturing +
Erreurs Batch
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + +
Instant + {{ row.date }} + Titre +
+ {{removePackage(row.errorType)}} +
+
Taux +
+ {{ + (row.count*100)/row.countok | number : '1.0-2' }}% +
+
+
+ + info + + Aucun résultat +
+
+ + Chargement en cours... + + +
+ +
+
+ +
+
+
+
+ + +
+ +
+
+ +
+ restart_alt +
Lancement de Serveur
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + - -
Serveur {{row.appName || 'N/A'}} Version {{row.version || 'N/A'}} Depuis +
+ {{ + (today?.getTime() - row.start) / 1000 | duration }} +
+
+
+ + info + + Aucun résultat +
+
Chargement en cours... -
- -
-
\ No newline at end of file +
+ + + + +
+ +
+
+ + \ No newline at end of file diff --git a/src/app/views/dashboard/dashboard.component.scss b/src/app/views/dashboard/dashboard.component.scss index e69de29..47b6b1f 100644 --- a/src/app/views/dashboard/dashboard.component.scss +++ b/src/app/views/dashboard/dashboard.component.scss @@ -0,0 +1,22 @@ +.exception-card { + display: flex; + flex-direction: row; + display: -webkit-box; + gap: 1em; + margin-bottom: 1em; +} + +.header-filter { + display: flex; + flex-direction: row; + align-items: center; + gap: 0.5em; +} + + + + +table { + height: 100%; + table-layout: fixed; +} diff --git a/src/app/views/dashboard/dashboard.component.ts b/src/app/views/dashboard/dashboard.component.ts index 4d0c9be..70bd8ab 100644 --- a/src/app/views/dashboard/dashboard.component.ts +++ b/src/app/views/dashboard/dashboard.component.ts @@ -1,37 +1,449 @@ -import { Component } from '@angular/core'; +import { Component, inject, OnInit, ViewChild } from '@angular/core'; +import { ActivatedRoute, Params } from '@angular/router'; +import { combineLatest, finalize, forkJoin, map, Observable, Subscription } from 'rxjs'; +import { DatePipe, Location } from '@angular/common'; +import { application, makePeriod } from 'src/environments/environment'; +import { EnvRouter } from "../../service/router.service"; +import { FormControl, FormGroup, Validators } from '@angular/forms'; +import { Constants } from '../constants'; +import { formatters, periodManagement } from 'src/app/shared/util'; +import { JQueryService } from 'src/app/service/jquery.service'; +import { MatDialog } from '@angular/material/dialog'; +import { ProtocolExceptionComponent } from './components/protocol-exception-modal/protocol-exception-modal.component'; +import { cp } from 'fs'; +import { MatPaginator } from '@angular/material/paginator'; import { MatTableDataSource } from '@angular/material/table'; -import { ActivatedRoute } from '@angular/router'; -import { TraceService } from 'src/app/service/trace.service'; -import { combineLatest } from 'rxjs'; -import { Location } from '@angular/common'; -import { application } from 'src/environments/environment'; -import {EnvRouter} from "../../service/router.service"; - +import { MatSort } from '@angular/material/sort'; @Component({ templateUrl: './dashboard.component.html', styleUrls: ['./dashboard.component.scss'], }) -export class DashboardComponent { +export class DashboardComponent { + constants = Constants; + private _activatedRoute: ActivatedRoute = inject(ActivatedRoute); + private _router: EnvRouter = inject(EnvRouter); + private _location: Location = inject(Location); + private _statsService: JQueryService = inject(JQueryService); + private _datePipe = inject(DatePipe); + private _dialog = inject(MatDialog) + - displayedColumns: string[] = ['message']; - dataSource: MatTableDataSource<{ count: number, message: string, class: string }> = new MatTableDataSource([]); + MAPPING_TYPE = Constants.MAPPING_TYPE; + serverStartDisplayedColumns: string[] = ["appName","version", "duree"]; + sessionExceptionsDisplayedColumns: string[] = ["date", "errorType", "count"]; + batchExceptionDisplayedColumns: string[] = ["date", "error", "count"]; paramsSubscription: any; - env: any; - constructor(private _activatedRoute: ActivatedRoute, - private _traceService: TraceService, - private _router: EnvRouter, - private _location: Location) { - - this.paramsSubscription = combineLatest([ - this._activatedRoute.params, - this._activatedRoute.queryParams - ]).subscribe({ - next: ([params, queryParams]) => { - this.env = queryParams.env || application.default_env; - this._location.replaceState(`${this._router.url.split('?')[0]}?env=${this.env}`) + today: Date = new Date(); + subscriptions: Subscription[] = []; + requests: { [key: string]: { observable?: Observable, data?: MatTableDataSource, isLoading?: boolean, key?: string } } = {}; + charts: any = {} + serverFilterForm = new FormGroup({ + appname: new FormControl([""]), + dateRangePicker: new FormGroup({ + start: new FormControl(null, [Validators.required]), + end: new FormControl(null, [Validators.required]), + }), + }); + serverNameIsLoading = true; + params: Partial<{ env: string, start: Date, end: Date, serveurs: string[] }> = {}; + nameDataList: any[]; + + + @ViewChild('sessionExceptionsTablePaginator') sessionExceptionsTablePaginator: MatPaginator; + @ViewChild('batchExceptionTablePaginator') batchExceptionTablePaginator: MatPaginator; + @ViewChild('serverStartTablePaginator') serverStartTablePaginator: MatPaginator; + + @ViewChild('serverStartTableSort') serverStartTableSort: MatSort; + @ViewChild('sessionExceptionsTableSort') sessionExceptionsTableSort: MatSort; + @ViewChild('batchExceptionTableSort') batchExceptionTableSort: MatSort; + + + + + constructor() { + this.paramsSubscription = combineLatest({ + params: this._activatedRoute.params, + queryParams: this._activatedRoute.queryParams + }).subscribe({ + next: (v: { params: Params, queryParams: Params }) => { + this.params.env = v.queryParams.env || application.default_env; + this.params.start = v.queryParams.start ? new Date(v.queryParams.start) : (application.dashboard.home.default_period || makePeriod(0, 1)).start; + this.params.end = v.queryParams.end ? new Date(v.queryParams.end) : (application.dashboard.home.default_period || makePeriod(0, 1)).end; + this.params.serveurs = Array.isArray(v.queryParams['appname']) ? v.queryParams['appname'] : v.queryParams['appname'] ? [v.queryParams['appname']] : [] + if (this.params.serveurs.length > 0) { + this.patchServerValue(this.params.serveurs); + } + this.patchDateValue(this.params.start, new Date(this.params.end.getFullYear(), this.params.end.getMonth(), this.params.end.getDate() - 1)); + this.subscriptions.push(this._statsService.getInstance({ 'column.distinct': 'app_name', 'order': 'app_name.asc' }) + .pipe(finalize(() => this.serverNameIsLoading = false)) + .subscribe({ + next: (appNames: { appName: string }[]) => { + this.nameDataList = appNames.map(r => r.appName); + this.patchServerValue(this.params.serveurs); + }, error: (e) => { + console.log(e) + } + })); + this.init(); + this._location.replaceState(`${this._router.url.split('?')[0]}?env=${this.params.env}&start=${this.params.start.toISOString()}&end=${this.params.end.toISOString()}${this.params.serveurs.length > 0 ? '&' + this.params.serveurs.map(name => `appname=${name}`).join('&') : ''}`) } }); } + init() { + let that: any = this; + this.setChartDialogEvent() + let serverParam = this.createServerFilter(); + this.requests = this.REQUESTS(this.params.env, this.params.start, this.params.end, serverParam.app_name); + Object.keys(this.requests).forEach(k => { + this.charts[k] = []; + this.requests[k].isLoading = true; + this.subscriptions.push(this.requests[k].observable + .pipe(finalize(() => { this.requests[k].isLoading = false; })) + .subscribe({ + next: (res: any) => { + + /*this.requests[k].data.sortingDataAccessor = (row: any, columnName: string) => { + + if (columnName == "count") return ((row['count']*100) / row['countok']).toFixed(0); + + // return row[columnName as keyof any] as string; + + }*/ + + // if(["serverStartTable","sessionExceptionsTable","batchExceptionTable"].indexOf(k)>-1){ + this.requests[k].data = new MatTableDataSource(res); + this.requests[k].data.sort = that[`${k}Sort`]; + this.requests[k].data.paginator = that[`${k}Paginator`]; + // } + } + })) + }) + } + + search() { // TODO: finish search button + if (this.serverFilterForm.valid) { + let appname = this.serverFilterForm.getRawValue().appname; + let start = this.serverFilterForm.getRawValue().dateRangePicker.start; + let end = this.serverFilterForm.getRawValue().dateRangePicker.end + let excludedEnd = new Date(end.getFullYear(), end.getMonth(), end.getDate() + 1) + if (this.params.start.toISOString() != start.toISOString() + || this.params.end.toISOString() != excludedEnd.toISOString() + || !this.params?.serveurs?.every((element, index) => element === appname[index]) + || appname.length != this.params?.serveurs?.length) { + this._router.navigate([], { + relativeTo: this._activatedRoute, + queryParamsHandling: 'merge', + queryParams: { ...(appname !== undefined && { appname }), start: start.toISOString(), end: excludedEnd } + }) + } else { + this.init(); + } + } + } + + patchDateValue(start: Date, end: Date) { + this.serverFilterForm.patchValue({ + dateRangePicker: { + start: start, + end: end + } + }, { emitEvent: false }); + } + + + createServerFilter(): any { + if (this.params.serveurs.length > 0) { + return { app_name: `instance.app_name.in(${this.params.serveurs.map(v => `"${v}"`).join(',')})` }; + } + return { app_name: '' }; + } + + setChartDialogEvent() { + let dis = this; + [this.constants.REST_REQUEST_EXCEPTION_BY_PERIOD_LINE, + this.constants.DATABASE_REQUEST_EXCEPTION_BY_PERIOD_LINE, + this.constants.FTP_REQUEST_EXCEPTION_BY_PERIOD_LINE, + this.constants.SMTP_REQUEST_EXCEPTION_BY_PERIOD_LINE, + this.constants.LDAP_REQUEST_EXCEPTION_BY_PERIOD_LINE].forEach(p => { + p.options.chart.toolbar = { + show: true, + tools: { + customIcons: [{ + icon: '', + title: 'Détail', + class: 'custom-icon', + click: function (chart: any, options: any, e: any) { + dis.openProtocolDialog({ observable: dis.requests[p.options.chart.data.name], type: p.options.chart.data.type }); + } + }], + } + } + return p + }) + } + + removePackage(errorType: string) { + const index = errorType.lastIndexOf('.') + 1; + return errorType?.substring(index); + return '' + } + + openProtocolDialog(exceptions: { observable: any, type: string }) { + if (exceptions.observable.data.data.length > 0 && exceptions.observable.data.data.some((d: any) => d.count > 0)) { + + const dialog = this._dialog.open(ProtocolExceptionComponent, { + width: "70%", + data: exceptions + }) + + dialog.afterClosed().subscribe(result => { + }) + } + } + + patchServerValue(servers: any[]) { + this.serverFilterForm.patchValue({ + appname: servers + }, { emitEvent: false }) + } + + setChartData(data: any[], type: string, chartName: string, configName: string, groupedBy: string) { + let c: any = this.constants; + let title = `${c[configName].options.chart.data.type}: ` + let subtitle = '' + formatters[groupedBy](data, this._datePipe) + + let arr = this.groupByProperty("date", data).map((d: any) => { return { ...d, perc: (d.count * 100) / d.countok } }); + if (arr.length) { + let sumRes = this.sumcounts(arr); + title = `${type}: ${((sumRes.count * 100) / sumRes.countok).toFixed(2)}%`; + subtitle = `sur ${sumRes.countok} requête(s)`; + } + let config = { ...c[configName] } + config.options.title.text = title + config.options.subtitle.text = subtitle + c[configName] = config + this.charts[chartName] = arr; + + return data; + } + + groupByProperty(property: string, array: any[]) { + let helper: any = {}; + return array.reduce((acc: any, item: any) => { + + if (!helper[item[property]]) { + helper[item[property]] = Object.assign({}, item); + acc.push(helper[item[property]]); + } else { + helper[item[property]].countok += item["countok"]; + helper[item[property]].count += item["count"]; + } + return acc; + }, []); + } + + sumcounts(array: any[]) { + return array.reduce((acc, obj) => { + return { + countok: acc.countok + obj.countok, + count: acc.count + obj.count + } + }, { countok: 0, count: 0 }); + } + + + REQUESTS = (env: string, start: Date, end: Date, app_name: string) => { + let groupedBy = periodManagement(start, end); + let serverStartAppName = ""; + if (app_name) { + serverStartAppName = `.and(${app_name})`; + } + return { + + // Server start + serverStartTable: { observable: this._statsService.getInstance({ 'column': `view1.appName,view1.version,view1.start`, 'view': `select(app_name,version,start,rank.over(partition(environement,app_name).order(start.desc)):rk).filter(type.eq(SERVER).and(environement.eq(${env})).and(start.ge(${start.toISOString()})).and(start.lt(${end.toISOString()}))${serverStartAppName}):view1`, 'view1.rk': '1', 'order': 'view1.start.desc' }) }, + + // Rest-Main Sessions exceptions + sessionExceptionsTable: { + observable: this._statsService.getRestSession({ "column": `start.${groupedBy}:date,err_type,count:count,count.sum.over(partition(date)):countok,count.divide(countok).multiply(100).round(2):pct,start.year:year`, 'join': 'instance', 'instance.environement': env, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), [app_name]: '', "order": "date.desc,count.desc" }) + .pipe(map(((result: any[]) => { + formatters[groupedBy](result, this._datePipe) + // result.map( ) + return result.filter(r => r.errorType != null); + }))) + + + }, + + batchExceptionTable: { + observable: this._statsService.getMainSession({ "column": `start.${groupedBy}:date,err_type,count:count,count.sum.over(partition(date)):countok,count.divide(countok).multiply(100).round(2):pct,start.year:year`, 'main_session.type': 'BATCH', 'join': 'instance', 'instance.environement': env, 'start.ge': start.toISOString(), [app_name]: '', 'start.lt': end.toISOString(), "order": "date.desc,count.desc" }) + .pipe(map(((result: any[]) => { + formatters[groupedBy](result, this._datePipe) + return result.filter(r => r.errorType != null); + }))) + }, + + //------- TABLE + CHART + restRequestExceptionsTable: { + observable: combineLatest({ + restSession: this._statsService.getRestRequest({ 'column': `count:countok,exception.count_exception:count,exception.err_type.coalesce():err_type,start.${groupedBy}:date,start.year:year`, 'instance.environement': env, 'join': 'exception,rest_request.rest_session,rest_session.instance', 'start.ge': start.toISOString(), [app_name]: '', 'start.lt': end.toISOString(), 'order': 'date.asc' }), + mainSession: this._statsService.getRestRequest({ 'column': `count:countok,exception.count_exception:count,exception.err_type.coalesce():err_type,start.${groupedBy}:date,start.year:year`, 'instance.environement': env, 'join': 'exception,rest_request.main_session,main_session.instance', 'start.ge': start.toISOString(), [app_name]: '', 'start.lt': end.toISOString(), 'order': 'date.asc' }) + }) + .pipe(map(((result: { restSession: any[]; mainSession: any[]; }) => { + let r = this.setChartData([...result.restSession, ...result.mainSession], 'REST', 'restRequestExceptionsTable', 'REST_REQUEST_EXCEPTION_BY_PERIOD_LINE', groupedBy) + return r; + }))) + }, + + databaseRequestExceptionsTable: { + observable: forkJoin({ + restSession: this._statsService.getDatabaseRequest({ 'column': `count:countok,exception.count_exception:count,exception.err_type.coalesce():err_type,start.${groupedBy}:date,start.year:year`, 'instance.environement': env, 'join': 'exception,database_request.rest_session,rest_session.instance', 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), [app_name]: '', 'order': 'date.asc' }), + mainSession: this._statsService.getDatabaseRequest({ 'column': `count:countok,exception.count_exception:count,exception.err_type.coalesce():err_type,start.${groupedBy}:date,start.year:year`, 'instance.environement': env, 'join': 'exception,database_request.main_session,main_session.instance', 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), [app_name]: '', 'order': 'date.asc' }) + }) + .pipe(map(((result: { restSession: any[]; mainSession: any[]; }) => { + let r = this.setChartData([...result.restSession, ...result.mainSession], 'JDBC', 'databaseRequestExceptionsTable', 'DATABASE_REQUEST_EXCEPTION_BY_PERIOD_LINE', groupedBy) + return r; + }))) + }, + ftpRequestExceptionsTable: { + observable: forkJoin({ + restSession: this._statsService.getFtpRequest({ 'column': `count:countok,exception.count_exception:count,exception.err_type.coalesce():err_type,start.${groupedBy}:date,start.year:year`, 'instance.environement': env, 'join': 'exception,ftp_request.rest_session,rest_session.instance', 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), [app_name]: '', 'order': 'date.asc' }), + mainSession: this._statsService.getFtpRequest({ 'column': `count:countok,exception.count_exception:count,exception.err_type.coalesce():err_type,start.${groupedBy}:date,start.year:year`, 'instance.environement': env, 'join': 'exception,ftp_request.main_session,main_session.instance', 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), [app_name]: '', 'order': 'date.asc' }) + }) + .pipe(map(((result: { restSession: any[]; mainSession: any[]; }) => { + let r = this.setChartData([...result.restSession, ...result.mainSession], 'FTP', 'ftpRequestExceptionsTable', 'FTP_REQUEST_EXCEPTION_BY_PERIOD_LINE', groupedBy) + return r; + }))) + }, + smtpRequestExceptionsTable: { + observable: forkJoin({ + restSession: this._statsService.getSmtpRequest({ 'column': `count:countok,exception.count_exception:count,exception.err_type.coalesce():err_type,start.${groupedBy}:date,start.year:year`, 'instance.environement': env, 'join': 'exception,smtp_request.rest_session,rest_session.instance', 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), [app_name]: '', 'order': 'date.asc' }), + mainSession: this._statsService.getSmtpRequest({ 'column': `count:countok,exception.count_exception:count,exception.err_type.coalesce():err_type,start.${groupedBy}:date,start.year:year`, 'instance.environement': env, 'join': 'exception,smtp_request.main_session,main_session.instance', 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), [app_name]: '', 'order': 'date.asc' }) + }) + .pipe(map(((result: { restSession: any[]; mainSession: any[]; }) => { + let r = this.setChartData([...result.restSession, ...result.mainSession], 'SMTP', 'smtpRequestExceptionsTable', 'SMTP_REQUEST_EXCEPTION_BY_PERIOD_LINE', groupedBy) + return r; + }))) + }, + ldapRequestExceptionsTable: { + observable: forkJoin({ + restSession: this._statsService.getLdapRequest({ 'column': `count:countok,exception.count_exception:count,exception.err_type.coalesce():err_type,start.${groupedBy}:date,start.year:year`, 'instance.environement': env, 'join': 'exception,ldap_request.rest_session,rest_session.instance', 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), [app_name]: '', 'order': 'date.asc' }), + mainSession: this._statsService.getLdapRequest({ 'column': `count:countok,exception.count_exception:count,exception.err_type.coalesce():err_type,start.${groupedBy}:date,start.year:year`, 'instance.environement': env, 'join': 'exception,ldap_request.main_session,main_session.instance', 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), [app_name]: '', 'order': 'date.asc' }) + }) + .pipe(map(((result: { restSession: any[]; mainSession: any[]; }) => { + let r = this.setChartData([...result.restSession, ...result.mainSession], 'LDAP', 'ldapRequestExceptionsTable', 'LDAP_REQUEST_EXCEPTION_BY_PERIOD_LINE', groupedBy) + return r; + }))) + }, + } + } } + + + + +// old restsession batch session exception requests +/*sessionExceptionsTable: { + observable: combineLatest({ + countError: this._statsService.getRestSession({ 'column': `count:count,err_type,start.${groupedBy}:date,start.year:year`, 'err_type.notNull': '', 'join': 'instance', 'instance.environement': env, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'order': `date.desc`, 'limit': 10 }), + countOk: this._statsService.getRestSession({ 'column': `count:count,start.${groupedBy}:date,start.year:year`, 'join': 'instance', 'instance.environement': env, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'order': `date.desc`, 'limit': 10 }) + }) + .pipe(map(((result: { countError: any[], countOk: any[] }) => { + formatters[groupedBy](result.countError, this._datePipe) + formatters[groupedBy](result.countOk, this._datePipe) + + result.countError.forEach((e) => { + e['countok'] = result.countOk.find(a => a.date == e.date).count + }) + return result.countError; + }))) + },*/ + +/*batchExceptionTable: { + observable: combineLatest({ + countError: this._statsService.getMainSession({ 'column': `count:count,err_type,start.${groupedBy}:date,start.year:year`, 'err_type.notNull': '', 'main_session.type': 'BATCH', 'join': 'instance', 'instance.environement': env, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'order': `date.desc`, 'limit': 10 }), + countOk: this._statsService.getMainSession({ 'column': `count:count,start.${groupedBy}:date,start.year:year`, 'main_session.type': 'BATCH', 'join': 'instance', 'instance.environement': env, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'order': `date.desc`, 'limit': 10 }) + }) + .pipe(map(((result: { countError: any[], countOk: any[] }) => { + formatters[groupedBy](result.countError, this._datePipe) + formatters[groupedBy](result.countOk, this._datePipe) + + result.countError.forEach((e) => { + e['countok'] = result.countOk.find(a => a.date == e.date).count + }) + + console.log(result.countError) + + return result.countError; + }))) +},*/ + + + + + +//-------CHART + + + +/* + +restRequestExceptionsChart: { + observable: forkJoin({ + restSession: this._statsService.getRestRequest({ 'column': `count:countok,exception.count_exception:count,start.${groupedBy}:date,start.year:year`, 'instance.environement': env, 'join': 'exception,rest_session,rest_session.instance', 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'order': 'date.asc' }), + mainSession: this._statsService.getRestRequest({ 'column': `count:countok,exception.count_exception:count,start.${groupedBy}:date,start.year:year`, 'instance.environement': env, 'join': 'exception,main_session,main_session.instance', 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'order': 'date.asc' }) + }) + .pipe(map(((result: { restSession: any[]; mainSession: any[]; }) => { + let r = [...result.restSession, ...result.mainSession]; + formatters[groupedBy](r, this._datePipe) + r = this.groupByProperty("date", r); + r.sort((a, b) => a.date.localeCompare(b.date)); + this.constants.REST_REQUEST_EXCEPTION_BY_PERIOD_LINE.options.title.text = "100%" + console.log(r) + return r; + }))) +}, + + +databaseRequestExceptionsChart: { + observable: this._statsService.getDatabaseRequest({ 'column': `count:countok,exception.count_exception:count,start.${groupedBy}:date,start.year:year`, 'instance.environement': env, 'join': 'exception,database_request.rest_session,rest_session.instance', 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'order': 'date.asc' }) + .pipe(map(((r: any[]) => { + formatters[groupedBy](r, this._datePipe) + return r; + }))) +}, +ftpRequestExceptionsChart: { + observable: this._statsService.getFtpRequest({ 'column': `count:countok,exception.count_exception:count,start.${groupedBy}:date,start.year:year`, 'instance.environement': env, 'join': 'exception,ftp_request.rest_session,rest_session.instance', 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'order': 'date.asc' }) + .pipe(map(((r: any[]) => { + formatters[groupedBy](r, this._datePipe) + return r; + }))) +}, +smtpRequestExceptionsChart: { + observable: this._statsService.getSmtpRequest({ 'column': `count:countok,exception.count_exception:count,start.${groupedBy}:date,start.year:year`, 'instance.environement': env, 'join': 'exception,smtp_request.rest_session,rest_session.instance', 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'order': 'date.asc' }) + .pipe(map(((r: any[]) => { + formatters[groupedBy](r, this._datePipe) + return r; + }))) +}, +ldapRequestExceptionsChart: { + observable: this._statsService.getLdapRequest({ 'column': `count:countok,exception.count_exception:count,start.${groupedBy}:date,start.year:year`, 'instance.environement': env, 'join': 'exception,ldap_request.rest_session,rest_session.instance', 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), 'order': 'date.asc' }) + .pipe(map(((r: any[]) => { + formatters[groupedBy](r, this._datePipe) + return r; + }))) +},*/ + + + + + + + + + + + diff --git a/src/app/views/search/rest/search-rest.view.ts b/src/app/views/search/rest/search-rest.view.ts index 38fd4ba..95a9228 100644 --- a/src/app/views/search/rest/search-rest.view.ts +++ b/src/app/views/search/rest/search-rest.view.ts @@ -56,7 +56,6 @@ export class SearchRestView implements OnInit, OnDestroy { this._activatedRoute.queryParams .subscribe({ next: (params: Params) => { - console.log(params['start'], params['end']) this.params.env = params['env'] || application.default_env; this.params.start = params['start'] ? new Date(params['start']) : (application.session.api.default_period || makePeriod(0)).start; this.params.end = params['end'] ? new Date(params['end']) : (application.session.api.default_period || makePeriod(0, 1)).end; diff --git a/src/app/views/views.module.ts b/src/app/views/views.module.ts index ac585ff..16e0dcd 100644 --- a/src/app/views/views.module.ts +++ b/src/app/views/views.module.ts @@ -39,6 +39,7 @@ import { StatisticUserSessionTableComponent } from "./statistic/user/_component/session-table/statistic-user-session-table.component"; import {DashboardComponent} from "./dashboard/dashboard.component"; +import { ProtocolExceptionComponent } from './dashboard/components/protocol-exception-modal/protocol-exception-modal.component'; @NgModule({ imports: [ @@ -76,7 +77,8 @@ import {DashboardComponent} from "./dashboard/dashboard.component"; StatisticDependenciesTableComponent, StatisticExceptionTableComponent, StatisticUserSessionTableComponent, - DashboardComponent + DashboardComponent, + ProtocolExceptionComponent ] }) export class ViewsModule { } diff --git a/src/environments/environment.ts b/src/environments/environment.ts index a571b51..003d298 100644 --- a/src/environments/environment.ts +++ b/src/environments/environment.ts @@ -21,6 +21,9 @@ export const application: Application = { }, dashboard: { default_period: makePeriod(6, 1), + home: { + default_period : makePeriod (0, 1) + }, api : { default_period: undefined }, diff --git a/src/styles.scss b/src/styles.scss index 3ef20c5..5ca3289 100644 --- a/src/styles.scss +++ b/src/styles.scss @@ -191,6 +191,14 @@ mat-form-field.loading { overflow: initial; } +.error-badge { + background-color: red; + color: white; + padding: 2px 6px; + text-align: center; + border-radius: 12px; +} + From 3bca747320e2d55494164427624ed5ef5ce41774 Mon Sep 17 00:00:00 2001 From: YoussefDahi Date: Mon, 23 Sep 2024 01:46:51 +0200 Subject: [PATCH 062/126] dashboard Home Component --- src/app/app.module.ts | 11 ++- src/app/model/jquery.model.ts | 13 ++++ .../jquery/database-request.service.ts | 30 +++++++- src/app/service/jquery/instance.service.ts | 23 ++++-- .../service/jquery/main-session.service.ts | 25 +++++-- .../service/jquery/rest-session.service.ts | 16 ++++- .../views/dashboard/dashboard.component.ts | 70 +++++++++++-------- 7 files changed, 137 insertions(+), 51 deletions(-) diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 7f4fcc3..6d20789 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -158,11 +158,13 @@ const routes: Route[] = [ }, { path: 'dashboard', + component: DashboardComponent, + title: 'Dashboard', children: [ { path: 'server/:server_name', component: StatisticApplicationView, - title: 'Statistiques Serveur' + title: 'Statist iques Serveur' }, { path: 'server/:server_name/rest/:rest_name', @@ -179,14 +181,9 @@ const routes: Route[] = [ component: StatisticDatabaseView, title: 'Statistiques Base de Donnée' }, - { path: '**', pathMatch: 'full', redirectTo: `/session/rest` } + // { path: '**', pathMatch: 'full', redirectTo: `/session/rest` } ] }, - /*{ - path: 'dashboard', - component: DashboardComponent, - title: 'Dashboard' - },*/ { path: '**', pathMatch: 'full', redirectTo: `/session/rest` } ]; diff --git a/src/app/model/jquery.model.ts b/src/app/model/jquery.model.ts index be9caca..191e775 100644 --- a/src/app/model/jquery.model.ts +++ b/src/app/model/jquery.model.ts @@ -1,6 +1,19 @@ export type RepartitionTimeAndTypeResponse = {elapsedTimeSlowest: number, elapsedTimeSlow: number, elapsedTimeMedium: number, elapsedTimeFast: number, elapsedTimeFastest: number, countSucces: number, countErrorServer: number, countErrorClient: number}[]; export type RepartitionTimeAndTypeResponseByPeriod = {countSucces: number, countErrorClient: number, countErrorServer: number, elapsedTimeSlowest: number, elapsedTimeSlow: number, elapsedTimeMedium: number, elapsedTimeFast: number, elapsedTimeFastest: number, avg: number, max: number, date: number, year: number}[]; export type RepartitionRequestByPeriod = {count: number, countErrorServer: number, countSlowest: number, date: number}[]; +export type ServerStartByPeriodAndAppname = { appName: string, version: string, start:number}[]; +export type SessionExceptionsByPeriodAndAppname = {date: string, errorType: string, count: number, countok: number, groupedBy: string,}; +export type MainExceptionsByPeriodAndAppname = {date: string, errorType: string, count: number, countok: number, groupedBy: string,}; +export type LdapSessionExceptionsByPeriodAndappname = {countok: number,count: number, date: string, year: string }; +export type LdapMainExceptionsByPeriodAndappname = {countok: number,count: number, date: string, year: string }; +export type SmtpSessionExceptionsByPeriodAndappname = {countok: number,count: number, date: string, year: string }; +export type SmtpMainExceptionsByPeriodAndappname = {countok: number,count: number, date: string, year: string }; +export type RestMainExceptionsByPeriodAndappname = {countok: number,count: number, date: string, year: string }; +export type RestSessionExceptionsByPeriodAndappname = {countok: number,count: number, date: string, year: string }; +export type FtpMainExceptionsByPeriodAndappname = {countok: number,count: number, date: string, year: string }; +export type FtpSessionExceptionsByPeriodAndappname = {countok: number,count: number, date: string, year: string }; +export type JdbcMainExceptionsByPeriodAndappname = {countok: number,count: number, date: string, year: string }; +export type JdbcSessionExceptionsByPeriodAndappname = {countok: number,count: number, date: string, year: string }; diff --git a/src/app/service/jquery/database-request.service.ts b/src/app/service/jquery/database-request.service.ts index ab1405a..39890c2 100644 --- a/src/app/service/jquery/database-request.service.ts +++ b/src/app/service/jquery/database-request.service.ts @@ -1,7 +1,7 @@ import {Injectable} from "@angular/core"; import {HttpClient} from "@angular/common/http"; import {Observable} from "rxjs"; -import {RepartitionRequestByPeriod} from "../../model/jquery.model"; +import {JdbcMainExceptionsByPeriodAndappname, JdbcSessionExceptionsByPeriodAndappname, RepartitionRequestByPeriod} from "../../model/jquery.model"; @Injectable({ providedIn: 'root' }) export class DatabaseRequestService { @@ -62,4 +62,32 @@ export class DatabaseRequestService { } return this.getDatabaseRequest(args); } + + getJdbcRestSessionExceptions(filters: { env: string, start: Date, end: Date, groupedBy: string, app_name: string }): Observable { + let args = { + 'column': `count:countok,exception.count_exception:count,exception.err_type.coalesce():err_type,start.${filters.groupedBy}:date,start.year:year`, + 'instance.environement': filters.env, + 'join': 'exception,database_request.rest_session,rest_session.instance', + 'start.ge': filters.start.toISOString(), + 'start.lt': filters.end.toISOString(), + [filters.app_name]: '', + 'order': 'date.asc' + } + return this.getDatabaseRequest(args); + } + + getJdbcMainSessionExceptions(filters: { env: string, start: Date, end: Date, groupedBy: string, app_name: string }): Observable{ + let args = { + 'column': `count:countok,exception.count_exception:count,exception.err_type.coalesce():err_type,start.${filters.groupedBy}:date,start.year:year`, + 'instance.environement': filters.env, + 'join': 'exception,database_request.main_session,main_session.instance', + 'start.ge': filters.start.toISOString(), + 'start.lt': filters.end.toISOString(), + [filters.app_name]: '', + 'order': 'date.asc' } + return this.getDatabaseRequest(args); + } + + + } \ No newline at end of file diff --git a/src/app/service/jquery/instance.service.ts b/src/app/service/jquery/instance.service.ts index 93f548c..bbd27a4 100644 --- a/src/app/service/jquery/instance.service.ts +++ b/src/app/service/jquery/instance.service.ts @@ -1,6 +1,7 @@ -import {Injectable} from "@angular/core"; -import {HttpClient} from "@angular/common/http"; -import {Observable} from "rxjs"; +import { Injectable } from "@angular/core"; +import { HttpClient } from "@angular/common/http"; +import { Observable } from "rxjs"; +import { ServerStartByPeriodAndAppname } from "src/app/model/jquery.model"; @Injectable({ providedIn: 'root' }) export class InstanceService { @@ -13,7 +14,7 @@ export class InstanceService { return this.http.get(url, { params: params }); } - getIds(env: string, end: Date, appName: string): Observable<{id: string}[]> { + getIds(env: string, end: Date, appName: string): Observable<{ id: string }[]> { let args: any = { 'column.distinct': 'id', 'app_name.in': `"${appName}"`, @@ -22,8 +23,8 @@ export class InstanceService { } return this.getInstance(args); } - - getEnvironments(): Observable<{environement: string}[]> { + + getEnvironments(): Observable<{ environement: string }[]> { let args = { 'column.distinct': 'environement', 'environement.notNull': '', @@ -32,11 +33,19 @@ export class InstanceService { return this.getInstance(args); } - getApplications(): Observable<{appName: string}[]> { + getApplications(): Observable<{ appName: string }[]> { let args = { 'column.distinct': 'app_name:appName', 'order': 'app_name.asc' } return this.getInstance(args); } + + getServerStart(filters : {env: string, start:Date, end: Date,groupedBy:string, app_name: string }): Observable { + let args = { + 'column': `view1.appName,view1.version,view1.start`, + 'view': `select(app_name,version,start,rank.over(partition(environement,app_name).order(start.desc)):rk).filter(type.eq(SERVER).and(environement.eq(${filters.env})).and(start.ge(${filters.start.toISOString()})).and(start.lt(${filters.end.toISOString()}))${filters.app_name}):view1`, + 'view1.rk': '1', 'order': 'view1.start.desc' } + return this.getInstance(args); + } } \ No newline at end of file diff --git a/src/app/service/jquery/main-session.service.ts b/src/app/service/jquery/main-session.service.ts index e0a3440..acc24f5 100644 --- a/src/app/service/jquery/main-session.service.ts +++ b/src/app/service/jquery/main-session.service.ts @@ -1,7 +1,8 @@ -import {Injectable} from "@angular/core"; -import {HttpClient} from "@angular/common/http"; -import {Observable} from "rxjs"; -import {FilterMap} from "../../views/constants"; +import { Injectable } from "@angular/core"; +import { HttpClient } from "@angular/common/http"; +import { Observable } from "rxjs"; +import { FilterMap } from "../../views/constants"; +import { MainExceptionsByPeriodAndAppname } from "src/app/model/jquery.model"; @Injectable({ providedIn: 'root' }) export class MainSessionService { @@ -14,7 +15,7 @@ export class MainSessionService { return this.http.get(url, { params: params }); } - getInfos(filters: {start: Date, end: Date, advancedParams: FilterMap, user: string, env: string}): Observable<{name: string, date: number, elapsedtime: number, location: string, appName: string}[]> { + getInfos(filters: { start: Date, end: Date, advancedParams: FilterMap, user: string, env: string }): Observable<{ name: string, date: number, elapsedtime: number, location: string, appName: string }[]> { let args = { 'column': "name:name,start:date,elapsedtime:elapsedtime,location:location,instance.app_name:appName", 'main_session.instance_env': 'instance.id', @@ -28,4 +29,18 @@ export class MainSessionService { } return this.getMainSession(args) } + + getMainExceptions(filters: { env: string, start: Date, end: Date, groupedBy: string, app_name: string }): Observable { + let args = { + "column": `start.${filters.groupedBy}:date,err_type,count:count,count.sum.over(partition(date)):countok,count.divide(countok).multiply(100).round(2):pct,start.year:year`, + 'main_session.type': 'BATCH', + 'join': 'instance', + 'instance.environement': filters.env, + 'start.ge': filters.start.toISOString(), + [filters.app_name]: '', + 'start.lt': filters.end.toISOString(), + "order": "date.desc,count.desc" + } + return this.getMainSession(args); + } } \ No newline at end of file diff --git a/src/app/service/jquery/rest-session.service.ts b/src/app/service/jquery/rest-session.service.ts index 14a1954..9c8674b 100644 --- a/src/app/service/jquery/rest-session.service.ts +++ b/src/app/service/jquery/rest-session.service.ts @@ -5,7 +5,8 @@ import {FilterMap} from "../../views/constants"; import { RepartitionRequestByPeriod, RepartitionTimeAndTypeResponse, - RepartitionTimeAndTypeResponseByPeriod + RepartitionTimeAndTypeResponseByPeriod, + SessionExceptionsByPeriodAndAppname } from "../../model/jquery.model"; @Injectable({ providedIn: 'root' }) @@ -233,4 +234,17 @@ export class RestSessionService { } return this.getRestSession(args); } + + getSessionExceptions(filters : {env: string, start:Date, end: Date,groupedBy:string, app_name: string }): Observable { + let args = { + "column": `start.${filters.groupedBy}:date,err_type,count:count,count.sum.over(partition(date)):countok,count.divide(countok).multiply(100).round(2):pct,start.year:year`, + 'join': 'instance', + 'instance.environement': filters.env, + 'start.ge': filters.start.toISOString(), + 'start.lt': filters.end.toISOString(), + [filters.app_name]: '', + "order": "date.desc,count.desc" + } + return this.getRestSession(args); + } } \ No newline at end of file diff --git a/src/app/views/dashboard/dashboard.component.ts b/src/app/views/dashboard/dashboard.component.ts index 70bd8ab..a9db70d 100644 --- a/src/app/views/dashboard/dashboard.component.ts +++ b/src/app/views/dashboard/dashboard.component.ts @@ -7,13 +7,20 @@ import { EnvRouter } from "../../service/router.service"; import { FormControl, FormGroup, Validators } from '@angular/forms'; import { Constants } from '../constants'; import { formatters, periodManagement } from 'src/app/shared/util'; -import { JQueryService } from 'src/app/service/jquery.service'; import { MatDialog } from '@angular/material/dialog'; import { ProtocolExceptionComponent } from './components/protocol-exception-modal/protocol-exception-modal.component'; -import { cp } from 'fs'; import { MatPaginator } from '@angular/material/paginator'; import { MatTableDataSource } from '@angular/material/table'; import { MatSort } from '@angular/material/sort'; +import { InstanceService } from 'src/app/service/jquery/instance.service'; +import { RestSessionService } from 'src/app/service/jquery/rest-session.service'; +import { MainSessionService } from 'src/app/service/jquery/main-session.service'; +import { restRequestService } from 'src/app/service/jquery/rest-request.service'; +import { DatabaseRequestService } from 'src/app/service/jquery/database-request.service'; +import { FtpRequestService} from 'src/app/service/jquery/ftp-request.service'; +import { LdapRequestService } from 'src/app/service/jquery/ldap-request.service'; +import { FtpMainExceptionsByPeriodAndappname, FtpSessionExceptionsByPeriodAndappname, JdbcMainExceptionsByPeriodAndappname, JdbcSessionExceptionsByPeriodAndappname, LdapMainExceptionsByPeriodAndappname, LdapSessionExceptionsByPeriodAndappname, RestMainExceptionsByPeriodAndappname, RestSessionExceptionsByPeriodAndappname, SessionExceptionsByPeriodAndAppname, SmtpMainExceptionsByPeriodAndappname, SmtpSessionExceptionsByPeriodAndappname } from 'src/app/model/jquery.model'; +import { smtpRequestService } from 'src/app/service/jquery/smtp-request.service'; @Component({ templateUrl: './dashboard.component.html', styleUrls: ['./dashboard.component.scss'], @@ -23,12 +30,18 @@ export class DashboardComponent { constants = Constants; private _activatedRoute: ActivatedRoute = inject(ActivatedRoute); private _router: EnvRouter = inject(EnvRouter); + private _instanceService = inject(InstanceService); + private _sessionService = inject(RestSessionService); + private _mainService = inject(MainSessionService); + private _restService = inject(restRequestService); + private _datebaseService = inject(DatabaseRequestService); + private _ftpService = inject(FtpRequestService); + private _smtpService = inject(smtpRequestService) + private _ldapService = inject(LdapRequestService); private _location: Location = inject(Location); - private _statsService: JQueryService = inject(JQueryService); private _datePipe = inject(DatePipe); private _dialog = inject(MatDialog) - MAPPING_TYPE = Constants.MAPPING_TYPE; serverStartDisplayedColumns: string[] = ["appName","version", "duree"]; sessionExceptionsDisplayedColumns: string[] = ["date", "errorType", "count"]; @@ -75,7 +88,7 @@ export class DashboardComponent { this.patchServerValue(this.params.serveurs); } this.patchDateValue(this.params.start, new Date(this.params.end.getFullYear(), this.params.end.getMonth(), this.params.end.getDate() - 1)); - this.subscriptions.push(this._statsService.getInstance({ 'column.distinct': 'app_name', 'order': 'app_name.asc' }) + this.subscriptions.push(this._instanceService.getApplications() .pipe(finalize(() => this.serverNameIsLoading = false)) .subscribe({ next: (appNames: { appName: string }[]) => { @@ -187,7 +200,6 @@ export class DashboardComponent { removePackage(errorType: string) { const index = errorType.lastIndexOf('.') + 1; return errorType?.substring(index); - return '' } openProtocolDialog(exceptions: { observable: any, type: string }) { @@ -264,23 +276,21 @@ export class DashboardComponent { return { // Server start - serverStartTable: { observable: this._statsService.getInstance({ 'column': `view1.appName,view1.version,view1.start`, 'view': `select(app_name,version,start,rank.over(partition(environement,app_name).order(start.desc)):rk).filter(type.eq(SERVER).and(environement.eq(${env})).and(start.ge(${start.toISOString()})).and(start.lt(${end.toISOString()}))${serverStartAppName}):view1`, 'view1.rk': '1', 'order': 'view1.start.desc' }) }, + serverStartTable: { observable: this._instanceService.getServerStart({env: env, start: start, end: end,groupedBy: groupedBy, app_name: serverStartAppName})}, // Rest-Main Sessions exceptions sessionExceptionsTable: { - observable: this._statsService.getRestSession({ "column": `start.${groupedBy}:date,err_type,count:count,count.sum.over(partition(date)):countok,count.divide(countok).multiply(100).round(2):pct,start.year:year`, 'join': 'instance', 'instance.environement': env, 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), [app_name]: '', "order": "date.desc,count.desc" }) - .pipe(map(((result: any[]) => { + observable: this._sessionService.getSessionExceptions({env: env, start: start, end: end,groupedBy: groupedBy, app_name: serverStartAppName}) + .pipe(map(((result: SessionExceptionsByPeriodAndAppname[]) => { formatters[groupedBy](result, this._datePipe) - // result.map( ) - return result.filter(r => r.errorType != null); + // result.map( ) + return result.filter(r => r.errorType != null); // rename errorType to errType in backend }))) - - }, batchExceptionTable: { - observable: this._statsService.getMainSession({ "column": `start.${groupedBy}:date,err_type,count:count,count.sum.over(partition(date)):countok,count.divide(countok).multiply(100).round(2):pct,start.year:year`, 'main_session.type': 'BATCH', 'join': 'instance', 'instance.environement': env, 'start.ge': start.toISOString(), [app_name]: '', 'start.lt': end.toISOString(), "order": "date.desc,count.desc" }) - .pipe(map(((result: any[]) => { + observable: this._mainService.getMainExceptions({env: env, start: start, end: end,groupedBy: groupedBy, app_name: serverStartAppName}) + .pipe(map(((result: SessionExceptionsByPeriodAndAppname[]) => { formatters[groupedBy](result, this._datePipe) return result.filter(r => r.errorType != null); }))) @@ -289,10 +299,10 @@ export class DashboardComponent { //------- TABLE + CHART restRequestExceptionsTable: { observable: combineLatest({ - restSession: this._statsService.getRestRequest({ 'column': `count:countok,exception.count_exception:count,exception.err_type.coalesce():err_type,start.${groupedBy}:date,start.year:year`, 'instance.environement': env, 'join': 'exception,rest_request.rest_session,rest_session.instance', 'start.ge': start.toISOString(), [app_name]: '', 'start.lt': end.toISOString(), 'order': 'date.asc' }), - mainSession: this._statsService.getRestRequest({ 'column': `count:countok,exception.count_exception:count,exception.err_type.coalesce():err_type,start.${groupedBy}:date,start.year:year`, 'instance.environement': env, 'join': 'exception,rest_request.main_session,main_session.instance', 'start.ge': start.toISOString(), [app_name]: '', 'start.lt': end.toISOString(), 'order': 'date.asc' }) + restSession: this._restService.getrestSessionExceptions({env: env, start: start, end: end,groupedBy: groupedBy, app_name: serverStartAppName}), + mainSession: this._restService.getrestMainExceptions({env: env, start: start, end: end,groupedBy: groupedBy, app_name: serverStartAppName}) }) - .pipe(map(((result: { restSession: any[]; mainSession: any[]; }) => { + .pipe(map(((result: { restSession: RestSessionExceptionsByPeriodAndappname[]; mainSession: RestMainExceptionsByPeriodAndappname[]; }) => { let r = this.setChartData([...result.restSession, ...result.mainSession], 'REST', 'restRequestExceptionsTable', 'REST_REQUEST_EXCEPTION_BY_PERIOD_LINE', groupedBy) return r; }))) @@ -300,40 +310,40 @@ export class DashboardComponent { databaseRequestExceptionsTable: { observable: forkJoin({ - restSession: this._statsService.getDatabaseRequest({ 'column': `count:countok,exception.count_exception:count,exception.err_type.coalesce():err_type,start.${groupedBy}:date,start.year:year`, 'instance.environement': env, 'join': 'exception,database_request.rest_session,rest_session.instance', 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), [app_name]: '', 'order': 'date.asc' }), - mainSession: this._statsService.getDatabaseRequest({ 'column': `count:countok,exception.count_exception:count,exception.err_type.coalesce():err_type,start.${groupedBy}:date,start.year:year`, 'instance.environement': env, 'join': 'exception,database_request.main_session,main_session.instance', 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), [app_name]: '', 'order': 'date.asc' }) + restSession: this._datebaseService.getJdbcRestSessionExceptions({env: env, start: start, end: end,groupedBy: groupedBy, app_name: serverStartAppName}), + mainSession: this._datebaseService.getJdbcMainSessionExceptions({env: env, start: start, end: end,groupedBy: groupedBy, app_name: serverStartAppName}) }) - .pipe(map(((result: { restSession: any[]; mainSession: any[]; }) => { + .pipe(map(((result: { restSession: JdbcSessionExceptionsByPeriodAndappname[]; mainSession: JdbcMainExceptionsByPeriodAndappname[]; }) => { let r = this.setChartData([...result.restSession, ...result.mainSession], 'JDBC', 'databaseRequestExceptionsTable', 'DATABASE_REQUEST_EXCEPTION_BY_PERIOD_LINE', groupedBy) return r; }))) }, ftpRequestExceptionsTable: { observable: forkJoin({ - restSession: this._statsService.getFtpRequest({ 'column': `count:countok,exception.count_exception:count,exception.err_type.coalesce():err_type,start.${groupedBy}:date,start.year:year`, 'instance.environement': env, 'join': 'exception,ftp_request.rest_session,rest_session.instance', 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), [app_name]: '', 'order': 'date.asc' }), - mainSession: this._statsService.getFtpRequest({ 'column': `count:countok,exception.count_exception:count,exception.err_type.coalesce():err_type,start.${groupedBy}:date,start.year:year`, 'instance.environement': env, 'join': 'exception,ftp_request.main_session,main_session.instance', 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), [app_name]: '', 'order': 'date.asc' }) + restSession: this._ftpService.getftpSessionExceptions({env: env, start: start, end: end,groupedBy: groupedBy, app_name: serverStartAppName}), + mainSession: this._ftpService.getftpMainExceptions({env: env, start: start, end: end,groupedBy: groupedBy, app_name: serverStartAppName}) }) - .pipe(map(((result: { restSession: any[]; mainSession: any[]; }) => { + .pipe(map(((result: { restSession: FtpSessionExceptionsByPeriodAndappname[]; mainSession: FtpMainExceptionsByPeriodAndappname[]; }) => { let r = this.setChartData([...result.restSession, ...result.mainSession], 'FTP', 'ftpRequestExceptionsTable', 'FTP_REQUEST_EXCEPTION_BY_PERIOD_LINE', groupedBy) return r; }))) }, smtpRequestExceptionsTable: { observable: forkJoin({ - restSession: this._statsService.getSmtpRequest({ 'column': `count:countok,exception.count_exception:count,exception.err_type.coalesce():err_type,start.${groupedBy}:date,start.year:year`, 'instance.environement': env, 'join': 'exception,smtp_request.rest_session,rest_session.instance', 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), [app_name]: '', 'order': 'date.asc' }), - mainSession: this._statsService.getSmtpRequest({ 'column': `count:countok,exception.count_exception:count,exception.err_type.coalesce():err_type,start.${groupedBy}:date,start.year:year`, 'instance.environement': env, 'join': 'exception,smtp_request.main_session,main_session.instance', 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), [app_name]: '', 'order': 'date.asc' }) + restSession: this._smtpService.getsmtpSessionExceptions({env: env, start: start, end: end,groupedBy: groupedBy, app_name: serverStartAppName}), + mainSession: this._smtpService.getsmtpMainExceptions({env: env, start: start, end: end,groupedBy: groupedBy, app_name: serverStartAppName}) }) - .pipe(map(((result: { restSession: any[]; mainSession: any[]; }) => { + .pipe(map(((result: { restSession: SmtpSessionExceptionsByPeriodAndappname[]; mainSession: SmtpMainExceptionsByPeriodAndappname[]; }) => { let r = this.setChartData([...result.restSession, ...result.mainSession], 'SMTP', 'smtpRequestExceptionsTable', 'SMTP_REQUEST_EXCEPTION_BY_PERIOD_LINE', groupedBy) return r; }))) }, ldapRequestExceptionsTable: { observable: forkJoin({ - restSession: this._statsService.getLdapRequest({ 'column': `count:countok,exception.count_exception:count,exception.err_type.coalesce():err_type,start.${groupedBy}:date,start.year:year`, 'instance.environement': env, 'join': 'exception,ldap_request.rest_session,rest_session.instance', 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), [app_name]: '', 'order': 'date.asc' }), - mainSession: this._statsService.getLdapRequest({ 'column': `count:countok,exception.count_exception:count,exception.err_type.coalesce():err_type,start.${groupedBy}:date,start.year:year`, 'instance.environement': env, 'join': 'exception,ldap_request.main_session,main_session.instance', 'start.ge': start.toISOString(), 'start.lt': end.toISOString(), [app_name]: '', 'order': 'date.asc' }) + restSession: this._ldapService.getLdapSessionExceptions({env: env, start: start, end: end,groupedBy: groupedBy, app_name: serverStartAppName}), + mainSession: this._ldapService.getLdapMainExceptions({env: env, start: start, end: end,groupedBy: groupedBy, app_name: serverStartAppName}) }) - .pipe(map(((result: { restSession: any[]; mainSession: any[]; }) => { + .pipe(map(((result: { restSession: LdapSessionExceptionsByPeriodAndappname[]; mainSession: LdapMainExceptionsByPeriodAndappname[]; }) => { let r = this.setChartData([...result.restSession, ...result.mainSession], 'LDAP', 'ldapRequestExceptionsTable', 'LDAP_REQUEST_EXCEPTION_BY_PERIOD_LINE', groupedBy) return r; }))) From 9089d34a0aa61517f154f53feecebee15765c651 Mon Sep 17 00:00:00 2001 From: fufuu Date: Mon, 23 Sep 2024 10:01:00 +0200 Subject: [PATCH 063/126] jquery v4 --- src/app/app.module.ts | 99 ++++++++++++++----- .../service/jquery/rest-session.service.ts | 23 ++--- .../main/detail-session-main.view.html | 4 +- .../main/detail-session-main.view.scss | 2 - .../rest/detail-session-rest.view.scss | 1 + .../statistic-dependencies-table.component.ts | 4 +- .../statistic-application.view.html | 16 +-- .../application/statistic-application.view.ts | 46 ++++++--- .../statistic/rest/statistic-rest.view.html | 14 +-- .../statistic/rest/statistic-rest.view.ts | 94 ++++++++++++------ src/environments/environment.ts | 2 +- 11 files changed, 206 insertions(+), 99 deletions(-) diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 7f4fcc3..7113e90 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -41,7 +41,7 @@ const routes: Route[] = [ { path: '', component: SearchRestView, - title: 'Recherche Appels REST', + title: 'Appel d\'API', }, { path: ':id_session', @@ -49,37 +49,39 @@ const routes: Route[] = [ { path: '', component: DetailSessionRestView, - title: 'Detail Appel REST' + title: `Appel d'API > Détail` }, { path: 'database/:id_jdbc', data: { type: 'rest' }, component: DetailDatabaseView, - title: 'Detail Base de donnée' + title: `Appel d'API > Base de donnée` }, { path: 'ftp/:id_ftp', data: { type: 'rest' }, component: DetailFtpView, - title: 'Detail Ftp' + title: `Appel d'API > FTP` }, { path: 'ldap/:id_ldap', data: { type: 'rest' }, component: DetailLdapView, - title: 'Detail Ldap' + title: `Appel d'API > LDAP` }, { path: 'smtp/:id_smtp', data: { type: 'rest' }, component: DetailSmtpView, - title: 'Detail Smtp' + title: `Appel d'API > SMTP` + }, { path: 'tree', data: { type: 'rest' }, component: TreeView, - title: 'Arbre d\'Appels' + title: `Appel d'API > Arbre d\'Appels` + }, { path: '**', pathMatch: 'full', redirectTo: `/session/rest/:id_session` } ] @@ -95,12 +97,12 @@ const routes: Route[] = [ component: SearchMainView, title: (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => { if (route.paramMap.get('type_main') == 'batch') { - return 'Recherche BATCHs'; + return 'Lancement de Batch'; } else if(route.paramMap.get('type_main') == 'startup') { - return 'Recherche Serveurs'; + return 'Lancement de Serveur'; } - return 'Recherche Vues'; - }, + return 'Navigation'; + } }, { path: ':id_session', @@ -109,43 +111,84 @@ const routes: Route[] = [ path: '', component: DetailSessionMainView, title: (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => { + let detail = '> Detail'; if (route.paramMap.get('type_main') == 'batch') { - return 'Detail BATCH'; + return `Lancement de Batch ${detail}`; } else if (route.paramMap.get('type_main') == 'startup') { - return 'Detail Serveur'; + return `Lancement de Serveur ${detail}`; } - return 'Detail Vue'; - }, + return `Navigation ${detail}`; + } }, { path: 'database/:id_jdbc', component: DetailDatabaseView, data: { type: 'main' }, - title: 'Detail Base de donnée' + title: (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => { + let detail = `> Base de Donnée`; + if (route.paramMap.get('type_main') == 'batch') { + return `Lancement de Batch ${detail}`; + } else if (route.paramMap.get('type_main') == 'startup') { + return `Lancement de Serveur ${detail}`; + } + return `Navigation ${detail}`; + } }, { path: 'ftp/:id_ftp', data: { type: 'main' }, component: DetailFtpView, - title: 'Detail Ftp' + title: (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => { + let detail = `> FTP`; + if (route.paramMap.get('type_main') == 'batch') { + return `Lancement de Batch ${detail}`; + } else if (route.paramMap.get('type_main') == 'startup') { + return `Lancement de Serveur ${detail}`; + } + return `Navigation ${detail}`; + } }, { path: 'ldap/:id_ldap', data: { type: 'main' }, component: DetailLdapView, - title: 'Detail Ldap' + title: (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => { + let detail = `> LDAP`; + if (route.paramMap.get('type_main') == 'batch') { + return `Lancement de Batch ${detail}`; + } else if (route.paramMap.get('type_main') == 'startup') { + return `Lancement de Serveur ${detail}`; + } + return `Navigation ${detail}`; + } }, { path: 'smtp/:id_smtp', data: { type: 'main' }, component: DetailSmtpView, - title: 'Detail Smtp' + title: (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => { + let detail = `> SMTP`; + if (route.paramMap.get('type_main') == 'batch') { + return `Lancement de Batch ${detail}`; + } else if (route.paramMap.get('type_main') == 'startup') { + return `Lancement de Serveur ${detail}`; + } + return `Navigation ${detail}`; + } }, { path: 'tree', data: { type: 'main' }, component: TreeView, - title: 'Arbre d\'appels' + title: (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => { + let detail = `> Arbre d'Appels`; + if (route.paramMap.get('type_main') == 'batch') { + return `Lancement de Batch ${detail}`; + } else if (route.paramMap.get('type_main') == 'startup') { + return `Lancement de Serveur ${detail}`; + } + return `Navigation ${detail}`; + } }, { path: '**', pathMatch: 'full', redirectTo: `/main/:type_main/:id_session` } ] @@ -162,22 +205,30 @@ const routes: Route[] = [ { path: 'server/:server_name', component: StatisticApplicationView, - title: 'Statistiques Serveur' + title: (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => { + return `Dashboard > ${route.paramMap.get('server_name')}`; + } }, { path: 'server/:server_name/rest/:rest_name', component: StatisticRestView, - title: 'Statistiques API' + title: (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => { + return `Dashboard > ${route.paramMap.get('server_name')} > ${route.paramMap.get('rest_name')}`; + } }, { path: 'user/:user_name', component: StatisticUserView, - title: 'Statistiques Utilisateur' + title: (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => { + return `Dashboard > ${route.paramMap.get('user_name')}`; + } }, { path: 'database/:database_name', component: StatisticDatabaseView, - title: 'Statistiques Base de Donnée' + title: (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => { + return `Dashboard > ${route.paramMap.get('database_name')}`; + } }, { path: '**', pathMatch: 'full', redirectTo: `/session/rest` } ] diff --git a/src/app/service/jquery/rest-session.service.ts b/src/app/service/jquery/rest-session.service.ts index 14a1954..77cbcb8 100644 --- a/src/app/service/jquery/rest-session.service.ts +++ b/src/app/service/jquery/rest-session.service.ts @@ -106,7 +106,7 @@ export class RestSessionService { 'start.lt': filters.end.toISOString(), 'user.notNull': '', 'order': 'count.desc', - 'fetch': 5, + 'limit': 5, ...filters.advancedParams } if (filters.apiName) { @@ -115,24 +115,21 @@ export class RestSessionService { return this.getRestSession(args); } - getRepartitionUserByPeriod(filters: {users: string, start: Date, end: Date, groupedBy: string, advancedParams: FilterMap, ids: string}): Observable<{count: number, date: number, year: number, user: string}[]>; - getRepartitionUserByPeriod(filters: {users: string, start: Date, end: Date, groupedBy: string, advancedParams: FilterMap, ids: string, apiName: string}): Observable<{count: number, date: number, year: number, user: string}[]>; - getRepartitionUserByPeriod(filters: {users: string, start: Date, end: Date, groupedBy: string, advancedParams: FilterMap, ids: string, apiName: string}): Observable<{count: number, date: number, year: number, user: string}[]> { + getRepartitionUserByPeriod(filters: {start: Date, end: Date, groupedBy: string, advancedParams: FilterMap, ids: string}): Observable<{count: number, date: number, year: number, user: string}[]>; + getRepartitionUserByPeriod(filters: {start: Date, end: Date, groupedBy: string, advancedParams: FilterMap, ids: string, apiName: string}): Observable<{count: number, date: number, year: number, user: string}[]>; + getRepartitionUserByPeriod(filters: {start: Date, end: Date, groupedBy: string, advancedParams: FilterMap, ids: string, apiName: string}): Observable<{count: number, date: number, year: number, user: string}[]> { let args: any = { 'column': `count:count,start.${filters.groupedBy}:date,start.year:year,user`, 'instance_env.in': filters.ids, 'start.ge': filters.start.toISOString(), 'start.lt': filters.end.toISOString(), 'user.notNull': '', - 'order': `year.asc,date.asc`, + 'order': `year.asc,date.asc,count.desc`, ...filters.advancedParams } if(filters.apiName) { args['api_name'] = `"${filters.apiName}"`; } - if(filters.users) { - args['user.in'] = filters.users; - } return this.getRestSession(args); } @@ -145,7 +142,7 @@ export class RestSessionService { 'start.lt': filters.end.toISOString(), 'api_name.notNull': '', 'order': 'count.desc', - 'fetch': 5, + 'limit': 5, ...filters.advancedParams } if(filters.ids) { @@ -161,10 +158,10 @@ export class RestSessionService { } getDependencies(filters: {start: Date, end: Date, advancedParams: FilterMap, ids: string}): Observable<{count: number, countSucces: number, countErrClient: number, countErrServer: number, name: string}[]>; - getDependencies(filters: {start: Date, end: Date, advancedParams: FilterMap, ids: string, apiName: string}): Observable<{count: number, countSucces: number, countErrClient: number, countErrServer: number, name: string}[]> ; - getDependencies(filters: {start: Date, end: Date, advancedParams: FilterMap, ids: string, apiName: string}): Observable<{count: number, countSucces: number, countErrClient: number, countErrServer: number, name: string}[]> { + getDependencies(filters: {start: Date, end: Date, advancedParams: FilterMap, ids: string, apiName: string}): Observable<{count: number, countSucces: number, countErrClient: number, countErrServer: number, name: string, appName: string}[]> ; + getDependencies(filters: {start: Date, end: Date, advancedParams: FilterMap, ids: string, apiName: string}): Observable<{count: number, countSucces: number, countErrClient: number, countErrServer: number, name: string, appName: string}[]> { let args: any = { - 'column': 'count:count,count_succes:countSucces,count_error_client:countErrClient,count_error_server:countErrServer,instance.app_name:name', + 'column': `count:count,count_succes:countSucces,count_error_client:countErrClient,count_error_server:countErrServer,${filters.apiName ? 'api_name:name,instance.app_name' : 'instance.app_name:name'}`, 'instance.id': 'instance_env', 'id': 'rest_request.parent', 'rest_request.remote': 'rest_session_join.id', @@ -218,7 +215,7 @@ export class RestSessionService { 'start.ge': filters.start.toISOString(), 'start.lt': filters.end.toISOString(), 'order': 'count.desc', - 'fetch': 5, + 'limit': 5, ...filters.advancedParams } if(filters.ids) { diff --git a/src/app/views/detail/session/main/detail-session-main.view.html b/src/app/views/detail/session/main/detail-session-main.view.html index 216a524..7852a39 100644 --- a/src/app/views/detail/session/main/detail-session-main.view.html +++ b/src/app/views/detail/session/main/detail-session-main.view.html @@ -5,7 +5,7 @@ settings_suggest - {{ '[' + session.type + '] ' + session.name || 'N/A' }} + {{ '[' + session.type + '] ' + (session.name || 'N/A') }}
- en {{ { start: session.start, end: session.end } | duration }} + en {{{ start: session.start, end: session.end } | duration }}
diff --git a/src/app/views/detail/session/main/detail-session-main.view.scss b/src/app/views/detail/session/main/detail-session-main.view.scss index 434f184..d3d1024 100644 --- a/src/app/views/detail/session/main/detail-session-main.view.scss +++ b/src/app/views/detail/session/main/detail-session-main.view.scss @@ -34,8 +34,6 @@ mat-card-footer { font-size: 14px; .right { margin-left: auto; - display: flex; - align-items: center; } } diff --git a/src/app/views/detail/session/rest/detail-session-rest.view.scss b/src/app/views/detail/session/rest/detail-session-rest.view.scss index 434f184..370046d 100644 --- a/src/app/views/detail/session/rest/detail-session-rest.view.scss +++ b/src/app/views/detail/session/rest/detail-session-rest.view.scss @@ -36,6 +36,7 @@ mat-card-footer { margin-left: auto; display: flex; align-items: center; + gap: 0.5em; } } diff --git a/src/app/views/statistic/_component/dependencies-table/statistic-dependencies-table.component.ts b/src/app/views/statistic/_component/dependencies-table/statistic-dependencies-table.component.ts index e40f427..72b2574 100644 --- a/src/app/views/statistic/_component/dependencies-table/statistic-dependencies-table.component.ts +++ b/src/app/views/statistic/_component/dependencies-table/statistic-dependencies-table.component.ts @@ -11,7 +11,7 @@ import { ChartProvider, field, values } from "@oneteme/jquery-core"; export class StatisticDependenciesTableComponent { displayedColumns: string[] = ['name', 'response']; - dataSource: MatTableDataSource<{ name: string, count: number, data: any[] }> = new MatTableDataSource([]); + dataSource: MatTableDataSource<{ name: string, appName: string, count: number, data: any[] }> = new MatTableDataSource([]); readonly CONFIG_SPARKLINE: ChartProvider = { height: 50, @@ -65,7 +65,7 @@ export class StatisticDependenciesTableComponent { @Input() set data(objects: any[]) { if (objects?.length) { this.dataSource = new MatTableDataSource(objects.map(r => { - return { name: r.name, count: r.count, data: [r] }; + return { name: r.name, appName: r.appName, count: r.count, data: [r] }; })); this.dataSource.paginator = this.paginator; } else { diff --git a/src/app/views/statistic/application/statistic-application.view.html b/src/app/views/statistic/application/statistic-application.view.html index c459b89..d3a8f0c 100644 --- a/src/app/views/statistic/application/statistic-application.view.html +++ b/src/app/views/statistic/application/statistic-application.view.html @@ -33,23 +33,23 @@
+ [data]="requests.repartitionTimeAndTypeResponseByPeriod?.data?.pie || []" + [isLoading]="requests.repartitionTimeAndTypeResponseByPeriod?.isLoading" />
+ [data]="requests.repartitionTimeAndTypeResponseByPeriod?.data?.bar || []" [isLoading]="requests.repartitionTimeAndTypeResponseByPeriod?.isLoading" /> + [data]="requests.repartitionTimeAndTypeResponseByPeriod?.data?.pie || []" [isLoading]="requests.repartitionTimeAndTypeResponseByPeriod?.isLoading" />
+ [data]="requests.repartitionUser?.data?.pie || []" [isLoading]="requests.repartitionUser?.isLoading" /> @@ -61,10 +61,10 @@
diff --git a/src/app/views/statistic/application/statistic-application.view.ts b/src/app/views/statistic/application/statistic-application.view.ts index 31e56b3..6df604d 100644 --- a/src/app/views/statistic/application/statistic-application.view.ts +++ b/src/app/views/statistic/application/statistic-application.view.ts @@ -10,6 +10,7 @@ import {FilterService} from "src/app/service/filter.service"; import {EnvRouter} from "../../../service/router.service"; import {InstanceService} from "../../../service/jquery/instance.service"; import {RestSessionService} from "../../../service/jquery/rest-session.service"; +import {countByFields, groupByField} from "../rest/statistic-rest.view"; @Component({ templateUrl: './statistic-application.view.html', @@ -137,24 +138,47 @@ export class StatisticApplicationView implements OnInit, OnDestroy { return this._instanceService.getIds(env, end, name).pipe(map(data => { let ids = data.map(d => `"${d.id}"`).join(','); return { - repartitionTimeAndTypeResponse: { observable: this._restSessionService.getRepartitionTimeAndTypeResponse({start: start, end: end, advancedParams: advancedParams, ids: ids}) }, repartitionTimeAndTypeResponseByPeriod: { observable: this._restSessionService.getRepartitionTimeAndTypeResponseByPeriod({start: start, end: end, groupedBy: groupedBy, advancedParams: advancedParams, ids: ids}).pipe(map(r => { formatters[groupedBy](r, this._datePipe); - return r; + let combiner = (args: any[], f: string)=> args.reduce((acc, o) => { + acc += o[f]; + return acc; + }, 0); + return { + pie: [countByFields(r, combiner, ['countSucces', 'countErrorClient', 'countErrorServer', 'elapsedTimeSlowest', 'elapsedTimeSlow', 'elapsedTimeMedium', 'elapsedTimeFast', 'elapsedTimeFastest'])], + bar: r + } })) }, repartitionRequestByPeriodLine: { observable: this._restSessionService.getRepartitionRequestByPeriod({now: now, advancedParams: advancedParams, ids: ids}) }, repartitionUser: { observable: - this._restSessionService.getRepartitionUser({start: start, end: end, advancedParams: advancedParams, ids: ids}) - .pipe(switchMap(res => { - return forkJoin({ - polar: of(res), - bar: this._restSessionService.getRepartitionUserByPeriod({users: res.map(d => `"${d.user}"`).join(','), start: start, end: end, groupedBy: groupedBy, advancedParams: advancedParams, ids: ids}).pipe(map(r => { - formatters[groupedBy](r, this._datePipe); - return r; - })) - }) + this._restSessionService.getRepartitionUserByPeriod({start: start, end: end, groupedBy: groupedBy, advancedParams: advancedParams, ids: ids}) + .pipe(map(r => { + formatters[groupedBy](r, this._datePipe); + let bar = Object.values(groupByField(r, "date")).flatMap(g=> { + let other = g.slice(6).reduce((acc, o)=> { + if(acc) { + acc = {count: o['count'], date: o['date'], year: o['year'], user: 'Autres'}; + } else { + acc['count'] += o['count']; + } + return acc; + }, {}); + return g.slice(6).length ? [g.slice(0,5), other].flat(): g.slice(0,5); + }); + let groupByUser = groupByField(r, "user"); + let pie = Object.keys(groupByUser).map(k => { + let count = groupByUser[k].reduce((acc, o) => { + acc += o['count']; + return acc; + }, 0); + return {user: k, count: count}; + }).sort((a, b) => b.count - a.count).slice(0, 5); + return { + bar: bar, + pie: pie + }; })) }, repartitionApiBar: { observable: this._restSessionService.getRepartitionApi({start: start, end: end, advancedParams: advancedParams, ids: ids}) }, diff --git a/src/app/views/statistic/rest/statistic-rest.view.html b/src/app/views/statistic/rest/statistic-rest.view.html index 6ce426e..194f0c5 100644 --- a/src/app/views/statistic/rest/statistic-rest.view.html +++ b/src/app/views/statistic/rest/statistic-rest.view.html @@ -37,35 +37,35 @@
+ [data]="requests.repartitionUser?.data?.pie || []" [isLoading]="requests.repartitionUser?.isLoading" />
diff --git a/src/app/views/statistic/rest/statistic-rest.view.ts b/src/app/views/statistic/rest/statistic-rest.view.ts index 219d00b..8b8ffa2 100644 --- a/src/app/views/statistic/rest/statistic-rest.view.ts +++ b/src/app/views/statistic/rest/statistic-rest.view.ts @@ -1,23 +1,23 @@ -import { Component, OnDestroy, OnInit, inject } from "@angular/core"; -import { JQueryService } from "src/app/service/jquery/jquery.service"; -import { DatePipe, Location } from '@angular/common'; -import { ActivatedRoute, Params } from "@angular/router"; -import { FormControl, FormGroup, Validators } from "@angular/forms"; +import {Component, inject, OnDestroy, OnInit} from "@angular/core"; +import {DatePipe, Location} from '@angular/common'; +import {ActivatedRoute, Params} from "@angular/router"; +import {FormControl, FormGroup, Validators} from "@angular/forms"; import { BehaviorSubject, - Observable, - Subscription, combineLatest, - filter, finalize, + forkJoin, map, + Observable, + of, + Subscription, switchMap, - forkJoin, of + tap } from "rxjs"; -import { Constants, FilterConstants, FilterMap, FilterPreset } from "../../constants"; -import { Utils, formatters, groupingBy, periodManagement, mapParams, } from "src/app/shared/util"; -import { application, makePeriod } from "src/environments/environment"; -import { FilterService } from "src/app/service/filter.service"; +import {Constants, FilterConstants, FilterMap, FilterPreset} from "../../constants"; +import {formatters, mapParams, periodManagement,} from "src/app/shared/util"; +import {application, makePeriod} from "src/environments/environment"; +import {FilterService} from "src/app/service/filter.service"; import {EnvRouter} from "../../../service/router.service"; import {InstanceService} from "../../../service/jquery/instance.service"; import {RestSessionService} from "../../../service/jquery/rest-session.service"; @@ -135,9 +135,9 @@ export class StatisticRestView implements OnInit, OnDestroy { onClickRow(event: MouseEvent, row: any) { if (event.ctrlKey) { - this._router.open(`#/dashboard/server/${this.params.serverName}/rest/${row.name}?env=${this.params.env}&start=${this.params.start.toISOString()}&end=${this.params.end.toISOString()}`, '_blank') + this._router.open(`#/dashboard/server/${row.appName}/rest/${row.name}?env=${this.params.env}&start=${this.params.start.toISOString()}&end=${this.params.end.toISOString()}`, '_blank') } else { - this._router.navigate(['/dashboard/server',this.params.serverName, 'rest', row.name], { + this._router.navigate(['/dashboard/server', row.appName, 'rest', row.name], { queryParamsHandling: 'preserve' }); } @@ -149,26 +149,46 @@ export class StatisticRestView implements OnInit, OnDestroy { return this._instanceService.getIds(env, end, serverName).pipe(map((data: {id: string}[]) => { let ids = data.map(d => `"${d.id}"`).join(','); return { - repartitionTimeAndTypeResponse: { observable: this._restSessionService.getRepartitionTimeAndTypeResponse({start: start, end: end, advancedParams: advancedParams, ids: ids, apiName: restName}) }, repartitionTimeAndTypeResponseByPeriod: { observable: this._restSessionService.getRepartitionTimeAndTypeResponseByPeriod({start: start, end: end, groupedBy: groupedBy, advancedParams: advancedParams, ids: ids, apiName: restName}).pipe(map(r => { formatters[groupedBy](r, this._datePipe); - return r; + let combiner = (args: any[], f: string)=> args.reduce((acc, o) => { + acc += o[f]; + return acc; + }, 0); + return { + pie: [countByFields(r, combiner, ['countSucces', 'countErrorClient', 'countErrorServer', 'elapsedTimeSlowest', 'elapsedTimeSlow', 'elapsedTimeMedium', 'elapsedTimeFast', 'elapsedTimeFastest'])], + bar: r + } })) }, repartitionRequestByPeriodLine: { observable: this._restSessionService.getRepartitionRequestByPeriod({now: now, advancedParams: advancedParams, ids: ids, apiName: restName}) }, // 7 derniers jours - repartitionUser: { observable: - this._restSessionService.getRepartitionUser({start: start, end: end, advancedParams: advancedParams, ids: ids, apiName: restName}) - .pipe(switchMap(res => { - return forkJoin({ - polar: of(res), - bar: this._restSessionService.getRepartitionUserByPeriod({users: res.map(d => `"${d.user}"`).join(','), start: start, end: end, groupedBy: groupedBy, advancedParams: advancedParams, ids: ids, apiName: restName}).pipe(map(r => { - formatters[groupedBy](r, this._datePipe); - return r; - })) - }) - })) - }, + repartitionUser: { observable: this._restSessionService.getRepartitionUserByPeriod({start: start, end: end, groupedBy: groupedBy, advancedParams: advancedParams, ids: ids, apiName: restName}).pipe(map(r => { + formatters[groupedBy](r, this._datePipe); + let bar = Object.values(groupByField(r, "date")).flatMap(g=> { + let other = g.slice(6).reduce((acc, o)=> { + if(acc) { + acc = {count: o['count'], date: o['date'], year: o['year'], user: 'Autres'}; + } else { + acc['count'] += o['count']; + } + return acc; + }, {}); + return g.slice(6).length ? [g.slice(0,5), other].flat(): g.slice(0,5); + }); + let groupByUser = groupByField(r, "user"); + let pie = Object.keys(groupByUser).map(k => { + let count = groupByUser[k].reduce((acc, o) => { + acc += o['count']; + return acc; + }, 0); + return {user: k, count: count}; + }).sort((a, b) => b.count - a.count).slice(0, 5); + return { + bar: bar, + pie: pie + }; + }))}, dependenciesTable: { observable: this._restSessionService.getDependencies({start: start, end: end, advancedParams: advancedParams, ids: ids, apiName: restName}) }, dependentsTable: { observable: this._restSessionService.getDependents({start: start, end: end, advancedParams: advancedParams, ids: ids, apiName: restName}) }, exceptionsTable: { observable: this._restSessionService.getExceptions({start: start, end: end, advancedParams: advancedParams, ids: ids, apiName: restName}) } @@ -230,4 +250,20 @@ export class StatisticRestView implements OnInit, OnDestroy { this._filter.setFilterMap(this.advancedParams); } } +} +export declare type DataProvider = (o: any, idx: number) => T; + +export function groupByField(arr: any[], field: string): {[key: string]: any[]}{ + return arr.reduce((acc: {[key: string]: any[]}, o)=> { + let key: string = o[field]; + (acc[key] = acc[key] || []).push(o); + return acc; + }, {}); +} + +export function countByFields(arr: any[], combiner: (args: any[], o: string)=> T, fields: string[]): {[key: string]: T}{ + return fields.reduce((acc: {[key: string]: T}, o)=> { + acc[o] = combiner(arr, o); + return acc; + }, {}); } \ No newline at end of file diff --git a/src/environments/environment.ts b/src/environments/environment.ts index a571b51..f4cd7e5 100644 --- a/src/environments/environment.ts +++ b/src/environments/environment.ts @@ -10,7 +10,7 @@ export const environment = { }; export const application: Application = { - default_env: 'dev', + default_env: 'rec', session: { api: { default_period: makePeriod(0, 1) From ff87ccb29b00cb63c23e5fbaefa94e1b798d624d Mon Sep 17 00:00:00 2001 From: fufuu Date: Mon, 23 Sep 2024 14:18:15 +0200 Subject: [PATCH 064/126] mat icon --- src/app/views/detail/session/main/detail-session-main.view.html | 2 +- src/app/views/detail/session/rest/detail-session-rest.view.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/views/detail/session/main/detail-session-main.view.html b/src/app/views/detail/session/main/detail-session-main.view.html index 7852a39..866e1a4 100644 --- a/src/app/views/detail/session/main/detail-session-main.view.html +++ b/src/app/views/detail/session/main/detail-session-main.view.html @@ -23,7 +23,7 @@
- warning + warning
{{ session.exception?.message || session.exception?.type }}
diff --git a/src/app/views/detail/session/rest/detail-session-rest.view.html b/src/app/views/detail/session/rest/detail-session-rest.view.html index 08086f5..a9a0d4c 100644 --- a/src/app/views/detail/session/rest/detail-session-rest.view.html +++ b/src/app/views/detail/session/rest/detail-session-rest.view.html @@ -31,7 +31,7 @@
- warning + warning
{{ session.exception?.message || session.exception?.type }}
From 4448222dda6a26cbb93909ef15da061fe9cb9026 Mon Sep 17 00:00:00 2001 From: fufuu Date: Tue, 24 Sep 2024 16:25:15 +0200 Subject: [PATCH 065/126] evols --- src/app/service/jquery/main-session.service.ts | 18 ++++++++++++++++++ src/app/service/jquery/rest-session.service.ts | 2 +- .../header-page/header-page.component.html | 4 +--- .../header-page/header-page.component.scss | 1 - src/app/shared/material/material.module.ts | 5 +++++ .../statistic-application.view.html | 2 +- .../application/statistic-application.view.ts | 10 +++++++++- 7 files changed, 35 insertions(+), 7 deletions(-) diff --git a/src/app/service/jquery/main-session.service.ts b/src/app/service/jquery/main-session.service.ts index e0a3440..d78dc71 100644 --- a/src/app/service/jquery/main-session.service.ts +++ b/src/app/service/jquery/main-session.service.ts @@ -28,4 +28,22 @@ export class MainSessionService { } return this.getMainSession(args) } + + getDependencies(filters: {start: Date, end: Date, advancedParams: FilterMap, ids: string}): Observable<{count: number, countSucces: number, countErrClient: number, countErrServer: number, name: string, appName: string}[]> { + let args: any = { + 'column': `rest_request.count:count,rest_request.count_succes:countSucces,rest_request.count_error_client:countErrClient,rest_request.count_error_server:countErrServer,instance.app_name:name`, + 'instance.id': 'instance_env', + 'id': 'rest_request.parent', + 'rest_request.remote': 'rest_session_join.id', + 'rest_session_join.start.ge': filters.start.toISOString(), + 'rest_session_join.start.lt': filters.end.toISOString(), + 'rest_session_join.instance_env.in': filters.ids, + 'start.ge': filters.start.toISOString(), + 'start.lt': filters.end.toISOString(), + 'view': 'rest_session:rest_session_join', + 'order': 'count.desc', + ...filters.advancedParams + } + return this.getMainSession(args); + } } \ No newline at end of file diff --git a/src/app/service/jquery/rest-session.service.ts b/src/app/service/jquery/rest-session.service.ts index 77cbcb8..31cafe2 100644 --- a/src/app/service/jquery/rest-session.service.ts +++ b/src/app/service/jquery/rest-session.service.ts @@ -161,7 +161,7 @@ export class RestSessionService { getDependencies(filters: {start: Date, end: Date, advancedParams: FilterMap, ids: string, apiName: string}): Observable<{count: number, countSucces: number, countErrClient: number, countErrServer: number, name: string, appName: string}[]> ; getDependencies(filters: {start: Date, end: Date, advancedParams: FilterMap, ids: string, apiName: string}): Observable<{count: number, countSucces: number, countErrClient: number, countErrServer: number, name: string, appName: string}[]> { let args: any = { - 'column': `count:count,count_succes:countSucces,count_error_client:countErrClient,count_error_server:countErrServer,${filters.apiName ? 'api_name:name,instance.app_name' : 'instance.app_name:name'}`, + 'column': `rest_request.count:count,rest_request.count_succes:countSucces,rest_request.count_error_client:countErrClient,rest_request.count_error_server:countErrServer,${filters.apiName ? 'api_name:name,instance.app_name' : 'instance.app_name:name'}`, 'instance.id': 'instance_env', 'id': 'rest_request.parent', 'rest_request.remote': 'rest_session_join.id', diff --git a/src/app/shared/_component/header-page/header-page.component.html b/src/app/shared/_component/header-page/header-page.component.html index eda4769..bc6e96a 100644 --- a/src/app/shared/_component/header-page/header-page.component.html +++ b/src/app/shared/_component/header-page/header-page.component.html @@ -1,7 +1,5 @@
-
- -
+
{{title}}
diff --git a/src/app/shared/_component/header-page/header-page.component.scss b/src/app/shared/_component/header-page/header-page.component.scss index 5326be2..4090bfe 100644 --- a/src/app/shared/_component/header-page/header-page.component.scss +++ b/src/app/shared/_component/header-page/header-page.component.scss @@ -9,7 +9,6 @@ display: flex; align-items: center; justify-content: center; - gap: 1rem; .title-icon { display: flex; diff --git a/src/app/shared/material/material.module.ts b/src/app/shared/material/material.module.ts index c04070f..64d37c5 100644 --- a/src/app/shared/material/material.module.ts +++ b/src/app/shared/material/material.module.ts @@ -48,7 +48,11 @@ import {CdkMenuModule} from '@angular/cdk/menu'; import {DialogModule} from '@angular/cdk/dialog'; import {BrowserAnimationsModule} from '@angular/platform-browser/animations'; +import {LabelIconComponent} from "./_component/label-icon/label-icon.component"; +import {CommonModule} from "@angular/common"; @NgModule({ + imports: [CommonModule, MatIconModule], + declarations: [LabelIconComponent], exports: [ BrowserAnimationsModule, A11yModule, @@ -99,6 +103,7 @@ import {BrowserAnimationsModule} from PortalModule, ScrollingModule, DialogModule, + LabelIconComponent ] }) export class MaterialModule {} diff --git a/src/app/views/statistic/application/statistic-application.view.html b/src/app/views/statistic/application/statistic-application.view.html index d3a8f0c..cb21700 100644 --- a/src/app/views/statistic/application/statistic-application.view.html +++ b/src/app/views/statistic/application/statistic-application.view.html @@ -64,7 +64,7 @@ [data]="requests.repartitionTimeAndTypeResponseByPeriod?.data?.bar || []" [isLoading]="requests.repartitionTimeAndTypeResponseByPeriod?.isLoading" />
diff --git a/src/app/views/statistic/application/statistic-application.view.ts b/src/app/views/statistic/application/statistic-application.view.ts index 6df604d..c3dce94 100644 --- a/src/app/views/statistic/application/statistic-application.view.ts +++ b/src/app/views/statistic/application/statistic-application.view.ts @@ -11,6 +11,7 @@ import {EnvRouter} from "../../../service/router.service"; import {InstanceService} from "../../../service/jquery/instance.service"; import {RestSessionService} from "../../../service/jquery/rest-session.service"; import {countByFields, groupByField} from "../rest/statistic-rest.view"; +import {MainSessionService} from "../../../service/jquery/main-session.service"; @Component({ templateUrl: './statistic-application.view.html', @@ -19,6 +20,7 @@ import {countByFields, groupByField} from "../rest/statistic-rest.view"; export class StatisticApplicationView implements OnInit, OnDestroy { private _activatedRoute = inject(ActivatedRoute); private _restSessionService = inject(RestSessionService); + private _mainSessionService = inject(MainSessionService); private _instanceService = inject(InstanceService); private _router = inject(EnvRouter); private _location = inject(Location); @@ -182,7 +184,13 @@ export class StatisticApplicationView implements OnInit, OnDestroy { })) }, repartitionApiBar: { observable: this._restSessionService.getRepartitionApi({start: start, end: end, advancedParams: advancedParams, ids: ids}) }, - dependenciesTable: { observable: this._restSessionService.getDependencies({start: start, end: end, advancedParams: advancedParams, ids: ids}) }, + dependenciesTable: { observable: forkJoin({ + restSession : this._restSessionService.getDependencies({start: start, end: end, advancedParams: advancedParams, ids: ids}), + mainSession : this._mainSessionService.getDependencies({start: start, end: end, advancedParams: advancedParams, ids: ids}) + }).pipe(map(res => { + console.log("test", [res.restSession, res.mainSession.map(res => ({count: res.count, countSucces: 0, countErrClient: 0, countErrServer: 0, name: res.name}))].flat()) + return [res.restSession, res.mainSession].flat().sort((a, b) => b.count - a.count); + })) }, dependentsTable: { observable: this._restSessionService.getDependents({start: start, end: end, advancedParams: advancedParams, ids: ids}) }, exceptionsTable: { observable: this._restSessionService.getExceptions({start: start, end: end, advancedParams: advancedParams, ids: ids})} } From abb088a54ca8ae97702cc490a732a93094c98c48 Mon Sep 17 00:00:00 2001 From: YoussefDahi Date: Tue, 24 Sep 2024 16:53:39 +0200 Subject: [PATCH 066/126] dashboard Home Component --- src/app/service/jquery/ftp-request.service.ts | 47 ++++++++++++++ .../service/jquery/ldap-request.service.ts | 47 ++++++++++++++ .../service/jquery/rest-request.service.ts | 47 ++++++++++++++ .../service/jquery/smtp-request.service.ts | 47 ++++++++++++++ .../protocol-exception-modal.component.html | 62 +++++++++++++++++++ .../protocol-exception-modal.component.scss | 21 +++++++ .../protocol-exception-modal.component.ts | 42 +++++++++++++ 7 files changed, 313 insertions(+) create mode 100644 src/app/service/jquery/ftp-request.service.ts create mode 100644 src/app/service/jquery/ldap-request.service.ts create mode 100644 src/app/service/jquery/rest-request.service.ts create mode 100644 src/app/service/jquery/smtp-request.service.ts create mode 100644 src/app/views/dashboard/components/protocol-exception-modal/protocol-exception-modal.component.html create mode 100644 src/app/views/dashboard/components/protocol-exception-modal/protocol-exception-modal.component.scss create mode 100644 src/app/views/dashboard/components/protocol-exception-modal/protocol-exception-modal.component.ts diff --git a/src/app/service/jquery/ftp-request.service.ts b/src/app/service/jquery/ftp-request.service.ts new file mode 100644 index 0000000..30bf191 --- /dev/null +++ b/src/app/service/jquery/ftp-request.service.ts @@ -0,0 +1,47 @@ +import { Injectable } from "@angular/core"; +import { HttpClient } from "@angular/common/http"; +import { Observable } from "rxjs"; +import { FtpMainExceptionsByPeriodAndappname, FtpSessionExceptionsByPeriodAndappname } from "src/app/model/jquery.model"; + + +@Injectable({ providedIn: 'root' }) +export class FtpRequestService { + constructor(private http: HttpClient) { + + } + + getftp(params: any): Observable { + let url = `${localStorage.getItem('server')}/jquery/request/ftp`; + return this.http.get(url, { params: params }); + } + + + getftpSessionExceptions(filters: { env: string, start: Date, end: Date, groupedBy: string, app_name: string }): Observable { + let args = { + 'column': `count:countok,exception.count_exception:count,exception.err_type.coalesce():err_type,start.${filters.groupedBy}:date,start.year:year`, + 'instance.environement': filters.env, + 'join': 'exception,ftp_request.rest_session,rest_session.instance', + 'start.ge': filters.start.toISOString(), + 'start.lt': filters.end.toISOString(), + [filters.app_name]: '', + 'order': 'date.asc' + } + return this.getftp(args); + } + + getftpMainExceptions(filters: { env: string, start: Date, end: Date, groupedBy: string, app_name: string }): Observable { + let args = { + 'column': `count:countok,exception.count_exception:count,exception.err_type.coalesce():err_type,start.${filters.groupedBy}:date,start.year:year`, + 'instance.environement': filters.env, + 'join': 'exception,ftp_request.main_session,main_session.instance', + 'start.ge': filters.start.toISOString(), + 'start.lt': filters.end.toISOString(), + [filters.app_name]: '', + 'order': 'date.asc' + } + return this.getftp(args); + } + + + +} \ No newline at end of file diff --git a/src/app/service/jquery/ldap-request.service.ts b/src/app/service/jquery/ldap-request.service.ts new file mode 100644 index 0000000..3d5a4e7 --- /dev/null +++ b/src/app/service/jquery/ldap-request.service.ts @@ -0,0 +1,47 @@ +import { Injectable } from "@angular/core"; +import { HttpClient } from "@angular/common/http"; +import { Observable } from "rxjs"; +import { LdapMainExceptionsByPeriodAndappname, LdapSessionExceptionsByPeriodAndappname } from "src/app/model/jquery.model"; + + +@Injectable({ providedIn: 'root' }) +export class LdapRequestService { + constructor(private http: HttpClient) { + + } + + getLdap(params: any): Observable { + let url = `${localStorage.getItem('server')}/jquery/request/ldap`; + return this.http.get(url, { params: params }); + } + + + getLdapSessionExceptions(filters: { env: string, start: Date, end: Date, groupedBy: string, app_name: string }): Observable { + let args = { + 'column': `count:countok,exception.count_exception:count,exception.err_type.coalesce():err_type,start.${filters.groupedBy}:date,start.year:year`, + 'instance.environement': filters.env, + 'join': 'exception,ldap_request.rest_session,rest_session.instance', + 'start.ge': filters.start.toISOString(), + 'start.lt': filters.end.toISOString(), + [filters.app_name]: '', + 'order': 'date.asc' + } + return this.getLdap(args); + } + + getLdapMainExceptions(filters: { env: string, start: Date, end: Date, groupedBy: string, app_name: string }): Observable { + let args = { + 'column': `count:countok,exception.count_exception:count,exception.err_type.coalesce():err_type,start.${filters.groupedBy}:date,start.year:year`, + 'instance.environement': filters.env, + 'join': 'exception,ldap_request.main_session,main_session.instance', + 'start.ge': filters.start.toISOString(), + 'start.lt': filters.end.toISOString(), + [filters.app_name]: '', + 'order': 'date.asc' + } + return this.getLdap(args); + } + + + +} \ No newline at end of file diff --git a/src/app/service/jquery/rest-request.service.ts b/src/app/service/jquery/rest-request.service.ts new file mode 100644 index 0000000..fb91ea1 --- /dev/null +++ b/src/app/service/jquery/rest-request.service.ts @@ -0,0 +1,47 @@ +import { Injectable } from "@angular/core"; +import { HttpClient } from "@angular/common/http"; +import { Observable } from "rxjs"; +import { RestMainExceptionsByPeriodAndappname, RestSessionExceptionsByPeriodAndappname } from "src/app/model/jquery.model"; + + +@Injectable({ providedIn: 'root' }) +export class restRequestService { + constructor(private http: HttpClient) { + + } + + getrest(params: any): Observable { + let url = `${localStorage.getItem('server')}/jquery/request/rest`; + return this.http.get(url, { params: params }); + } + + + getrestSessionExceptions(filters: { env: string, start: Date, end: Date, groupedBy: string, app_name: string }): Observable { + let args = { + 'column': `count:countok,exception.count_exception:count,exception.err_type.coalesce():err_type,start.${filters.groupedBy}:date,start.year:year`, + 'instance.environement': filters.env, + 'join': 'exception,rest_request.rest_session,rest_session.instance', + 'start.ge': filters.start.toISOString(), + 'start.lt': filters.end.toISOString(), + [filters.app_name]: '', + 'order': 'date.asc' + } + return this.getrest(args); + } + + getrestMainExceptions(filters: { env: string, start: Date, end: Date, groupedBy: string, app_name: string }): Observable{ + let args = { + 'column': `count:countok,exception.count_exception:count,exception.err_type.coalesce():err_type,start.${filters.groupedBy}:date,start.year:year`, + 'instance.environement': filters.env, + 'join': 'exception,rest_request.main_session,main_session.instance', + 'start.ge': filters.start.toISOString(), + 'start.lt': filters.end.toISOString(), + [filters.app_name]: '', + 'order': 'date.asc' + } + return this.getrest(args); + } + + + +} \ No newline at end of file diff --git a/src/app/service/jquery/smtp-request.service.ts b/src/app/service/jquery/smtp-request.service.ts new file mode 100644 index 0000000..0f111cb --- /dev/null +++ b/src/app/service/jquery/smtp-request.service.ts @@ -0,0 +1,47 @@ +import { Injectable } from "@angular/core"; +import { HttpClient } from "@angular/common/http"; +import { Observable } from "rxjs"; +import { SmtpMainExceptionsByPeriodAndappname, SmtpSessionExceptionsByPeriodAndappname } from "src/app/model/jquery.model"; + + +@Injectable({ providedIn: 'root' }) +export class smtpRequestService { + constructor(private http: HttpClient) { + + } + + getsmtp(params: any): Observable { + let url = `${localStorage.getItem('server')}/jquery/request/smtp`; + return this.http.get(url, { params: params }); + } + + + getsmtpSessionExceptions(filters: { env: string, start: Date, end: Date, groupedBy: string, app_name: string }): Observable { + let args = { + 'column': `count:countok,exception.count_exception:count,exception.err_type.coalesce():err_type,start.${filters.groupedBy}:date,start.year:year`, + 'instance.environement': filters.env, + 'join': 'exception,smtp_request.rest_session,rest_session.instance', + 'start.ge': filters.start.toISOString(), + 'start.lt': filters.end.toISOString(), + [filters.app_name]: '', + 'order': 'date.asc' + } + return this.getsmtp(args); + } + + getsmtpMainExceptions(filters: { env: string, start: Date, end: Date, groupedBy: string, app_name: string }): Observable { + let args = { + 'column': `count:countok,exception.count_exception:count,exception.err_type.coalesce():err_type,start.${filters.groupedBy}:date,start.year:year`, + 'instance.environement': filters.env, + 'join': 'exception,smtp_request.main_session,main_session.instance', + 'start.ge': filters.start.toISOString(), + 'start.lt': filters.end.toISOString(), + [filters.app_name]: '', + 'order': 'date.asc' + } + return this.getsmtp(args); + } + + + +} \ No newline at end of file diff --git a/src/app/views/dashboard/components/protocol-exception-modal/protocol-exception-modal.component.html b/src/app/views/dashboard/components/protocol-exception-modal/protocol-exception-modal.component.html new file mode 100644 index 0000000..6bdf20e --- /dev/null +++ b/src/app/views/dashboard/components/protocol-exception-modal/protocol-exception-modal.component.html @@ -0,0 +1,62 @@ +

{{exceptions.type}} Exceptions

+ + +
+ + + + + + + + + + + + + + + + + + + + + +
Instant + {{ row.date }} + Titre +
+ {{ removePackage(row.err_type) }} +
+
Taux +
+ {{ row.count }} +
+
+
+ + info + + Aucun résultat +
+
+ + Chargement en cours... + + +
+ +
+ +
+
+ + + \ No newline at end of file diff --git a/src/app/views/dashboard/components/protocol-exception-modal/protocol-exception-modal.component.scss b/src/app/views/dashboard/components/protocol-exception-modal/protocol-exception-modal.component.scss new file mode 100644 index 0000000..7dff680 --- /dev/null +++ b/src/app/views/dashboard/components/protocol-exception-modal/protocol-exception-modal.component.scss @@ -0,0 +1,21 @@ + + + +.title{ + width: max-content; + margin-right: 10px; +} + +.dialog-header{ + display: flex; + align-items: center; + justify-content: space-between; +} + +.dialog-actions{ + margin-left: auto; +} + +.hidden { + display: none; +} \ No newline at end of file diff --git a/src/app/views/dashboard/components/protocol-exception-modal/protocol-exception-modal.component.ts b/src/app/views/dashboard/components/protocol-exception-modal/protocol-exception-modal.component.ts new file mode 100644 index 0000000..1bf43d2 --- /dev/null +++ b/src/app/views/dashboard/components/protocol-exception-modal/protocol-exception-modal.component.ts @@ -0,0 +1,42 @@ + +import { AfterContentInit, AfterViewInit, Component, Inject, OnInit, ViewChild} from "@angular/core"; +import { MAT_DIALOG_DATA, MatDialogRef } from "@angular/material/dialog"; +import { MatPaginator } from "@angular/material/paginator"; +import { MatSort } from "@angular/material/sort"; + + + +@Component({ + templateUrl: './protocol-exception-modal.component.html', + styleUrls: ['./protocol-exception-modal.component.scss'], + + +}) +export class ProtocolExceptionComponent implements OnInit, AfterViewInit { + + @ViewChild("paginator") paginator: MatPaginator; + @ViewChild("sort") sort: MatSort; + table :any; + protocolExceptionsDisplyedColumns: string[] = ["date","errType","count"]; + constructor(public dialogRef: MatDialogRef, + @Inject(MAT_DIALOG_DATA) public exceptions: any) { } + + ngAfterViewInit(): void { + + setTimeout(() => { // TODO: fix sort pagination + // this.exceptions.observable.data.paginator = this.paginator; + // this.exceptions.observable.data.sort = this.sort; + }, 0); + } + + ngOnInit(): void { + } + + removePackage(errorType: string ){ + if(errorType){ + const index = errorType.lastIndexOf('.') + 1; + return errorType?.substring(index) ; + } + return 'N/A'; + } +} \ No newline at end of file From a4081e86c2e4f96451be592380af9a0384c8711c Mon Sep 17 00:00:00 2001 From: fufuu Date: Tue, 24 Sep 2024 17:24:53 +0200 Subject: [PATCH 067/126] merge --- .../label-icon/label-icon.component.ts | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 src/app/shared/material/_component/label-icon/label-icon.component.ts diff --git a/src/app/shared/material/_component/label-icon/label-icon.component.ts b/src/app/shared/material/_component/label-icon/label-icon.component.ts new file mode 100644 index 0000000..1d35b6b --- /dev/null +++ b/src/app/shared/material/_component/label-icon/label-icon.component.ts @@ -0,0 +1,21 @@ +import {Component, Input} from "@angular/core"; + +@Component({ + selector: 'label-icon', + template: ` +
+ {{ icon }} + +
+ `, +}) +export class LabelIconComponent { + @Input() public icon: string; + @Input() public iconOutlined = true; + @Input() public size: number; + @Input() public color: string; +} \ No newline at end of file From c40b45fbe1a8b47c69692396f3f034cb49b4bcc8 Mon Sep 17 00:00:00 2001 From: fufuu Date: Tue, 24 Sep 2024 17:25:20 +0200 Subject: [PATCH 068/126] merge --- src/app/service/jquery/instance.service.ts | 5 ++--- src/app/service/jquery/rest-request.service.ts | 2 +- src/app/views/dashboard/dashboard.component.ts | 4 ++-- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/app/service/jquery/instance.service.ts b/src/app/service/jquery/instance.service.ts index bbd27a4..fd51c09 100644 --- a/src/app/service/jquery/instance.service.ts +++ b/src/app/service/jquery/instance.service.ts @@ -42,10 +42,9 @@ export class InstanceService { } getServerStart(filters : {env: string, start:Date, end: Date,groupedBy:string, app_name: string }): Observable { - let args = { + return this.getInstance({ 'column': `view1.appName,view1.version,view1.start`, 'view': `select(app_name,version,start,rank.over(partition(environement,app_name).order(start.desc)):rk).filter(type.eq(SERVER).and(environement.eq(${filters.env})).and(start.ge(${filters.start.toISOString()})).and(start.lt(${filters.end.toISOString()}))${filters.app_name}):view1`, - 'view1.rk': '1', 'order': 'view1.start.desc' } - return this.getInstance(args); + 'view1.rk': '1', 'order': 'view1.start.desc' }); } } \ No newline at end of file diff --git a/src/app/service/jquery/rest-request.service.ts b/src/app/service/jquery/rest-request.service.ts index fb91ea1..ed56bca 100644 --- a/src/app/service/jquery/rest-request.service.ts +++ b/src/app/service/jquery/rest-request.service.ts @@ -5,7 +5,7 @@ import { RestMainExceptionsByPeriodAndappname, RestSessionExceptionsByPeriodAnda @Injectable({ providedIn: 'root' }) -export class restRequestService { +export class RestRequestService { constructor(private http: HttpClient) { } diff --git a/src/app/views/dashboard/dashboard.component.ts b/src/app/views/dashboard/dashboard.component.ts index a9db70d..adaf5e8 100644 --- a/src/app/views/dashboard/dashboard.component.ts +++ b/src/app/views/dashboard/dashboard.component.ts @@ -15,7 +15,7 @@ import { MatSort } from '@angular/material/sort'; import { InstanceService } from 'src/app/service/jquery/instance.service'; import { RestSessionService } from 'src/app/service/jquery/rest-session.service'; import { MainSessionService } from 'src/app/service/jquery/main-session.service'; -import { restRequestService } from 'src/app/service/jquery/rest-request.service'; +import { RestRequestService } from 'src/app/service/jquery/rest-request.service'; import { DatabaseRequestService } from 'src/app/service/jquery/database-request.service'; import { FtpRequestService} from 'src/app/service/jquery/ftp-request.service'; import { LdapRequestService } from 'src/app/service/jquery/ldap-request.service'; @@ -33,7 +33,7 @@ export class DashboardComponent { private _instanceService = inject(InstanceService); private _sessionService = inject(RestSessionService); private _mainService = inject(MainSessionService); - private _restService = inject(restRequestService); + private _restService = inject(RestRequestService); private _datebaseService = inject(DatabaseRequestService); private _ftpService = inject(FtpRequestService); private _smtpService = inject(smtpRequestService) From b68365a2f089691e4a47a89ec8bd2698739f0b62 Mon Sep 17 00:00:00 2001 From: YoussefDahi Date: Wed, 25 Sep 2024 10:34:42 +0200 Subject: [PATCH 069/126] home page link --- src/app/app.component.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/app.component.html b/src/app/app.component.html index 0d80a88..621dcab 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -1,6 +1,6 @@