@viplance/nestjs-logger 0.4.0 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +23 -3
- package/dist/defaults.js +1 -1
- package/dist/entities/log.entity.d.ts +2 -2
- package/dist/entities/log.entity.js +1 -1
- package/dist/guards/access.guard.d.ts +1 -1
- package/dist/guards/access.guard.js +2 -2
- package/dist/index.d.ts +4 -4
- package/dist/interceptors/log.interceptor.d.ts +4 -4
- package/dist/log.module.d.ts +1 -1
- package/dist/log.module.js +7 -7
- package/dist/services/log.service.d.ts +8 -8
- package/dist/services/log.service.js +32 -29
- package/dist/services/log.service.js.map +1 -1
- package/dist/services/memory-db.service.d.ts +1 -1
- package/dist/services/memory-db.service.js +5 -5
- package/dist/services/ws.service.d.ts +3 -3
- package/dist/services/ws.service.js +14 -14
- package/dist/types/index.d.ts +3 -3
- package/dist/types/options.type.d.ts +1 -0
- package/dist/utils/entity2table.d.ts +1 -1
- package/dist/utils/entity2table.js +6 -6
- package/package.json +4 -1
- package/public/scripts/common.js +28 -28
- package/public/scripts/details-popup.js +10 -10
- package/public/scripts/json-viewer.js +4 -4
- package/src/defaults.ts +1 -1
- package/src/entities/log.entity.ts +3 -3
- package/src/guards/access.guard.ts +5 -5
- package/src/index.ts +4 -4
- package/src/interceptors/log.interceptor.ts +5 -5
- package/src/log.module.ts +18 -18
- package/src/services/log.service.ts +44 -40
- package/src/services/memory-db.service.ts +9 -9
- package/src/services/ws.d.ts +1 -1
- package/src/services/ws.service.ts +19 -19
- package/src/types/index.ts +3 -3
- package/src/types/log.type.ts +5 -5
- package/src/types/options.type.ts +1 -0
- package/src/utils/entity2table.ts +8 -8
- package/public/json.html +0 -0
package/public/scripts/common.js
CHANGED
|
@@ -10,7 +10,7 @@ const selectedLogTypes = {
|
|
|
10
10
|
const logTypes = Object.keys(selectedLogTypes).filter((key) => key !== `all`);
|
|
11
11
|
|
|
12
12
|
let logs = [];
|
|
13
|
-
let text =
|
|
13
|
+
let text = '';
|
|
14
14
|
|
|
15
15
|
connectWebSocket();
|
|
16
16
|
|
|
@@ -105,12 +105,12 @@ function getDate(incomingDate) {
|
|
|
105
105
|
const date = new Date(incomingDate);
|
|
106
106
|
|
|
107
107
|
const formatter = new Intl.DateTimeFormat(undefined, {
|
|
108
|
-
hour:
|
|
109
|
-
minute:
|
|
110
|
-
second:
|
|
111
|
-
month:
|
|
112
|
-
day:
|
|
113
|
-
year:
|
|
108
|
+
hour: '2-digit',
|
|
109
|
+
minute: '2-digit',
|
|
110
|
+
second: '2-digit',
|
|
111
|
+
month: 'short',
|
|
112
|
+
day: '2-digit',
|
|
113
|
+
year: 'numeric',
|
|
114
114
|
hour12: false,
|
|
115
115
|
});
|
|
116
116
|
|
|
@@ -133,20 +133,20 @@ function getLogHtmlElement(log) {
|
|
|
133
133
|
<div class="log-info">${log.message}</div>
|
|
134
134
|
<div class="date">${getDate(log.updatedAt)}</div>
|
|
135
135
|
</div>
|
|
136
|
-
<div class="col context">${log.trace ||
|
|
136
|
+
<div class="col context">${log.trace || ''}</div>
|
|
137
137
|
<div class="col">${log.count}</div>
|
|
138
138
|
</div>`;
|
|
139
139
|
}
|
|
140
140
|
|
|
141
141
|
function renderLogs(logList = logs) {
|
|
142
|
-
let html =
|
|
142
|
+
let html = '';
|
|
143
143
|
|
|
144
144
|
logList
|
|
145
145
|
.filter((log) => {
|
|
146
|
-
return selectedLogTypes[
|
|
146
|
+
return selectedLogTypes['all'] || selectedLogTypes[log.type];
|
|
147
147
|
})
|
|
148
148
|
.filter((log) => {
|
|
149
|
-
if (text ===
|
|
149
|
+
if (text === '') return true;
|
|
150
150
|
|
|
151
151
|
return (
|
|
152
152
|
log.message.toLowerCase().includes(text) ||
|
|
@@ -160,32 +160,32 @@ function renderLogs(logList = logs) {
|
|
|
160
160
|
html += getLogHtmlElement(log);
|
|
161
161
|
});
|
|
162
162
|
|
|
163
|
-
document.getElementById(
|
|
163
|
+
document.getElementById('logs').innerHTML = html;
|
|
164
164
|
}
|
|
165
165
|
|
|
166
166
|
async function checkElementsVisibility(logList = logs) {
|
|
167
167
|
if (logList.length === 0) {
|
|
168
|
-
document.getElementById(
|
|
169
|
-
document.getElementById(
|
|
170
|
-
document.querySelector(
|
|
171
|
-
document.querySelector(
|
|
168
|
+
document.getElementById('no-logs').style.display = 'block';
|
|
169
|
+
document.getElementById('search').style.display = 'none';
|
|
170
|
+
document.querySelector('.table-header').style.display = 'none';
|
|
171
|
+
document.querySelector('nav').style.display = 'none';
|
|
172
172
|
} else {
|
|
173
|
-
document.getElementById(
|
|
174
|
-
document.getElementById(
|
|
175
|
-
document.querySelector(
|
|
176
|
-
document.querySelector(
|
|
173
|
+
document.getElementById('no-logs').style.display = 'none';
|
|
174
|
+
document.getElementById('search').style.display = 'inline-block';
|
|
175
|
+
document.querySelector('.table-header').style.display = 'flex';
|
|
176
|
+
document.querySelector('nav').style.display = 'flex';
|
|
177
177
|
}
|
|
178
178
|
}
|
|
179
179
|
|
|
180
180
|
async function getLogs() {
|
|
181
181
|
const { origin, pathname, search } = window.location;
|
|
182
182
|
const searchParams = new URLSearchParams(search);
|
|
183
|
-
const key = searchParams.get(
|
|
183
|
+
const key = searchParams.get('key');
|
|
184
184
|
|
|
185
185
|
if (!!socket) {
|
|
186
186
|
socket.send(
|
|
187
187
|
JSON.stringify({
|
|
188
|
-
action:
|
|
188
|
+
action: 'getLogs',
|
|
189
189
|
key,
|
|
190
190
|
})
|
|
191
191
|
);
|
|
@@ -199,7 +199,7 @@ async function getLogs() {
|
|
|
199
199
|
|
|
200
200
|
renderLogs();
|
|
201
201
|
} else {
|
|
202
|
-
alert(
|
|
202
|
+
alert('An error occurred while fetching logs.');
|
|
203
203
|
}
|
|
204
204
|
}
|
|
205
205
|
}
|
|
@@ -210,12 +210,12 @@ async function deleteLog(_id) {
|
|
|
210
210
|
const { origin, pathname, search: searchParams } = window.location;
|
|
211
211
|
|
|
212
212
|
const searchParamsWithId = new URLSearchParams(searchParams);
|
|
213
|
-
const key = searchParamsWithId.get(
|
|
213
|
+
const key = searchParamsWithId.get('key');
|
|
214
214
|
|
|
215
215
|
if (!!socket) {
|
|
216
216
|
socket.send(
|
|
217
217
|
JSON.stringify({
|
|
218
|
-
action:
|
|
218
|
+
action: 'delete',
|
|
219
219
|
key,
|
|
220
220
|
data: {
|
|
221
221
|
_id,
|
|
@@ -225,12 +225,12 @@ async function deleteLog(_id) {
|
|
|
225
225
|
closePopup();
|
|
226
226
|
getLogs();
|
|
227
227
|
} else {
|
|
228
|
-
searchParamsWithId.set(
|
|
228
|
+
searchParamsWithId.set('id', _id);
|
|
229
229
|
|
|
230
230
|
const res = await fetch(
|
|
231
231
|
`${origin}${pathname}api?${searchParamsWithId.toString()}`,
|
|
232
232
|
{
|
|
233
|
-
method:
|
|
233
|
+
method: 'DELETE',
|
|
234
234
|
}
|
|
235
235
|
);
|
|
236
236
|
|
|
@@ -238,7 +238,7 @@ async function deleteLog(_id) {
|
|
|
238
238
|
closePopup();
|
|
239
239
|
getLogs();
|
|
240
240
|
} else {
|
|
241
|
-
alert(
|
|
241
|
+
alert('An error occurred while deleting log.');
|
|
242
242
|
}
|
|
243
243
|
}
|
|
244
244
|
}
|
|
@@ -6,9 +6,9 @@ function showLogDetails(log) {
|
|
|
6
6
|
const timeInfo =
|
|
7
7
|
log.updatedAt === log.createdAt
|
|
8
8
|
? getDate(log.updatedAt)
|
|
9
|
-
: `Updated: ${getDate(
|
|
10
|
-
log.
|
|
11
|
-
)}`;
|
|
9
|
+
: `Updated: ${getDate(
|
|
10
|
+
log.updatedAt
|
|
11
|
+
)}. First seen: ${getDate(log.createdAt)}`;
|
|
12
12
|
|
|
13
13
|
popup.innerHTML = `
|
|
14
14
|
<div class="content center">
|
|
@@ -23,7 +23,7 @@ function showLogDetails(log) {
|
|
|
23
23
|
<h3 class="mt-15">Trace</h3>
|
|
24
24
|
<p class="key pl-2"><span>${getTrace(log.trace)}</span></p>
|
|
25
25
|
`
|
|
26
|
-
:
|
|
26
|
+
: ''
|
|
27
27
|
}
|
|
28
28
|
${
|
|
29
29
|
context
|
|
@@ -31,7 +31,7 @@ function showLogDetails(log) {
|
|
|
31
31
|
<h3 class="mt-15">Context</h3>
|
|
32
32
|
<p>${jsonViewer(context)}</p>
|
|
33
33
|
`
|
|
34
|
-
:
|
|
34
|
+
: ''
|
|
35
35
|
}
|
|
36
36
|
${
|
|
37
37
|
breadcrumbs && breadcrumbs.length > 0
|
|
@@ -39,7 +39,7 @@ function showLogDetails(log) {
|
|
|
39
39
|
<h3 class="mt-15">Breadcrumbs</h3>
|
|
40
40
|
<p>${jsonViewer(breadcrumbs)}</p>
|
|
41
41
|
`
|
|
42
|
-
:
|
|
42
|
+
: ''
|
|
43
43
|
}
|
|
44
44
|
<div class="content">
|
|
45
45
|
<button class="white mt-2" onclick="closePopup()">Close</button>
|
|
@@ -50,11 +50,11 @@ function showLogDetails(log) {
|
|
|
50
50
|
</div>
|
|
51
51
|
<div>`;
|
|
52
52
|
|
|
53
|
-
popup.style.display =
|
|
53
|
+
popup.style.display = 'block';
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
function getObject(context) {
|
|
57
|
-
if (typeof context ===
|
|
57
|
+
if (typeof context === 'string') {
|
|
58
58
|
return JSON.parse(context);
|
|
59
59
|
}
|
|
60
60
|
|
|
@@ -62,10 +62,10 @@ function getObject(context) {
|
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
function getTrace(trace) {
|
|
65
|
-
return trace.replace(new RegExp(String.fromCharCode(10),
|
|
65
|
+
return trace.replace(new RegExp(String.fromCharCode(10), 'g'), '<br />');
|
|
66
66
|
}
|
|
67
67
|
|
|
68
68
|
function closePopup() {
|
|
69
69
|
const popup = document.getElementById(`popup`);
|
|
70
|
-
popup.style.display =
|
|
70
|
+
popup.style.display = 'none';
|
|
71
71
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
function jsonViewer(json, parentKey) {
|
|
2
2
|
if (!json) {
|
|
3
|
-
return
|
|
3
|
+
return '';
|
|
4
4
|
}
|
|
5
5
|
|
|
6
6
|
res = `<div>`;
|
|
@@ -8,7 +8,7 @@ function jsonViewer(json, parentKey) {
|
|
|
8
8
|
if (Array.isArray(json)) {
|
|
9
9
|
json.forEach((item) => {
|
|
10
10
|
res += `<div class="key pl-2">${
|
|
11
|
-
typeof item ===
|
|
11
|
+
typeof item === 'object' ? jsonViewer(item) : `<span>${item}</span>`
|
|
12
12
|
}</div>`;
|
|
13
13
|
});
|
|
14
14
|
|
|
@@ -23,7 +23,7 @@ function jsonViewer(json, parentKey) {
|
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
for (const key of keys) {
|
|
26
|
-
if (typeof json[key] ===
|
|
26
|
+
if (typeof json[key] === 'object') {
|
|
27
27
|
res += jsonViewer(json[key], key);
|
|
28
28
|
} else {
|
|
29
29
|
res += `<div class="key pl-2">${key}: <span>${json[key]}</span></div>`;
|
|
@@ -34,7 +34,7 @@ function jsonViewer(json, parentKey) {
|
|
|
34
34
|
res += `</div>`;
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
res +=
|
|
37
|
+
res += '</div>';
|
|
38
38
|
|
|
39
39
|
return res;
|
|
40
40
|
}
|
package/src/defaults.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const defaultTable =
|
|
1
|
+
export const defaultTable = 'logs';
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import { DataSourceOptions, EntitySchema } from
|
|
1
|
+
import { DataSourceOptions, EntitySchema } from 'typeorm';
|
|
2
2
|
|
|
3
3
|
export function createLogEntity(
|
|
4
4
|
name: string,
|
|
5
|
-
dbType: DataSourceOptions[
|
|
5
|
+
dbType: DataSourceOptions['type'] | 'memory'
|
|
6
6
|
) {
|
|
7
7
|
return new EntitySchema({
|
|
8
8
|
name,
|
|
9
9
|
columns: {
|
|
10
10
|
_id: {
|
|
11
|
-
type: dbType ===
|
|
11
|
+
type: dbType === 'mongodb' ? String : Number,
|
|
12
12
|
objectId: true,
|
|
13
13
|
primary: true,
|
|
14
14
|
generated: true,
|
|
@@ -3,9 +3,9 @@ import {
|
|
|
3
3
|
ExecutionContext,
|
|
4
4
|
HttpException,
|
|
5
5
|
Injectable,
|
|
6
|
-
} from
|
|
7
|
-
import { LogService } from
|
|
8
|
-
import querystring from
|
|
6
|
+
} from '@nestjs/common';
|
|
7
|
+
import { LogService } from '../services/log.service';
|
|
8
|
+
import querystring from 'node:querystring';
|
|
9
9
|
|
|
10
10
|
@Injectable()
|
|
11
11
|
export class LogAccessGuard implements CanActivate {
|
|
@@ -14,10 +14,10 @@ export class LogAccessGuard implements CanActivate {
|
|
|
14
14
|
? context.switchToHttp().getRequest()
|
|
15
15
|
: context; // hook for using as method
|
|
16
16
|
|
|
17
|
-
const params = querystring.parse(req.url.split(
|
|
17
|
+
const params = querystring.parse(req.url.split('?')[1]);
|
|
18
18
|
|
|
19
19
|
if (LogService.options.key && params.key !== LogService.options.key) {
|
|
20
|
-
throw new HttpException(
|
|
20
|
+
throw new HttpException('Unauthorized', 401);
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
return true;
|
package/src/index.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export * from
|
|
2
|
-
export * from
|
|
3
|
-
export * from
|
|
4
|
-
export * from
|
|
1
|
+
export * from './interceptors/log.interceptor';
|
|
2
|
+
export * from './log.module';
|
|
3
|
+
export * from './types/index';
|
|
4
|
+
export * from './services/log.service';
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type { CallHandler, NestInterceptor } from
|
|
2
|
-
import { Inject, Injectable } from
|
|
3
|
-
import { Observable, tap } from
|
|
4
|
-
import { LogService } from
|
|
5
|
-
import { ExecutionContextHost } from
|
|
1
|
+
import type { CallHandler, NestInterceptor } from '@nestjs/common';
|
|
2
|
+
import { Inject, Injectable } from '@nestjs/common';
|
|
3
|
+
import { Observable, tap } from 'rxjs';
|
|
4
|
+
import { LogService } from '../services/log.service';
|
|
5
|
+
import { ExecutionContextHost } from '@nestjs/core/helpers/execution-context-host';
|
|
6
6
|
|
|
7
7
|
@Injectable()
|
|
8
8
|
export class LogInterceptor implements NestInterceptor {
|
package/src/log.module.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import { Module, Global, HttpException } from
|
|
2
|
-
import { LogService } from
|
|
3
|
-
import { MemoryDbService } from
|
|
4
|
-
import { LogInterceptor } from
|
|
5
|
-
import { LogModuleOptions } from
|
|
6
|
-
import { TypeOrmModule } from
|
|
7
|
-
import querystring from
|
|
8
|
-
import { ApplicationConfig } from
|
|
9
|
-
import { join } from
|
|
10
|
-
import { LogAccessGuard } from
|
|
11
|
-
import { WsService } from
|
|
1
|
+
import { Module, Global, HttpException } from '@nestjs/common';
|
|
2
|
+
import { LogService } from './services/log.service';
|
|
3
|
+
import { MemoryDbService } from './services/memory-db.service';
|
|
4
|
+
import { LogInterceptor } from './interceptors/log.interceptor';
|
|
5
|
+
import { LogModuleOptions } from './types';
|
|
6
|
+
import { TypeOrmModule } from '@nestjs/typeorm';
|
|
7
|
+
import querystring from 'node:querystring';
|
|
8
|
+
import { ApplicationConfig } from '@nestjs/core';
|
|
9
|
+
import { join } from 'node:path';
|
|
10
|
+
import { LogAccessGuard } from './guards/access.guard';
|
|
11
|
+
import { WsService } from './services/ws.service';
|
|
12
12
|
|
|
13
13
|
@Global()
|
|
14
14
|
@Module({
|
|
@@ -40,7 +40,7 @@ export class LogModule {
|
|
|
40
40
|
app.useGlobalInterceptors(new LogInterceptor(logService)); // intercept all errors
|
|
41
41
|
|
|
42
42
|
if (options?.path) {
|
|
43
|
-
app.useStaticAssets(join(__dirname,
|
|
43
|
+
app.useStaticAssets(join(__dirname, '..', 'public'), {
|
|
44
44
|
prefix: options.path,
|
|
45
45
|
});
|
|
46
46
|
|
|
@@ -48,7 +48,7 @@ export class LogModule {
|
|
|
48
48
|
|
|
49
49
|
// frontend settings endpoint
|
|
50
50
|
httpAdapter.get(
|
|
51
|
-
join(options.path,
|
|
51
|
+
join(options.path, 'settings'),
|
|
52
52
|
async (req: any, res: any) => {
|
|
53
53
|
logAccessGuard.canActivate(req);
|
|
54
54
|
|
|
@@ -58,7 +58,7 @@ export class LogModule {
|
|
|
58
58
|
result.websocket = {
|
|
59
59
|
namespace: options.websocket?.namespace,
|
|
60
60
|
port: options.websocket?.port,
|
|
61
|
-
host: options.websocket?.host || req.headers?.host.split(
|
|
61
|
+
host: options.websocket?.host || req.headers?.host.split(':')[0],
|
|
62
62
|
};
|
|
63
63
|
}
|
|
64
64
|
|
|
@@ -67,7 +67,7 @@ export class LogModule {
|
|
|
67
67
|
);
|
|
68
68
|
|
|
69
69
|
// get all logs endpoint
|
|
70
|
-
httpAdapter.get(join(options.path,
|
|
70
|
+
httpAdapter.get(join(options.path, 'api'), async (req: any, res: any) => {
|
|
71
71
|
logAccessGuard.canActivate(req);
|
|
72
72
|
|
|
73
73
|
res.json(await logService.getAll());
|
|
@@ -75,14 +75,14 @@ export class LogModule {
|
|
|
75
75
|
|
|
76
76
|
// delete log endpoint
|
|
77
77
|
httpAdapter.delete(
|
|
78
|
-
join(options.path,
|
|
78
|
+
join(options.path, 'api'),
|
|
79
79
|
async (req: any, res: any) => {
|
|
80
80
|
logAccessGuard.canActivate(req);
|
|
81
81
|
|
|
82
|
-
const params = querystring.parse(req.url.split(
|
|
82
|
+
const params = querystring.parse(req.url.split('?')[1]);
|
|
83
83
|
|
|
84
84
|
if (!params.id) {
|
|
85
|
-
throw new HttpException(
|
|
85
|
+
throw new HttpException('id is required', 400);
|
|
86
86
|
}
|
|
87
87
|
|
|
88
88
|
res.json(await logService.delete(params.id.toString()));
|
|
@@ -3,28 +3,28 @@ import {
|
|
|
3
3
|
LoggerService,
|
|
4
4
|
OnApplicationShutdown,
|
|
5
5
|
Scope,
|
|
6
|
-
} from
|
|
7
|
-
import { MemoryDbService } from
|
|
8
|
-
import { defaultTable } from
|
|
9
|
-
import { Context, LogModuleOptions, LogType } from
|
|
6
|
+
} from '@nestjs/common';
|
|
7
|
+
import { MemoryDbService } from './memory-db.service';
|
|
8
|
+
import { defaultTable } from '../defaults';
|
|
9
|
+
import { Context, LogModuleOptions, LogType } from '../types';
|
|
10
10
|
import {
|
|
11
11
|
DataSource,
|
|
12
12
|
DataSourceOptions,
|
|
13
13
|
EntityManager,
|
|
14
14
|
EntitySchema,
|
|
15
|
-
} from
|
|
16
|
-
import { createLogEntity } from
|
|
17
|
-
import { ExecutionContextHost } from
|
|
18
|
-
import { setInterval } from
|
|
19
|
-
import { entity2table } from
|
|
20
|
-
import { WsService } from
|
|
21
|
-
import { Subscription } from
|
|
15
|
+
} from 'typeorm';
|
|
16
|
+
import { createLogEntity } from '../entities/log.entity';
|
|
17
|
+
import { ExecutionContextHost } from '@nestjs/core/helpers/execution-context-host';
|
|
18
|
+
import { setInterval } from 'timers';
|
|
19
|
+
import { entity2table } from '../utils/entity2table';
|
|
20
|
+
import { WsService } from './ws.service';
|
|
21
|
+
import { Subscription } from 'rxjs';
|
|
22
22
|
|
|
23
23
|
@Injectable({ scope: Scope.TRANSIENT })
|
|
24
24
|
export class LogService implements LoggerService, OnApplicationShutdown {
|
|
25
25
|
static connection: DataSource;
|
|
26
26
|
static options: LogModuleOptions;
|
|
27
|
-
static Log: EntitySchema = createLogEntity(defaultTable,
|
|
27
|
+
static Log: EntitySchema = createLogEntity(defaultTable, 'memory');
|
|
28
28
|
static timer: ReturnType<typeof setInterval>;
|
|
29
29
|
static subscription: Subscription;
|
|
30
30
|
|
|
@@ -44,7 +44,7 @@ export class LogService implements LoggerService, OnApplicationShutdown {
|
|
|
44
44
|
async connectDb(options: LogModuleOptions): Promise<DataSource> {
|
|
45
45
|
LogService.Log = createLogEntity(
|
|
46
46
|
options.database?.collection || options.database?.table || defaultTable,
|
|
47
|
-
options.database?.type ||
|
|
47
|
+
options.database?.type || 'mongodb'
|
|
48
48
|
);
|
|
49
49
|
|
|
50
50
|
if (!LogService.options) {
|
|
@@ -62,7 +62,7 @@ export class LogService implements LoggerService, OnApplicationShutdown {
|
|
|
62
62
|
LogService.connection = new DataSource(dataSourceOptions);
|
|
63
63
|
await LogService.connection.initialize();
|
|
64
64
|
|
|
65
|
-
if (dataSourceOptions.type !==
|
|
65
|
+
if (dataSourceOptions.type !== 'mongodb') {
|
|
66
66
|
const queryRunner = LogService.connection.createQueryRunner();
|
|
67
67
|
|
|
68
68
|
try {
|
|
@@ -92,13 +92,13 @@ export class LogService implements LoggerService, OnApplicationShutdown {
|
|
|
92
92
|
LogService.subscription = this.wsService.onMessage.subscribe(
|
|
93
93
|
async (message) => {
|
|
94
94
|
switch (message.action) {
|
|
95
|
-
case
|
|
95
|
+
case 'getLogs':
|
|
96
96
|
this.wsService.sendMessage({
|
|
97
|
-
action:
|
|
97
|
+
action: 'list',
|
|
98
98
|
data: await this.getAll(),
|
|
99
99
|
});
|
|
100
100
|
break;
|
|
101
|
-
case
|
|
101
|
+
case 'delete':
|
|
102
102
|
this.delete(message.data._id);
|
|
103
103
|
break;
|
|
104
104
|
}
|
|
@@ -159,23 +159,23 @@ export class LogService implements LoggerService, OnApplicationShutdown {
|
|
|
159
159
|
async getAll(): Promise<any[]> {
|
|
160
160
|
return this.getConnection().find(LogService.Log, {
|
|
161
161
|
select: [
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
162
|
+
'_id',
|
|
163
|
+
'type',
|
|
164
|
+
'message',
|
|
165
|
+
'count',
|
|
166
|
+
'createdAt',
|
|
167
|
+
'updatedAt',
|
|
168
|
+
'context',
|
|
169
|
+
'trace',
|
|
170
|
+
'breadcrumbs',
|
|
171
171
|
],
|
|
172
|
-
order: { updatedAt:
|
|
172
|
+
order: { updatedAt: 'DESC' },
|
|
173
173
|
});
|
|
174
174
|
}
|
|
175
175
|
|
|
176
176
|
async delete(_id: string) {
|
|
177
177
|
this.wsService.sendMessage({
|
|
178
|
-
action:
|
|
178
|
+
action: 'delete',
|
|
179
179
|
data: { _id },
|
|
180
180
|
});
|
|
181
181
|
return this.getConnection().delete(LogService.Log, _id);
|
|
@@ -192,12 +192,16 @@ export class LogService implements LoggerService, OnApplicationShutdown {
|
|
|
192
192
|
const connection = this.getConnection();
|
|
193
193
|
|
|
194
194
|
// find the same log in DB
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
195
|
+
let log;
|
|
196
|
+
|
|
197
|
+
if (LogService.options.join) {
|
|
198
|
+
log = await connection.findOne(LogService.Log, {
|
|
199
|
+
where: {
|
|
200
|
+
type: data.type,
|
|
201
|
+
message: data.message,
|
|
202
|
+
},
|
|
203
|
+
});
|
|
204
|
+
}
|
|
201
205
|
|
|
202
206
|
const context = data.context ? this.parseContext(data.context) : undefined;
|
|
203
207
|
|
|
@@ -211,11 +215,11 @@ export class LogService implements LoggerService, OnApplicationShutdown {
|
|
|
211
215
|
};
|
|
212
216
|
|
|
213
217
|
this.wsService.sendMessage({
|
|
214
|
-
action:
|
|
218
|
+
action: 'update',
|
|
215
219
|
data: { ...log, ...updatedLog },
|
|
216
220
|
});
|
|
217
221
|
|
|
218
|
-
await connection.update(LogService.Log, log[
|
|
222
|
+
await connection.update(LogService.Log, log['_id'], {
|
|
219
223
|
context,
|
|
220
224
|
trace: data.trace,
|
|
221
225
|
breadcrumbs: this.breadcrumbs,
|
|
@@ -241,7 +245,7 @@ export class LogService implements LoggerService, OnApplicationShutdown {
|
|
|
241
245
|
const _id = this.getNewObjectId(res);
|
|
242
246
|
|
|
243
247
|
this.wsService.sendMessage({
|
|
244
|
-
action:
|
|
248
|
+
action: 'insert',
|
|
245
249
|
data: { _id, ...insertedLog },
|
|
246
250
|
});
|
|
247
251
|
|
|
@@ -299,9 +303,9 @@ export class LogService implements LoggerService, OnApplicationShutdown {
|
|
|
299
303
|
private async checkRecords() {
|
|
300
304
|
if (LogService.options?.maxSize) {
|
|
301
305
|
const latest = await this.getConnection().find(LogService.Log, {
|
|
302
|
-
order: { updatedAt:
|
|
306
|
+
order: { updatedAt: 'DESC' },
|
|
303
307
|
take: LogService.options?.maxSize,
|
|
304
|
-
select: [
|
|
308
|
+
select: ['_id'],
|
|
305
309
|
});
|
|
306
310
|
|
|
307
311
|
const latestIds = latest.map((item) => item.id);
|
|
@@ -311,7 +315,7 @@ export class LogService implements LoggerService, OnApplicationShutdown {
|
|
|
311
315
|
.createQueryBuilder()
|
|
312
316
|
.delete()
|
|
313
317
|
.from(LogService.Log)
|
|
314
|
-
.where(
|
|
318
|
+
.where('_id NOT IN (:...ids)', { ids: latestIds })
|
|
315
319
|
.execute();
|
|
316
320
|
}
|
|
317
321
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// Memory DB layer
|
|
2
|
-
import { Injectable } from
|
|
3
|
-
import { createHash, randomBytes } from
|
|
4
|
-
import { defaultTable } from
|
|
5
|
-
import { EntitySchema, FindManyOptions } from
|
|
2
|
+
import { Injectable } from '@nestjs/common';
|
|
3
|
+
import { createHash, randomBytes } from 'crypto';
|
|
4
|
+
import { defaultTable } from '../defaults';
|
|
5
|
+
import { EntitySchema, FindManyOptions } from 'typeorm';
|
|
6
6
|
|
|
7
7
|
const tables = [defaultTable];
|
|
8
8
|
|
|
@@ -20,8 +20,8 @@ export class MemoryDbService {
|
|
|
20
20
|
const table = this.getTableName(entity);
|
|
21
21
|
|
|
22
22
|
// generate new random _id
|
|
23
|
-
const randomData = randomBytes(24).toString(
|
|
24
|
-
const _id = createHash(
|
|
23
|
+
const randomData = randomBytes(24).toString('hex');
|
|
24
|
+
const _id = createHash('sha256').update(randomData).digest('hex');
|
|
25
25
|
|
|
26
26
|
this.db[table].push({
|
|
27
27
|
...data,
|
|
@@ -39,7 +39,7 @@ export class MemoryDbService {
|
|
|
39
39
|
const table = this.getTableName(entity);
|
|
40
40
|
let index: number | null = null;
|
|
41
41
|
|
|
42
|
-
if (typeof condition ===
|
|
42
|
+
if (typeof condition === 'string') {
|
|
43
43
|
index = this.findIndex(entity, { where: { _id: condition } });
|
|
44
44
|
}
|
|
45
45
|
|
|
@@ -136,8 +136,8 @@ export class MemoryDbService {
|
|
|
136
136
|
if (
|
|
137
137
|
obj1 == null ||
|
|
138
138
|
obj2 == null ||
|
|
139
|
-
typeof obj1 !==
|
|
140
|
-
typeof obj2 !==
|
|
139
|
+
typeof obj1 !== 'object' ||
|
|
140
|
+
typeof obj2 !== 'object'
|
|
141
141
|
) {
|
|
142
142
|
return false;
|
|
143
143
|
}
|
package/src/services/ws.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
declare module
|
|
1
|
+
declare module 'ws';
|