@viplance/nestjs-logger 0.3.4 → 0.3.6
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 +6 -5
- package/dist/entities/log.entity.d.ts +1 -0
- package/dist/entities/log.entity.js +1 -0
- package/dist/entities/log.entity.js.map +1 -1
- package/dist/log.interceptor.js +4 -3
- package/dist/log.interceptor.js.map +1 -1
- package/dist/services/log.service.d.ts +3 -0
- package/dist/services/log.service.js +10 -0
- package/dist/services/log.service.js.map +1 -1
- package/package.json +1 -1
- package/public/index.html +1 -0
- package/public/scripts/common.js +35 -11
- package/public/scripts/details-popup.js +20 -12
- package/public/scripts/json-viewer.js +14 -3
- package/public/styles/index.css +51 -17
- package/src/entities/log.entity.ts +1 -0
- package/src/log.interceptor.ts +2 -2
- package/src/services/log.service.ts +13 -0
package/README.md
CHANGED
|
@@ -61,8 +61,9 @@ Connect the database to store logs.<br />
|
|
|
61
61
|
<br />
|
|
62
62
|
|
|
63
63
|
### The LogService methods:
|
|
64
|
-
- log()
|
|
65
|
-
- error()
|
|
66
|
-
- warn()
|
|
67
|
-
- debug()
|
|
68
|
-
- verbose()
|
|
64
|
+
- log(message: string)
|
|
65
|
+
- error(message: string)
|
|
66
|
+
- warn(message: string)
|
|
67
|
+
- debug(message: string)
|
|
68
|
+
- verbose(message: string)
|
|
69
|
+
- addBreadcrumb(any)
|
|
@@ -16,6 +16,7 @@ function createLogEntity(name) {
|
|
|
16
16
|
count: { type: Number, default: 1 },
|
|
17
17
|
context: { type: String, nullable: true },
|
|
18
18
|
trace: { type: String, nullable: true },
|
|
19
|
+
breadcrumbs: { type: String, nullable: true },
|
|
19
20
|
createdAt: { type: Date },
|
|
20
21
|
updatedAt: { type: Date },
|
|
21
22
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"log.entity.js","sourceRoot":"","sources":["../../src/entities/log.entity.ts"],"names":[],"mappings":";;AAEA,
|
|
1
|
+
{"version":3,"file":"log.entity.js","sourceRoot":"","sources":["../../src/entities/log.entity.ts"],"names":[],"mappings":";;AAEA,0CAmBC;AArBD,qCAAuC;AAEvC,SAAgB,eAAe,CAAC,IAAY;IAC1C,OAAO,IAAI,sBAAY,CAAC;QACtB,IAAI;QACJ,OAAO,EAAE;YACP,GAAG,EAAE;gBACH,IAAI,EAAE,MAAM;gBACZ,QAAQ,EAAE,IAAI;gBACd,OAAO,EAAE,IAAI;aACd;YACD,IAAI,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE;YACtB,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE;YACzB,KAAK,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,EAAE;YACnC,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE;YACzC,KAAK,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE;YACvC,WAAW,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE;YAC7C,SAAS,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE;YACzB,SAAS,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE;SAC1B;KACF,CAAC,CAAC;AACL,CAAC"}
|
package/dist/log.interceptor.js
CHANGED
|
@@ -23,12 +23,13 @@ let LogInterceptor = class LogInterceptor {
|
|
|
23
23
|
intercept(context, next) {
|
|
24
24
|
return next.handle().pipe((0, rxjs_1.tap)({
|
|
25
25
|
error: (error) => {
|
|
26
|
-
var _a;
|
|
27
|
-
// error handler
|
|
26
|
+
var _a, _b;
|
|
28
27
|
(_a = this.logService) === null || _a === void 0 ? void 0 : _a.error(error.message, error.stack, context);
|
|
28
|
+
(_b = this.logService) === null || _b === void 0 ? void 0 : _b.clearBreadcrumbs();
|
|
29
29
|
},
|
|
30
30
|
complete: () => {
|
|
31
|
-
|
|
31
|
+
var _a;
|
|
32
|
+
(_a = this.logService) === null || _a === void 0 ? void 0 : _a.clearBreadcrumbs();
|
|
32
33
|
},
|
|
33
34
|
}));
|
|
34
35
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"log.interceptor.js","sourceRoot":"","sources":["../src/log.interceptor.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AACA,2CAAoD;AACpD,+BAAuC;AACvC,wDAAoD;AAI7C,IAAM,cAAc,GAApB,MAAM,cAAc;IACzB,YAAiD,UAAsB;QAAtB,eAAU,GAAV,UAAU,CAAY;IAAG,CAAC;IAE3E,SAAS,CAAC,OAA6B,EAAE,IAAiB;QACxD,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,CACvB,IAAA,UAAG,EAAC;YACF,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE;;gBACf,
|
|
1
|
+
{"version":3,"file":"log.interceptor.js","sourceRoot":"","sources":["../src/log.interceptor.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AACA,2CAAoD;AACpD,+BAAuC;AACvC,wDAAoD;AAI7C,IAAM,cAAc,GAApB,MAAM,cAAc;IACzB,YAAiD,UAAsB;QAAtB,eAAU,GAAV,UAAU,CAAY;IAAG,CAAC;IAE3E,SAAS,CAAC,OAA6B,EAAE,IAAiB;QACxD,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,CACvB,IAAA,UAAG,EAAC;YACF,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE;;gBACf,MAAA,IAAI,CAAC,UAAU,0CAAE,KAAK,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;gBAC5D,MAAA,IAAI,CAAC,UAAU,0CAAE,gBAAgB,EAAE,CAAC;YACtC,CAAC;YACD,QAAQ,EAAE,GAAG,EAAE;;gBACb,MAAA,IAAI,CAAC,UAAU,0CAAE,gBAAgB,EAAE,CAAC;YACtC,CAAC;SACF,CAAC,CACH,CAAC;IACJ,CAAC;CACF,CAAA;AAhBY,wCAAc;yBAAd,cAAc;IAD1B,IAAA,mBAAU,GAAE;IAEE,WAAA,IAAA,eAAM,EAAC,wBAAU,CAAC,CAAA;qCAA8B,wBAAU;GAD5D,cAAc,CAgB1B"}
|
|
@@ -10,8 +10,11 @@ export declare class LogService implements LoggerService {
|
|
|
10
10
|
static options: LogModuleOptions;
|
|
11
11
|
static Log: EntitySchema;
|
|
12
12
|
static timer: ReturnType<typeof setInterval>;
|
|
13
|
+
breadcrumbs: any[];
|
|
13
14
|
constructor(memoryDbService: MemoryDbService);
|
|
14
15
|
connectDb(options: LogModuleOptions): Promise<DataSource>;
|
|
16
|
+
addBreadcrumb(breadcrumb: any): void;
|
|
17
|
+
clearBreadcrumbs(): void;
|
|
15
18
|
log(message: string, context?: ExecutionContextHost): void;
|
|
16
19
|
error(message: string, trace?: string, context?: ExecutionContextHost): void;
|
|
17
20
|
warn(message: string, context?: ExecutionContextHost): void;
|
|
@@ -21,6 +21,7 @@ const timers_1 = require("timers");
|
|
|
21
21
|
let LogService = LogService_1 = class LogService {
|
|
22
22
|
constructor(memoryDbService) {
|
|
23
23
|
this.memoryDbService = memoryDbService;
|
|
24
|
+
this.breadcrumbs = [];
|
|
24
25
|
}
|
|
25
26
|
async connectDb(options) {
|
|
26
27
|
var _a, _b, _c, _d, _e, _f;
|
|
@@ -41,6 +42,12 @@ let LogService = LogService_1 = class LogService {
|
|
|
41
42
|
LogService_1.timer = (0, timers_1.setInterval)(this.checkRecords, 1000 * 60 * 60); // check one time per hour
|
|
42
43
|
return LogService_1.connection;
|
|
43
44
|
}
|
|
45
|
+
addBreadcrumb(breadcrumb) {
|
|
46
|
+
this.breadcrumbs.push(breadcrumb);
|
|
47
|
+
}
|
|
48
|
+
clearBreadcrumbs() {
|
|
49
|
+
this.breadcrumbs = [];
|
|
50
|
+
}
|
|
44
51
|
log(message, context) {
|
|
45
52
|
this.smartInsert({
|
|
46
53
|
type: types_1.LogType.LOG,
|
|
@@ -88,6 +95,7 @@ let LogService = LogService_1 = class LogService {
|
|
|
88
95
|
"updatedAt",
|
|
89
96
|
"context",
|
|
90
97
|
"trace",
|
|
98
|
+
"breadcrumbs",
|
|
91
99
|
],
|
|
92
100
|
order: { updatedAt: "DESC" },
|
|
93
101
|
});
|
|
@@ -107,6 +115,7 @@ let LogService = LogService_1 = class LogService {
|
|
|
107
115
|
return await connection.update(LogService_1.Log, log._id, {
|
|
108
116
|
context,
|
|
109
117
|
trace: data.trace,
|
|
118
|
+
breadcrumbs: this.breadcrumbs,
|
|
110
119
|
count: log.count + 1,
|
|
111
120
|
updatedAt: currentDate,
|
|
112
121
|
});
|
|
@@ -116,6 +125,7 @@ let LogService = LogService_1 = class LogService {
|
|
|
116
125
|
message: data.message,
|
|
117
126
|
context,
|
|
118
127
|
trace: data.trace,
|
|
128
|
+
breadcrumbs: this.breadcrumbs,
|
|
119
129
|
count: 1,
|
|
120
130
|
createdAt: currentDate,
|
|
121
131
|
updatedAt: currentDate,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"log.service.js","sourceRoot":"","sources":["../../src/services/log.service.ts"],"names":[],"mappings":";;;;;;;;;;;;;AAAA,2CAAkE;AAClE,2DAAsD;AACtD,0CAA2C;AAC3C,oCAA8D;AAC9D,qCAKiB;AACjB,uDAAyD;AAEzD,mCAAqC;AAG9B,IAAM,UAAU,kBAAhB,MAAM,UAAU;
|
|
1
|
+
{"version":3,"file":"log.service.js","sourceRoot":"","sources":["../../src/services/log.service.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/public/index.html
CHANGED
|
@@ -41,6 +41,7 @@
|
|
|
41
41
|
<li class="verbose" data-selector="verbose">Verbose</li>
|
|
42
42
|
</ul>
|
|
43
43
|
</nav>
|
|
44
|
+
<input id="search" onkeyup="search(event)" type="text" placeholder="Search" />
|
|
44
45
|
<div onclick="getLogs()"><button class="white">Refresh</button></div>
|
|
45
46
|
</div>
|
|
46
47
|
<div class="container table-header">
|
package/public/scripts/common.js
CHANGED
|
@@ -10,6 +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
14
|
|
|
14
15
|
window.addEventListener("load", async () => {
|
|
15
16
|
getLogs();
|
|
@@ -37,7 +38,7 @@ document.addEventListener(`click`, (e) => {
|
|
|
37
38
|
});
|
|
38
39
|
}
|
|
39
40
|
|
|
40
|
-
|
|
41
|
+
renderLogs();
|
|
41
42
|
|
|
42
43
|
return;
|
|
43
44
|
}
|
|
@@ -124,7 +125,7 @@ function getLogHtmlElement(log) {
|
|
|
124
125
|
<div id="${log._id}" class="row">
|
|
125
126
|
<div class="col ${getTypeClass(log.type)}">${log.type}</div>
|
|
126
127
|
<div class="col">
|
|
127
|
-
<div>${log.message}</div>
|
|
128
|
+
<div class="log-info">${log.message}</div>
|
|
128
129
|
<div class="date">${getDate(log.updatedAt)}</div>
|
|
129
130
|
</div>
|
|
130
131
|
<div class="col context">${log.trace || ""}</div>
|
|
@@ -132,14 +133,37 @@ function getLogHtmlElement(log) {
|
|
|
132
133
|
</div>`;
|
|
133
134
|
}
|
|
134
135
|
|
|
136
|
+
function renderLogs() {
|
|
137
|
+
let html = "";
|
|
138
|
+
|
|
139
|
+
logs
|
|
140
|
+
.filter((log) => {
|
|
141
|
+
return selectedLogTypes["all"] || selectedLogTypes[log.type];
|
|
142
|
+
})
|
|
143
|
+
.filter((log) => {
|
|
144
|
+
if (text === "") return true;
|
|
145
|
+
|
|
146
|
+
return (
|
|
147
|
+
log.message.toLowerCase().includes(text) ||
|
|
148
|
+
log.trace?.toLowerCase().includes(text) ||
|
|
149
|
+
JSON.stringify(log.context || {})
|
|
150
|
+
.toLowerCase()
|
|
151
|
+
.includes(text)
|
|
152
|
+
);
|
|
153
|
+
})
|
|
154
|
+
.forEach((log) => {
|
|
155
|
+
html += getLogHtmlElement(log);
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
document.getElementById("logs").innerHTML = html;
|
|
159
|
+
}
|
|
160
|
+
|
|
135
161
|
async function getLogs() {
|
|
136
162
|
const { origin, pathname, search } = window.location;
|
|
137
163
|
const res = await fetch(`${origin}${pathname}api${search}`);
|
|
138
164
|
|
|
139
165
|
if (res.ok) {
|
|
140
|
-
logs =
|
|
141
|
-
return selectedLogTypes["all"] || selectedLogTypes[log.type];
|
|
142
|
-
});
|
|
166
|
+
logs = await res.json();
|
|
143
167
|
|
|
144
168
|
if (logs.length === 0) {
|
|
145
169
|
document.getElementById("no-logs").style.display = "block";
|
|
@@ -151,12 +175,12 @@ async function getLogs() {
|
|
|
151
175
|
document.querySelector("nav").style.display = "flex";
|
|
152
176
|
}
|
|
153
177
|
|
|
154
|
-
|
|
178
|
+
renderLogs();
|
|
179
|
+
}
|
|
180
|
+
}
|
|
155
181
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
});
|
|
182
|
+
function search(event) {
|
|
183
|
+
text = event.target.value.toLowerCase();
|
|
159
184
|
|
|
160
|
-
|
|
161
|
-
}
|
|
185
|
+
renderLogs();
|
|
162
186
|
}
|
|
@@ -3,25 +3,33 @@ function showLogDetails(log) {
|
|
|
3
3
|
|
|
4
4
|
popup.innerHTML = `
|
|
5
5
|
<div class="content center">
|
|
6
|
-
<div class="container
|
|
7
|
-
<h2 class="${log.type}">${log.type}: ${log.message}</h2>
|
|
8
|
-
<
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
6
|
+
<div class="container">
|
|
7
|
+
<h2 class="popup-title ${log.type}">${log.type}: ${log.message}</h2>
|
|
8
|
+
<div class="mt-05">${getDate(log.updatedAt)}</div>
|
|
9
|
+
${
|
|
10
|
+
log.trace
|
|
11
|
+
? `
|
|
12
|
+
<h3 class="mt-15">Trace</h3>
|
|
13
|
+
<p class="key pl-2"><span>${getTrace(log.trace)}</span></p>
|
|
14
|
+
`
|
|
15
|
+
: ""
|
|
16
|
+
}
|
|
17
17
|
${
|
|
18
18
|
log.context
|
|
19
19
|
? `
|
|
20
|
-
<h3 class="mt-
|
|
20
|
+
<h3 class="mt-15">Context</h3>
|
|
21
21
|
<p>${jsonViewer(log.context)}</p>
|
|
22
22
|
`
|
|
23
23
|
: ""
|
|
24
24
|
}
|
|
25
|
+
${
|
|
26
|
+
log.breadcrumbs && log.breadcrumbs.length > 0
|
|
27
|
+
? `
|
|
28
|
+
<h3 class="mt-15">Breadcrumbs</h3>
|
|
29
|
+
<p>${jsonViewer(log.breadcrumbs)}</p>
|
|
30
|
+
`
|
|
31
|
+
: ""
|
|
32
|
+
}
|
|
25
33
|
<button class="white mt-2" onclick="closePopup()">Close</button>
|
|
26
34
|
</div>
|
|
27
35
|
<div>`;
|
|
@@ -5,11 +5,22 @@ function jsonViewer(json, parentKey) {
|
|
|
5
5
|
|
|
6
6
|
res = `<div>`;
|
|
7
7
|
|
|
8
|
-
if (
|
|
9
|
-
|
|
8
|
+
if (Array.isArray(json)) {
|
|
9
|
+
json.forEach((item) => {
|
|
10
|
+
res += `<div class="key pl-2">${
|
|
11
|
+
typeof item === "object" ? jsonViewer(item) : `<span>${item}</span>`
|
|
12
|
+
}</div>`;
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
return res;
|
|
10
16
|
}
|
|
11
17
|
|
|
12
18
|
const keys = Object.keys(json);
|
|
19
|
+
const showParentKey = parentKey && keys.length > 0; // hide an empty object
|
|
20
|
+
|
|
21
|
+
if (showParentKey) {
|
|
22
|
+
res += `<div class="pl-2"><div>▾ ${parentKey}</div>`;
|
|
23
|
+
}
|
|
13
24
|
|
|
14
25
|
for (const key of keys) {
|
|
15
26
|
if (typeof json[key] === "object") {
|
|
@@ -19,7 +30,7 @@ function jsonViewer(json, parentKey) {
|
|
|
19
30
|
}
|
|
20
31
|
}
|
|
21
32
|
|
|
22
|
-
if (
|
|
33
|
+
if (showParentKey) {
|
|
23
34
|
res += `</div>`;
|
|
24
35
|
}
|
|
25
36
|
|
package/public/styles/index.css
CHANGED
|
@@ -3,6 +3,7 @@ body {
|
|
|
3
3
|
background-color: var(--white);
|
|
4
4
|
color: black;
|
|
5
5
|
font-family: Verdana, sans-serif;
|
|
6
|
+
font-size: 14px;
|
|
6
7
|
display: flex;
|
|
7
8
|
flex-direction: column;
|
|
8
9
|
align-items: center;
|
|
@@ -11,19 +12,19 @@ body {
|
|
|
11
12
|
}
|
|
12
13
|
|
|
13
14
|
h1 {
|
|
14
|
-
font-size: 2.
|
|
15
|
+
font-size: 2.6rem;
|
|
15
16
|
font-weight: 400;
|
|
16
17
|
line-height: 3rem;
|
|
17
18
|
}
|
|
18
19
|
|
|
19
20
|
h2 {
|
|
20
|
-
font-size: 1.
|
|
21
|
+
font-size: 1.4rem;
|
|
21
22
|
font-weight: 400;
|
|
22
|
-
line-height:
|
|
23
|
+
line-height: 1.8rem;
|
|
23
24
|
}
|
|
24
25
|
|
|
25
26
|
h3 {
|
|
26
|
-
font-size: 1.
|
|
27
|
+
font-size: 1.1rem;
|
|
27
28
|
font-weight: 400;
|
|
28
29
|
line-height: 2rem;
|
|
29
30
|
}
|
|
@@ -162,19 +163,33 @@ nav ul li:hover {
|
|
|
162
163
|
}
|
|
163
164
|
|
|
164
165
|
/* margins and paddings */
|
|
166
|
+
.mt-05 {
|
|
167
|
+
margin-top: 0.5rem;
|
|
168
|
+
}
|
|
169
|
+
.mt-1 {
|
|
170
|
+
margin-top: 1rem;
|
|
171
|
+
}
|
|
172
|
+
.mt-15 {
|
|
173
|
+
margin-top: 1.5rem;
|
|
174
|
+
}
|
|
165
175
|
.mt-2 {
|
|
166
176
|
margin-top: 2rem;
|
|
167
177
|
}
|
|
168
|
-
|
|
169
178
|
.mt-3 {
|
|
170
179
|
margin-top: 3rem;
|
|
171
180
|
}
|
|
172
|
-
|
|
173
181
|
.pl-2 {
|
|
174
182
|
box-sizing: border-box;
|
|
175
183
|
padding-left: 2rem;
|
|
176
184
|
}
|
|
177
185
|
|
|
186
|
+
#search {
|
|
187
|
+
outline: none;
|
|
188
|
+
padding: 0.5rem;
|
|
189
|
+
border: 1px solid var(--light);
|
|
190
|
+
font-size: 1rem;
|
|
191
|
+
}
|
|
192
|
+
|
|
178
193
|
/* table */
|
|
179
194
|
.table-header,
|
|
180
195
|
.row {
|
|
@@ -185,10 +200,10 @@ nav ul li:hover {
|
|
|
185
200
|
align-items: center;
|
|
186
201
|
justify-content: space-around;
|
|
187
202
|
}
|
|
188
|
-
|
|
189
203
|
.table-header {
|
|
190
|
-
display:
|
|
204
|
+
display: flex;
|
|
191
205
|
height: 2rem;
|
|
206
|
+
justify-content: space-between;
|
|
192
207
|
background-color: var(--dark);
|
|
193
208
|
color: var(--white);
|
|
194
209
|
margin-top: 0.5rem;
|
|
@@ -203,12 +218,10 @@ nav ul li:hover {
|
|
|
203
218
|
flex: 0 0 5rem;
|
|
204
219
|
text-align: center;
|
|
205
220
|
}
|
|
206
|
-
|
|
207
|
-
.table-header > :nth-child(2),
|
|
208
221
|
.row > :nth-child(2) {
|
|
209
|
-
flex: 0 0
|
|
222
|
+
flex: 0 0 auto;
|
|
223
|
+
max-width: 35rem;
|
|
210
224
|
}
|
|
211
|
-
.table-header > :nth-child(3),
|
|
212
225
|
.row > :nth-child(3) {
|
|
213
226
|
flex: 1 1 auto;
|
|
214
227
|
}
|
|
@@ -239,7 +252,6 @@ nav ul li:hover {
|
|
|
239
252
|
}
|
|
240
253
|
|
|
241
254
|
.context {
|
|
242
|
-
font-size: small;
|
|
243
255
|
color: var(--dark);
|
|
244
256
|
display: -webkit-box;
|
|
245
257
|
-webkit-box-orient: vertical;
|
|
@@ -247,10 +259,20 @@ nav ul li:hover {
|
|
|
247
259
|
-webkit-line-clamp: 2;
|
|
248
260
|
overflow: hidden;
|
|
249
261
|
text-overflow: ellipsis;
|
|
250
|
-
max-height: 2.
|
|
262
|
+
max-height: 2.7rem;
|
|
251
263
|
margin-top: -1rem;
|
|
252
264
|
}
|
|
253
265
|
|
|
266
|
+
.log-info {
|
|
267
|
+
display: -webkit-box;
|
|
268
|
+
-webkit-box-orient: vertical;
|
|
269
|
+
line-clamp: 1;
|
|
270
|
+
-webkit-line-clamp: 1;
|
|
271
|
+
overflow: hidden;
|
|
272
|
+
text-overflow: ellipsis;
|
|
273
|
+
max-height: 1.2rem;
|
|
274
|
+
}
|
|
275
|
+
|
|
254
276
|
.date {
|
|
255
277
|
font-size: small;
|
|
256
278
|
color: var(--dark);
|
|
@@ -288,17 +310,29 @@ nav ul li:hover {
|
|
|
288
310
|
height: 100%;
|
|
289
311
|
overflow-y: scroll;
|
|
290
312
|
z-index: 1;
|
|
291
|
-
opacity: 0.
|
|
313
|
+
opacity: 0.97;
|
|
292
314
|
}
|
|
293
315
|
|
|
294
316
|
/* JSON viewer */
|
|
317
|
+
.key {
|
|
318
|
+
font-size: 0.9rem;
|
|
319
|
+
}
|
|
320
|
+
|
|
295
321
|
.key span {
|
|
296
322
|
color: var(--dark);
|
|
297
323
|
}
|
|
298
324
|
|
|
299
325
|
@media (max-width: 1620px) {
|
|
300
|
-
|
|
301
|
-
|
|
326
|
+
header button {
|
|
327
|
+
margin-right: 1rem;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
.logo {
|
|
331
|
+
margin-left: 1rem;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
.logo h2 {
|
|
335
|
+
display: none;
|
|
302
336
|
}
|
|
303
337
|
|
|
304
338
|
#popup {
|
|
@@ -14,6 +14,7 @@ export function createLogEntity(name: string) {
|
|
|
14
14
|
count: { type: Number, default: 1 },
|
|
15
15
|
context: { type: String, nullable: true },
|
|
16
16
|
trace: { type: String, nullable: true },
|
|
17
|
+
breadcrumbs: { type: String, nullable: true },
|
|
17
18
|
createdAt: { type: Date },
|
|
18
19
|
updatedAt: { type: Date },
|
|
19
20
|
},
|
package/src/log.interceptor.ts
CHANGED
|
@@ -12,11 +12,11 @@ export class LogInterceptor implements NestInterceptor {
|
|
|
12
12
|
return next.handle().pipe(
|
|
13
13
|
tap({
|
|
14
14
|
error: (error) => {
|
|
15
|
-
// error handler
|
|
16
15
|
this.logService?.error(error.message, error.stack, context);
|
|
16
|
+
this.logService?.clearBreadcrumbs();
|
|
17
17
|
},
|
|
18
18
|
complete: () => {
|
|
19
|
-
|
|
19
|
+
this.logService?.clearBreadcrumbs();
|
|
20
20
|
},
|
|
21
21
|
})
|
|
22
22
|
);
|
|
@@ -19,6 +19,8 @@ export class LogService implements LoggerService {
|
|
|
19
19
|
static Log: EntitySchema = createLogEntity(defaultTable);
|
|
20
20
|
static timer: ReturnType<typeof setInterval>;
|
|
21
21
|
|
|
22
|
+
breadcrumbs: any[] = [];
|
|
23
|
+
|
|
22
24
|
constructor(private readonly memoryDbService: MemoryDbService) {}
|
|
23
25
|
|
|
24
26
|
async connectDb(options: LogModuleOptions): Promise<DataSource> {
|
|
@@ -49,6 +51,14 @@ export class LogService implements LoggerService {
|
|
|
49
51
|
return LogService.connection;
|
|
50
52
|
}
|
|
51
53
|
|
|
54
|
+
addBreadcrumb(breadcrumb: any) {
|
|
55
|
+
this.breadcrumbs.push(breadcrumb);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
clearBreadcrumbs() {
|
|
59
|
+
this.breadcrumbs = [];
|
|
60
|
+
}
|
|
61
|
+
|
|
52
62
|
log(message: string, context?: ExecutionContextHost) {
|
|
53
63
|
this.smartInsert({
|
|
54
64
|
type: LogType.LOG,
|
|
@@ -101,6 +111,7 @@ export class LogService implements LoggerService {
|
|
|
101
111
|
"updatedAt",
|
|
102
112
|
"context",
|
|
103
113
|
"trace",
|
|
114
|
+
"breadcrumbs",
|
|
104
115
|
],
|
|
105
116
|
order: { updatedAt: "DESC" },
|
|
106
117
|
});
|
|
@@ -130,6 +141,7 @@ export class LogService implements LoggerService {
|
|
|
130
141
|
return await connection.update(LogService.Log, log._id, {
|
|
131
142
|
context,
|
|
132
143
|
trace: data.trace,
|
|
144
|
+
breadcrumbs: this.breadcrumbs,
|
|
133
145
|
count: log.count + 1,
|
|
134
146
|
updatedAt: currentDate,
|
|
135
147
|
});
|
|
@@ -140,6 +152,7 @@ export class LogService implements LoggerService {
|
|
|
140
152
|
message: data.message,
|
|
141
153
|
context,
|
|
142
154
|
trace: data.trace,
|
|
155
|
+
breadcrumbs: this.breadcrumbs,
|
|
143
156
|
count: 1,
|
|
144
157
|
createdAt: currentDate,
|
|
145
158
|
updatedAt: currentDate,
|