From edcaf951c2d85b037c7a00583fc3fc2634fdae89 Mon Sep 17 00:00:00 2001 From: Peter Maquiran Date: Tue, 30 Jul 2024 15:52:07 +0100 Subject: [PATCH] improve monitoring the solution --- package-lock.json | 35 +++++++++++++ package.json | 1 + src/app/app.module.ts | 4 +- src/app/modals/profile/profile.page.ts | 50 ++++++++++++++++--- .../gabinete-digital.page.html | 2 +- .../gabinete-digital/gabinete-digital.page.ts | 8 +-- .../api-validate-schema.decorator.ts | 10 ++++ .../monitoring/opentelemetry/tracer.ts | 22 ++++++-- src/app/services/notifications.service.ts | 8 ++- src/main.ts | 42 ++++++++++++++++ version/git-version.ts | 12 ++--- 11 files changed, 167 insertions(+), 27 deletions(-) diff --git a/package-lock.json b/package-lock.json index 112402d9f..470730c03 100644 --- a/package-lock.json +++ b/package-lock.json @@ -175,6 +175,7 @@ "ng-lazyload-image": "^9.1.2", "ng2-pdf-viewer": "^3.0.8", "ngx-cookie-service": "^12.0.3", + "ngx-cropper": "^2.0.0-beta", "ngx-extended-pdf-viewer": "^13.0.0-alpha.2", "ngx-image-compress": "^11.0.3", "ngx-image-cropper": "^5.0.1", @@ -28580,6 +28581,24 @@ "@angular/core": "^12.0.0" } }, + "node_modules/ngx-cropper": { + "version": "2.0.0-beta", + "resolved": "https://registry.npmjs.org/ngx-cropper/-/ngx-cropper-2.0.0-beta.tgz", + "integrity": "sha512-nyX0OgPBYhIj6M7lVDswnn0yAALxvByl052iRKiUyQc4gn1Xf1LBX+my7Zfg6oq7F91hvwojTeYqvTeHkDMVfQ==", + "dependencies": { + "cropperjs": "^1.4.1", + "tslib": "^1.9.0" + }, + "peerDependencies": { + "@angular/common": "^6.0.0-rc.0 || ^6.0.0", + "@angular/core": "^6.0.0-rc.0 || ^6.0.0" + } + }, + "node_modules/ngx-cropper/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, "node_modules/ngx-extended-pdf-viewer": { "version": "13.0.0-alpha.2", "resolved": "https://registry.npmjs.org/ngx-extended-pdf-viewer/-/ngx-extended-pdf-viewer-13.0.0-alpha.2.tgz", @@ -66448,6 +66467,22 @@ "tslib": "^2.0.0" } }, + "ngx-cropper": { + "version": "2.0.0-beta", + "resolved": "https://registry.npmjs.org/ngx-cropper/-/ngx-cropper-2.0.0-beta.tgz", + "integrity": "sha512-nyX0OgPBYhIj6M7lVDswnn0yAALxvByl052iRKiUyQc4gn1Xf1LBX+my7Zfg6oq7F91hvwojTeYqvTeHkDMVfQ==", + "requires": { + "cropperjs": "^1.4.1", + "tslib": "^1.9.0" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + } + } + }, "ngx-extended-pdf-viewer": { "version": "13.0.0-alpha.2", "resolved": "https://registry.npmjs.org/ngx-extended-pdf-viewer/-/ngx-extended-pdf-viewer-13.0.0-alpha.2.tgz", diff --git a/package.json b/package.json index 47faba9a2..5cb76409b 100644 --- a/package.json +++ b/package.json @@ -193,6 +193,7 @@ "ng-lazyload-image": "^9.1.2", "ng2-pdf-viewer": "^3.0.8", "ngx-cookie-service": "^12.0.3", + "ngx-cropper": "^2.0.0-beta", "ngx-extended-pdf-viewer": "^13.0.0-alpha.2", "ngx-image-compress": "^11.0.3", "ngx-image-cropper": "^5.0.1", diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 6656a722e..57dc07330 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -103,7 +103,7 @@ import { calendarReducer } from './services/Repositorys/Agenda/agenda-memory-sou import {MatMenuModule} from '@angular/material/menu'; import {MatIconModule} from '@angular/material/icon'; - +import { AngularCropperjsModule } from 'angular-cropperjs'; // import { ServiceWorkerModule } from '@angular/service-worker'; // import { AngularFireModule } from '@angular/fire'; // import { AngularFireMessagingModule } from '@angular/fire/messaging'; @@ -191,7 +191,7 @@ import { FirebaseX } from '@ionic-native/firebase-x/ngx'; */ ImageCropperModule, MatMenuModule, - MatIconModule, + MatIconModule ], entryComponents: [ DiplomaOptionsPage, diff --git a/src/app/modals/profile/profile.page.ts b/src/app/modals/profile/profile.page.ts index 40a3a0e5d..e029bd954 100644 --- a/src/app/modals/profile/profile.page.ts +++ b/src/app/modals/profile/profile.page.ts @@ -144,7 +144,7 @@ export class ProfilePage implements OnInit { return time; } - @XTracerAsync({name:'profile/notificationClick', bugPrint: true, module:'notification'}) + @XTracerAsync({name:'profile/notificationClick', bugPrint: true, module:'notification', autoFinish: false}) async notificatinsRoutes (index, item: NotificationTable, tracing?: TracingType) { try { @@ -152,7 +152,9 @@ export class ProfilePage implements OnInit { this.isloading = true if (item.service === "agenda") { + tracing.addEvent('start getEventById') let res = await this.agendaDataRepository.getEventById(item.idObject, tracing) + tracing.addEvent('end getEventById') if(item.idObject) { @@ -168,9 +170,9 @@ export class ProfilePage implements OnInit { this.deleteNotification(item); tracing.setAttribute('outcome', 'success') } else { - tracing.setAttribute('outcome', 'success') - tracing.setAttribute('data.exist', 'false') + tracing.setAttribute('data.exist', 'false') + tracing.setAttribute('outcome', 'success') if (isHttpError(res.error)) { if(res.error.status == 404) { @@ -202,9 +204,10 @@ export class ProfilePage implements OnInit { this.deleteNotification(item); this.isloading = false } else { - tracing.setAttribute('outcome', 'success') + console.log('evento não existe') tracing.setAttribute('data.exist', 'false') + tracing.setAttribute('outcome', 'success') this.objectRead[item.notificationId] = true this.isloading = false } @@ -223,8 +226,11 @@ export class ProfilePage implements OnInit { } else if (item.service === "gabinete-digital") { this.isloading = true + + tracing.addEvent('start getTask') this.processesService.GetTask(item.idObject).subscribe((task) => { + tracing.addEvent('end getTask') if (item.service === "gabinete-digital" && item.object === "expedientes") { this.zone.run(() => this.router.navigate(['/home/gabinete-digital/expediente', item.idObject, 'gabinete-digital'])); } else if (item.service === "gabinete-digital" && item.object === "despachos") { @@ -258,9 +264,29 @@ export class ProfilePage implements OnInit { this.deleteNotification(item); this.isloading = false + tracing.setAttribute('outcome', 'success') + }, (error) => { + tracing.addEvent('end getTask') + tracing.log('gabinete notification not found', { + notificationObject: item + }) + this.objectRead[item.notificationId] = true this.isloading = false + + + if(isHttpError(error)) { + tracing.setAttribute('getTask.http.status.code', error.status?.toString()) + if(error.status == 400) { + tracing.setAttribute('outcome', 'failed') + } else { + tracing.setAttribute('outcome', 'success') + } + } else { + tracing.setAttribute('outcome', 'failed') + } + }) @@ -268,10 +294,14 @@ export class ProfilePage implements OnInit { if (item.service === "accoes" && item.idObject === "accao") { this.zone.run(() => this.router.navigate(['/home/publications', item.idObject])); this.deleteNotification(item); + + tracing.setAttribute('outcome', 'success') } else if (item.service === "accoes" && item.idObject === "publicacao") { this.zone.run(() => this.router.navigate(['/home/publications/view-publications', item.folderId, item.idObject])); this.deleteNotification(item); + + tracing.setAttribute('outcome', 'success') } } else if (item.service === "chat") { @@ -285,22 +315,30 @@ export class ProfilePage implements OnInit { }, 200); + + tracing.setAttribute('outcome', 'success') this.deleteNotification(item); } else { console.log({service:item.service, Object, IdObject:item.idObject, FolderId:item.folderId}) + tracing.log('click notification no route', { + notificationObject: item + }) tracing.setAttribute('notification.route', 'false') - tracing.setAttribute('outcome', 'failed') tracing.setAttribute('parameters', JSON.stringify({Service:item.service, Object, IdObject:item.idObject, FolderId:item.folderId})) + tracing.setAttribute('outcome', 'failed') } } catch(error) { console.log({service:item.service, Object, IdObject:item.idObject, FolderId: item.folderId}) - tracing.setAttribute('outcome', 'failed') + tracing.log('click notification catch', { + notificationObject: item + }) tracing.setAttribute('parameters', JSON.stringify({service:item.service, Object, IdObject:item.idObject, FolderId:item.folderId})) tracing.setAttribute('error', JSON.stringify(error)) + tracing.setAttribute('outcome', 'failed') } diff --git a/src/app/pages/gabinete-digital/gabinete-digital.page.html b/src/app/pages/gabinete-digital/gabinete-digital.page.html index ce99b0ccb..68cb8861a 100644 --- a/src/app/pages/gabinete-digital/gabinete-digital.page.html +++ b/src/app/pages/gabinete-digital/gabinete-digital.page.html @@ -9,7 +9,7 @@
- +
Gabinete Digital diff --git a/src/app/pages/gabinete-digital/gabinete-digital.page.ts b/src/app/pages/gabinete-digital/gabinete-digital.page.ts index 5eb47d8c1..068c25b4e 100644 --- a/src/app/pages/gabinete-digital/gabinete-digital.page.ts +++ b/src/app/pages/gabinete-digital/gabinete-digital.page.ts @@ -462,10 +462,10 @@ export class GabineteDigitalPage implements OnInit { async loadAllProcesses() { - // this.skeletonLoader = true - await this.TaskService.LoadTask() - this.dynamicSearch() - // this.skeletonLoader = false + this.skeletonLoader = true + await this.TaskService.LoadTask(); + this.dynamicSearch(); + this.skeletonLoader = false } diff --git a/src/app/services/decorator/api-validate-schema.decorator.ts b/src/app/services/decorator/api-validate-schema.decorator.ts index fb577f2b4..75cc726b8 100644 --- a/src/app/services/decorator/api-validate-schema.decorator.ts +++ b/src/app/services/decorator/api-validate-schema.decorator.ts @@ -33,6 +33,11 @@ export function APIReturn(schema: z.ZodTypeAny, path: string) { tracing?.setAttribute?.('map.error.schema-'+i, JSON.stringify(schema)) } + tracing.log('API return '+ path, { + data: result?.value, + issues: error?.errors + }) + } else { // Throw any other unexpected errors // throw error; @@ -74,6 +79,11 @@ export function APINODReturn(schema: z.ZodTypeAny, data , path: string, tracing? tracing?.setAttribute('map.error.schema-'+i, JSON.stringify(schema)) } + tracing.log('API return '+ path, { + data, + issues: error?.errors + }) + } else { console.log(error) // Throw any other unexpected errors diff --git a/src/app/services/monitoring/opentelemetry/tracer.ts b/src/app/services/monitoring/opentelemetry/tracer.ts index 550e6952f..39612e4c4 100644 --- a/src/app/services/monitoring/opentelemetry/tracer.ts +++ b/src/app/services/monitoring/opentelemetry/tracer.ts @@ -52,11 +52,13 @@ const createTracingInstance = ({bugPrint, name, module, autoFinish}): TracingTyp } const span = _tracerInstance.startSpan(name); + let finish = false const data = { event: {}, tags: {}, status: {} as any, + logs:[] } const returnObject = { @@ -83,14 +85,22 @@ const createTracingInstance = ({bugPrint, name, module, autoFinish}): TracingTyp if(key =='outcome' && value == 'failed') { returnObject.hasError('error') + if(!autoFinish) { + returnObject.finish() + } + } else if (key =='outcome' && value == 'success') { + span.setStatus({code: SpanStatusCode.OK, message:name}) + if(!autoFinish) { + returnObject.finish() + } } }, - log(message: string, data: Object) { + log(message: string, dataObject: Object) { const spanId = span.spanContext().spanId; const _tracer = OpentelemetryLogging.getTracer('logging') const spanContext = _tracer.startSpan(name) - data = convertAttributesToString(data) + dataObject = convertAttributesToString(dataObject) if(environment.apiURL != 'https://gdqas-api.oapr.gov.ao/api/') { openTelemetryLogging.send({ @@ -99,7 +109,7 @@ const createTracingInstance = ({bugPrint, name, module, autoFinish}): TracingTyp payload: { message: message, object: { - ...data, + ...dataObject, spanId, name, user: SessionStore?.user?.FullName, @@ -110,11 +120,15 @@ const createTracingInstance = ({bugPrint, name, module, autoFinish}): TracingTyp }) } + data.logs.push(dataObject) + }, getAttribute: (key: string) => { return data.tags[key] }, finish: () => { + if(finish) return + if(environment.apiURL != 'https://gdqas-api.oapr.gov.ao/api/') { span.end(); UseCaseCounter.add(1, {user: SessionStore?.user?.FullName, outcome:data.tags['outcome'] || data.status?.code , usecase: name}) @@ -123,6 +137,8 @@ const createTracingInstance = ({bugPrint, name, module, autoFinish}): TracingTyp if(bugPrint && (data.tags['outcome'] == 'failed' || data.status?.code == SpanStatusCode.ERROR)) { console.error(name, data) } + + finish = true }, hasError:(message: string) => { if(data.status?.code != SpanStatusCode.ERROR) { diff --git a/src/app/services/notifications.service.ts b/src/app/services/notifications.service.ts index 53468ede9..a8a64e141 100644 --- a/src/app/services/notifications.service.ts +++ b/src/app/services/notifications.service.ts @@ -124,10 +124,9 @@ export class NotificationsService { if (this.platform.is('ios')) { FCM.getToken() .then(r => { + tracing.setAttribute('notification.token', 'true') this.postToken(r.token, geturl, tracing) this.token = r.token - tracing.setAttribute('notification.token', 'true') - tracing.setAttribute('outcome', 'success') // alert(this.token) }) .catch(err => { @@ -139,9 +138,10 @@ export class NotificationsService { PushNotifications.addListener('registration', (token: Token) => { + + tracing.setAttribute('notification.token', 'true') this.postToken(token.value, geturl, tracing) this.token = token.value - tracing.setAttribute('notification.token', 'true') } ); @@ -157,13 +157,11 @@ export class NotificationsService { this.token = token tracing.setAttribute('notification.token', 'true') tracing.setAttribute('outcome', 'success') - tracing.finish() }, (error) => { console.error('Permission denied:', error); tracing.setAttribute('notification.token', 'false') tracing.setAttribute('outcome', 'failed') - tracing.finish() } ); } diff --git a/src/main.ts b/src/main.ts index a09850b03..54c214c33 100644 --- a/src/main.ts +++ b/src/main.ts @@ -62,3 +62,45 @@ platformBrowserDynamic().bootstrapModule(AppModule) defineCustomElements(window); console.log(environment.version.lastCommitTime) + +// error-capture.js + +// Function to capture error details +function captureError(message, sourceURL, lineno, colno, error) { + const errorDetails = { + message: message || 'Unknown error', + sourceURL: sourceURL || 'Unknown source', + lineNumber: lineno || 'Unknown line', + columnNumber: colno || 'Unknown column', + stack: error ? error.stack : 'No stack trace' + }; + + // Log to console + console.error('Error Details:', JSON.stringify(errorDetails, null, 2)); + + // Optionally, send to server or write to a local storage + // Example: Sending to server (requires server-side handling) + // fetch('/log-error', { + // method: 'POST', + // headers: { + // 'Content-Type': 'application/json' + // }, + // body: JSON.stringify(errorDetails) + // }); + + // Example: Storing in localStorage + // localStorage.setItem('errorLog', JSON.stringify(errorDetails)); +} + +// Capture errors from synchronous code +window.onerror = function(message, sourceURL, lineno, colno, error) { + captureError(message, sourceURL, lineno, colno, error); + // Return true to prevent default handling (optional) + return true; +}; + +// Capture errors from promise rejections +window.addEventListener('unhandledrejection', function(event) { + const { reason } = event; + captureError(reason.message || 'Unhandled rejection', 'Unknown source', 'Unknown line', 'Unknown column', reason); +}); diff --git a/version/git-version.ts b/version/git-version.ts index 257f40de3..65cf48d00 100644 --- a/version/git-version.ts +++ b/version/git-version.ts @@ -1,11 +1,11 @@ export let versionData = { - "shortSHA": "2e7ebc71c", - "SHA": "2e7ebc71cea8c47f27fe163f1d460d9694e0b0ea", + "shortSHA": "8f0625eed", + "SHA": "8f0625eed4612d4f1564895de23a9ec633f54ca0", "branch": "feature/agenda-api-peter", "lastCommitAuthor": "'Peter Maquiran'", - "lastCommitTime": "'Mon Jul 29 17:23:41 2024 +0100'", - "lastCommitMessage": "fix video controls", - "lastCommitNumber": "5893", - "changeStatus": "On branch feature/agenda-api-peter\nYour branch is ahead of 'origin/feature/agenda-api-peter' by 1 commit.\n (use \"git push\" to publish your local commits)\n\nChanges to be committed:\n (use \"git restore --staged ...\" to unstage)\n\tmodified: src/app/services/monitoring/opentelemetry/opentelemetry.ts\n\tmodified: src/app/shared/publication/view-publications/view-publications.page.html\n\tmodified: src/app/shared/publication/view-publications/view-publications.page.scss\n\tmodified: version/git-version.ts", + "lastCommitTime": "'Mon Jul 29 17:36:35 2024 +0100'", + "lastCommitMessage": "expand click area", + "lastCommitNumber": "5894", + "changeStatus": "On branch feature/agenda-api-peter\nYour branch is up to date with 'origin/feature/agenda-api-peter'.\n\nChanges to be committed:\n (use \"git restore --staged ...\" to unstage)\n\tmodified: package-lock.json\n\tmodified: package.json\n\tmodified: src/app/app.module.ts\n\tmodified: src/app/modals/profile/profile.page.ts\n\tmodified: src/app/pages/gabinete-digital/gabinete-digital.page.html\n\tmodified: src/app/pages/gabinete-digital/gabinete-digital.page.ts\n\tmodified: src/app/services/decorator/api-validate-schema.decorator.ts\n\tmodified: src/app/services/monitoring/opentelemetry/tracer.ts\n\tmodified: src/app/services/notifications.service.ts\n\tmodified: src/main.ts", "changeAuthor": "peter.maquiran" } \ No newline at end of file