@pallasoft/ps-utilities 2.20.0 → 2.21.0
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/dist/edge-logs/edge-log-level.d.ts +5 -0
- package/dist/edge-logs/edge-log-level.js +9 -0
- package/dist/edge-logs/edge-logs-config.d.ts +30 -0
- package/dist/edge-logs/edge-logs-config.js +35 -0
- package/dist/edge-logs/edge-logs-service.d.ts +22 -0
- package/dist/edge-logs/edge-logs-service.js +208 -0
- package/dist/edge-logs/index.d.ts +11 -0
- package/dist/edge-logs/index.js +19 -0
- package/dist/esm/edge-logs/edge-log-level.js +6 -0
- package/dist/esm/edge-logs/edge-logs-config.js +31 -0
- package/dist/esm/edge-logs/edge-logs-service.js +149 -0
- package/dist/esm/edge-logs/index.js +3 -0
- package/dist/esm/models/edge-log-attribute-value.js +1 -0
- package/dist/esm/models/edge-log-attribute.js +1 -0
- package/dist/esm/models/edge-log-entry.js +1 -0
- package/dist/esm/models/edge-log-options.js +1 -0
- package/dist/esm/models/edge-log-payload.js +1 -0
- package/dist/esm/models/edge-log-record.js +1 -0
- package/dist/esm/models/edge-log-resource-logs.js +1 -0
- package/dist/esm/models/edge-log-scope-logs.js +1 -0
- package/dist/models/edge-log-attribute-value.d.ts +6 -0
- package/dist/models/edge-log-attribute-value.js +2 -0
- package/dist/models/edge-log-attribute.d.ts +5 -0
- package/dist/models/edge-log-attribute.js +2 -0
- package/dist/models/edge-log-entry.d.ts +7 -0
- package/dist/models/edge-log-entry.js +2 -0
- package/dist/models/edge-log-options.d.ts +8 -0
- package/dist/models/edge-log-options.js +2 -0
- package/dist/models/edge-log-payload.d.ts +4 -0
- package/dist/models/edge-log-payload.js +2 -0
- package/dist/models/edge-log-record.d.ts +9 -0
- package/dist/models/edge-log-record.js +2 -0
- package/dist/models/edge-log-resource-logs.d.ts +8 -0
- package/dist/models/edge-log-resource-logs.js +2 -0
- package/dist/models/edge-log-scope-logs.d.ts +7 -0
- package/dist/models/edge-log-scope-logs.js +2 -0
- package/package.json +10 -1
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.EdgeLogLevel = void 0;
|
|
4
|
+
var EdgeLogLevel;
|
|
5
|
+
(function (EdgeLogLevel) {
|
|
6
|
+
EdgeLogLevel["Info"] = "INFO";
|
|
7
|
+
EdgeLogLevel["Warn"] = "WARN";
|
|
8
|
+
EdgeLogLevel["Error"] = "ERROR";
|
|
9
|
+
})(EdgeLogLevel || (exports.EdgeLogLevel = EdgeLogLevel = {}));
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export declare const EdgeLogsConfig: {
|
|
2
|
+
readonly bearerPattern: RegExp;
|
|
3
|
+
readonly defaultEnvironment: "development";
|
|
4
|
+
readonly defaultScheme: "https://";
|
|
5
|
+
readonly emailPattern: RegExp;
|
|
6
|
+
readonly flushTimeoutMilliseconds: 5000;
|
|
7
|
+
readonly maxBufferedEntries: 200;
|
|
8
|
+
readonly maxDepth: 3;
|
|
9
|
+
readonly maxTextLength: 2000;
|
|
10
|
+
readonly nanosPerMillisecondSuffix: "000000";
|
|
11
|
+
readonly offValues: readonly ["", "_"];
|
|
12
|
+
readonly queryPattern: RegExp;
|
|
13
|
+
readonly redactedValue: "[redacted]";
|
|
14
|
+
readonly resourceKeys: {
|
|
15
|
+
readonly environment: "deployment.environment";
|
|
16
|
+
readonly serviceName: "service.name";
|
|
17
|
+
readonly serviceNamespace: "service.namespace";
|
|
18
|
+
readonly serviceVersion: "service.version";
|
|
19
|
+
};
|
|
20
|
+
readonly scopeName: "ps-utilities.edge-logs";
|
|
21
|
+
readonly schemePattern: RegExp;
|
|
22
|
+
readonly sensitiveKeyPattern: RegExp;
|
|
23
|
+
readonly severityNumbers: {
|
|
24
|
+
readonly INFO: 9;
|
|
25
|
+
readonly WARN: 13;
|
|
26
|
+
readonly ERROR: 17;
|
|
27
|
+
};
|
|
28
|
+
readonly signalPath: "/v1/logs";
|
|
29
|
+
readonly trailingSlashesPattern: RegExp;
|
|
30
|
+
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var _a;
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.EdgeLogsConfig = void 0;
|
|
5
|
+
var edge_log_level_1 = require("./edge-log-level");
|
|
6
|
+
exports.EdgeLogsConfig = {
|
|
7
|
+
bearerPattern: /Bearer\s+[A-Za-z0-9._~+/=-]+/gi,
|
|
8
|
+
defaultEnvironment: 'development',
|
|
9
|
+
defaultScheme: 'https://',
|
|
10
|
+
emailPattern: /[^\s@"']+@[^\s@"']+\.[^\s@"']+/g,
|
|
11
|
+
flushTimeoutMilliseconds: 5000,
|
|
12
|
+
maxBufferedEntries: 200,
|
|
13
|
+
maxDepth: 3,
|
|
14
|
+
maxTextLength: 2000,
|
|
15
|
+
nanosPerMillisecondSuffix: '000000',
|
|
16
|
+
offValues: ['', '_'],
|
|
17
|
+
queryPattern: /(https?:\/\/[^\s?#"']+|\/[^\s?#"']*)\?[^\s#"']*/g,
|
|
18
|
+
redactedValue: '[redacted]',
|
|
19
|
+
resourceKeys: {
|
|
20
|
+
environment: 'deployment.environment',
|
|
21
|
+
serviceName: 'service.name',
|
|
22
|
+
serviceNamespace: 'service.namespace',
|
|
23
|
+
serviceVersion: 'service.version',
|
|
24
|
+
},
|
|
25
|
+
scopeName: 'ps-utilities.edge-logs',
|
|
26
|
+
schemePattern: /^[a-z][a-z0-9+.-]*:\/\//i,
|
|
27
|
+
sensitiveKeyPattern: /token|secret|password|passwd|authorization|cookie|credential|api[-_]?key|email|body|session|phone|header/i,
|
|
28
|
+
severityNumbers: (_a = {},
|
|
29
|
+
_a[edge_log_level_1.EdgeLogLevel.Info] = 9,
|
|
30
|
+
_a[edge_log_level_1.EdgeLogLevel.Warn] = 13,
|
|
31
|
+
_a[edge_log_level_1.EdgeLogLevel.Error] = 17,
|
|
32
|
+
_a),
|
|
33
|
+
signalPath: '/v1/logs',
|
|
34
|
+
trailingSlashesPattern: /\/+$/,
|
|
35
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { EdgeLogEntry } from '../models/edge-log-entry';
|
|
2
|
+
import type { EdgeLogOptions } from '../models/edge-log-options';
|
|
3
|
+
import type { EdgeLogPayload } from '../models/edge-log-payload';
|
|
4
|
+
import type { EdgeLogRecord } from '../models/edge-log-record';
|
|
5
|
+
export declare class EdgeLogsService {
|
|
6
|
+
private static buffer;
|
|
7
|
+
static isOff(value: string | undefined): boolean;
|
|
8
|
+
static baseUrl(host: string | undefined): string | null;
|
|
9
|
+
static endpoint(host: string | undefined): string | null;
|
|
10
|
+
static isEnabled(options: EdgeLogOptions): boolean;
|
|
11
|
+
static enqueue(options: EdgeLogOptions, entry: EdgeLogEntry): boolean;
|
|
12
|
+
static pending(): number;
|
|
13
|
+
static reset(): void;
|
|
14
|
+
static flush(options: EdgeLogOptions): Promise<boolean>;
|
|
15
|
+
static payload(options: EdgeLogOptions, entries: EdgeLogEntry[]): EdgeLogPayload;
|
|
16
|
+
static record(entry: EdgeLogEntry): EdgeLogRecord;
|
|
17
|
+
static sanitize(source: Record<string, unknown>, depth?: number): Record<string, unknown>;
|
|
18
|
+
static text(value: string): string;
|
|
19
|
+
private static value;
|
|
20
|
+
private static attribute;
|
|
21
|
+
private static attributeValue;
|
|
22
|
+
}
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
12
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
13
|
+
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
14
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
15
|
+
function step(op) {
|
|
16
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
17
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
18
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
19
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
20
|
+
switch (op[0]) {
|
|
21
|
+
case 0: case 1: t = op; break;
|
|
22
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
23
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
24
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
25
|
+
default:
|
|
26
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
27
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
28
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
29
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
30
|
+
if (t[2]) _.ops.pop();
|
|
31
|
+
_.trys.pop(); continue;
|
|
32
|
+
}
|
|
33
|
+
op = body.call(thisArg, _);
|
|
34
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
35
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.EdgeLogsService = void 0;
|
|
40
|
+
var http_auth_scheme_1 = require("../common/constants/http-auth-scheme");
|
|
41
|
+
var http_content_type_1 = require("../common/constants/http-content-type");
|
|
42
|
+
var http_header_1 = require("../common/constants/http-header");
|
|
43
|
+
var http_method_1 = require("../common/constants/http-method");
|
|
44
|
+
var edge_logs_config_1 = require("./edge-logs-config");
|
|
45
|
+
var EdgeLogsService = /** @class */ (function () {
|
|
46
|
+
function EdgeLogsService() {
|
|
47
|
+
}
|
|
48
|
+
EdgeLogsService.isOff = function (value) {
|
|
49
|
+
if (typeof value !== 'string')
|
|
50
|
+
return true;
|
|
51
|
+
return edge_logs_config_1.EdgeLogsConfig.offValues.includes(value.trim());
|
|
52
|
+
};
|
|
53
|
+
EdgeLogsService.baseUrl = function (host) {
|
|
54
|
+
if (EdgeLogsService.isOff(host))
|
|
55
|
+
return null;
|
|
56
|
+
var trimmed = host.trim().replace(edge_logs_config_1.EdgeLogsConfig.trailingSlashesPattern, '');
|
|
57
|
+
var withScheme = edge_logs_config_1.EdgeLogsConfig.schemePattern.test(trimmed)
|
|
58
|
+
? trimmed
|
|
59
|
+
: "".concat(edge_logs_config_1.EdgeLogsConfig.defaultScheme).concat(trimmed);
|
|
60
|
+
return URL.canParse(withScheme) ? withScheme : null;
|
|
61
|
+
};
|
|
62
|
+
EdgeLogsService.endpoint = function (host) {
|
|
63
|
+
var base = EdgeLogsService.baseUrl(host);
|
|
64
|
+
return base === null ? null : "".concat(base).concat(edge_logs_config_1.EdgeLogsConfig.signalPath);
|
|
65
|
+
};
|
|
66
|
+
EdgeLogsService.isEnabled = function (options) {
|
|
67
|
+
return EdgeLogsService.endpoint(options.host) !== null && !EdgeLogsService.isOff(options.token);
|
|
68
|
+
};
|
|
69
|
+
EdgeLogsService.enqueue = function (options, entry) {
|
|
70
|
+
if (!EdgeLogsService.isEnabled(options))
|
|
71
|
+
return false;
|
|
72
|
+
EdgeLogsService.buffer.push(entry);
|
|
73
|
+
if (EdgeLogsService.buffer.length > edge_logs_config_1.EdgeLogsConfig.maxBufferedEntries)
|
|
74
|
+
EdgeLogsService.buffer.shift();
|
|
75
|
+
return true;
|
|
76
|
+
};
|
|
77
|
+
EdgeLogsService.pending = function () {
|
|
78
|
+
return EdgeLogsService.buffer.length;
|
|
79
|
+
};
|
|
80
|
+
EdgeLogsService.reset = function () {
|
|
81
|
+
EdgeLogsService.buffer = [];
|
|
82
|
+
};
|
|
83
|
+
EdgeLogsService.flush = function (options) {
|
|
84
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
85
|
+
var entries, url, controller, timer, response, _a;
|
|
86
|
+
var _b;
|
|
87
|
+
return __generator(this, function (_c) {
|
|
88
|
+
switch (_c.label) {
|
|
89
|
+
case 0:
|
|
90
|
+
entries = EdgeLogsService.buffer;
|
|
91
|
+
EdgeLogsService.buffer = [];
|
|
92
|
+
url = EdgeLogsService.endpoint(options.host);
|
|
93
|
+
if (entries.length === 0 || url === null || EdgeLogsService.isOff(options.token))
|
|
94
|
+
return [2 /*return*/, false];
|
|
95
|
+
controller = new AbortController();
|
|
96
|
+
timer = setTimeout(function () { return controller.abort(); }, edge_logs_config_1.EdgeLogsConfig.flushTimeoutMilliseconds);
|
|
97
|
+
_c.label = 1;
|
|
98
|
+
case 1:
|
|
99
|
+
_c.trys.push([1, 3, 4, 5]);
|
|
100
|
+
return [4 /*yield*/, fetch(url, {
|
|
101
|
+
body: JSON.stringify(EdgeLogsService.payload(options, entries)),
|
|
102
|
+
headers: (_b = {},
|
|
103
|
+
_b[http_header_1.HttpHeader.authorization] = "".concat(http_auth_scheme_1.HttpAuthScheme.bearerPrefix).concat(options.token.trim()),
|
|
104
|
+
_b[http_header_1.HttpHeader.contentType] = http_content_type_1.HttpContentType.json,
|
|
105
|
+
_b),
|
|
106
|
+
method: http_method_1.HttpMethod.Post,
|
|
107
|
+
signal: controller.signal,
|
|
108
|
+
})];
|
|
109
|
+
case 2:
|
|
110
|
+
response = _c.sent();
|
|
111
|
+
return [2 /*return*/, response.ok];
|
|
112
|
+
case 3:
|
|
113
|
+
_a = _c.sent();
|
|
114
|
+
return [2 /*return*/, false];
|
|
115
|
+
case 4:
|
|
116
|
+
clearTimeout(timer);
|
|
117
|
+
return [7 /*endfinally*/];
|
|
118
|
+
case 5: return [2 /*return*/];
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
};
|
|
123
|
+
EdgeLogsService.payload = function (options, entries) {
|
|
124
|
+
var environment = typeof options.environment === 'string' && options.environment.trim() !== ''
|
|
125
|
+
? options.environment.trim()
|
|
126
|
+
: edge_logs_config_1.EdgeLogsConfig.defaultEnvironment;
|
|
127
|
+
return {
|
|
128
|
+
resourceLogs: [
|
|
129
|
+
{
|
|
130
|
+
resource: {
|
|
131
|
+
attributes: [
|
|
132
|
+
EdgeLogsService.attribute(edge_logs_config_1.EdgeLogsConfig.resourceKeys.serviceName, options.serviceName),
|
|
133
|
+
EdgeLogsService.attribute(edge_logs_config_1.EdgeLogsConfig.resourceKeys.serviceNamespace, options.serviceNamespace),
|
|
134
|
+
EdgeLogsService.attribute(edge_logs_config_1.EdgeLogsConfig.resourceKeys.serviceVersion, options.serviceVersion),
|
|
135
|
+
EdgeLogsService.attribute(edge_logs_config_1.EdgeLogsConfig.resourceKeys.environment, environment),
|
|
136
|
+
],
|
|
137
|
+
},
|
|
138
|
+
scopeLogs: [
|
|
139
|
+
{
|
|
140
|
+
scope: { name: edge_logs_config_1.EdgeLogsConfig.scopeName },
|
|
141
|
+
logRecords: entries.map(function (entry) { return EdgeLogsService.record(entry); }),
|
|
142
|
+
},
|
|
143
|
+
],
|
|
144
|
+
},
|
|
145
|
+
],
|
|
146
|
+
};
|
|
147
|
+
};
|
|
148
|
+
EdgeLogsService.record = function (entry) {
|
|
149
|
+
var timestamp = typeof entry.timestamp === 'number' ? entry.timestamp : Date.now();
|
|
150
|
+
var attributes = EdgeLogsService.sanitize(entry.attributes === undefined ? {} : entry.attributes);
|
|
151
|
+
return {
|
|
152
|
+
attributes: Object.keys(attributes).map(function (key) {
|
|
153
|
+
return EdgeLogsService.attribute(key, attributes[key]);
|
|
154
|
+
}),
|
|
155
|
+
body: { stringValue: EdgeLogsService.text(entry.event) },
|
|
156
|
+
severityNumber: edge_logs_config_1.EdgeLogsConfig.severityNumbers[entry.level],
|
|
157
|
+
severityText: entry.level,
|
|
158
|
+
timeUnixNano: "".concat(Math.floor(timestamp)).concat(edge_logs_config_1.EdgeLogsConfig.nanosPerMillisecondSuffix),
|
|
159
|
+
};
|
|
160
|
+
};
|
|
161
|
+
EdgeLogsService.sanitize = function (source, depth) {
|
|
162
|
+
if (depth === void 0) { depth = 0; }
|
|
163
|
+
var result = {};
|
|
164
|
+
Object.keys(source).forEach(function (key) {
|
|
165
|
+
result[key] = edge_logs_config_1.EdgeLogsConfig.sensitiveKeyPattern.test(key)
|
|
166
|
+
? edge_logs_config_1.EdgeLogsConfig.redactedValue
|
|
167
|
+
: EdgeLogsService.value(source[key], depth);
|
|
168
|
+
});
|
|
169
|
+
return result;
|
|
170
|
+
};
|
|
171
|
+
EdgeLogsService.text = function (value) {
|
|
172
|
+
return value
|
|
173
|
+
.replace(edge_logs_config_1.EdgeLogsConfig.bearerPattern, edge_logs_config_1.EdgeLogsConfig.redactedValue)
|
|
174
|
+
.replace(edge_logs_config_1.EdgeLogsConfig.emailPattern, edge_logs_config_1.EdgeLogsConfig.redactedValue)
|
|
175
|
+
.replace(edge_logs_config_1.EdgeLogsConfig.queryPattern, '$1')
|
|
176
|
+
.slice(0, edge_logs_config_1.EdgeLogsConfig.maxTextLength);
|
|
177
|
+
};
|
|
178
|
+
EdgeLogsService.value = function (value, depth) {
|
|
179
|
+
if (value === null || value === undefined)
|
|
180
|
+
return '';
|
|
181
|
+
if (typeof value === 'number' || typeof value === 'boolean')
|
|
182
|
+
return value;
|
|
183
|
+
if (typeof value === 'string')
|
|
184
|
+
return EdgeLogsService.text(value);
|
|
185
|
+
if (value instanceof Error)
|
|
186
|
+
return EdgeLogsService.text("".concat(value.name, ": ").concat(value.message));
|
|
187
|
+
if (depth >= edge_logs_config_1.EdgeLogsConfig.maxDepth)
|
|
188
|
+
return edge_logs_config_1.EdgeLogsConfig.redactedValue;
|
|
189
|
+
if (Array.isArray(value))
|
|
190
|
+
return EdgeLogsService.text(JSON.stringify(value.map(function (item) { return EdgeLogsService.value(item, depth + 1); })));
|
|
191
|
+
if (typeof value === 'object')
|
|
192
|
+
return EdgeLogsService.text(JSON.stringify(EdgeLogsService.sanitize(value, depth + 1)));
|
|
193
|
+
return EdgeLogsService.text(String(value));
|
|
194
|
+
};
|
|
195
|
+
EdgeLogsService.attribute = function (key, value) {
|
|
196
|
+
return { key: key, value: EdgeLogsService.attributeValue(value) };
|
|
197
|
+
};
|
|
198
|
+
EdgeLogsService.attributeValue = function (value) {
|
|
199
|
+
if (typeof value === 'boolean')
|
|
200
|
+
return { boolValue: value };
|
|
201
|
+
if (typeof value === 'number' && Number.isFinite(value))
|
|
202
|
+
return Number.isInteger(value) ? { intValue: String(value) } : { doubleValue: value };
|
|
203
|
+
return { stringValue: String(value) };
|
|
204
|
+
};
|
|
205
|
+
EdgeLogsService.buffer = [];
|
|
206
|
+
return EdgeLogsService;
|
|
207
|
+
}());
|
|
208
|
+
exports.EdgeLogsService = EdgeLogsService;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export * from './edge-log-level';
|
|
2
|
+
export * from './edge-logs-config';
|
|
3
|
+
export * from './edge-logs-service';
|
|
4
|
+
export type { EdgeLogAttribute } from '../models/edge-log-attribute';
|
|
5
|
+
export type { EdgeLogAttributeValue } from '../models/edge-log-attribute-value';
|
|
6
|
+
export type { EdgeLogEntry } from '../models/edge-log-entry';
|
|
7
|
+
export type { EdgeLogOptions } from '../models/edge-log-options';
|
|
8
|
+
export type { EdgeLogPayload } from '../models/edge-log-payload';
|
|
9
|
+
export type { EdgeLogRecord } from '../models/edge-log-record';
|
|
10
|
+
export type { EdgeLogResourceLogs } from '../models/edge-log-resource-logs';
|
|
11
|
+
export type { EdgeLogScopeLogs } from '../models/edge-log-scope-logs';
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./edge-log-level"), exports);
|
|
18
|
+
__exportStar(require("./edge-logs-config"), exports);
|
|
19
|
+
__exportStar(require("./edge-logs-service"), exports);
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { EdgeLogLevel } from './edge-log-level.js';
|
|
2
|
+
export const EdgeLogsConfig = {
|
|
3
|
+
bearerPattern: /Bearer\s+[A-Za-z0-9._~+/=-]+/gi,
|
|
4
|
+
defaultEnvironment: 'development',
|
|
5
|
+
defaultScheme: 'https://',
|
|
6
|
+
emailPattern: /[^\s@"']+@[^\s@"']+\.[^\s@"']+/g,
|
|
7
|
+
flushTimeoutMilliseconds: 5000,
|
|
8
|
+
maxBufferedEntries: 200,
|
|
9
|
+
maxDepth: 3,
|
|
10
|
+
maxTextLength: 2000,
|
|
11
|
+
nanosPerMillisecondSuffix: '000000',
|
|
12
|
+
offValues: ['', '_'],
|
|
13
|
+
queryPattern: /(https?:\/\/[^\s?#"']+|\/[^\s?#"']*)\?[^\s#"']*/g,
|
|
14
|
+
redactedValue: '[redacted]',
|
|
15
|
+
resourceKeys: {
|
|
16
|
+
environment: 'deployment.environment',
|
|
17
|
+
serviceName: 'service.name',
|
|
18
|
+
serviceNamespace: 'service.namespace',
|
|
19
|
+
serviceVersion: 'service.version',
|
|
20
|
+
},
|
|
21
|
+
scopeName: 'ps-utilities.edge-logs',
|
|
22
|
+
schemePattern: /^[a-z][a-z0-9+.-]*:\/\//i,
|
|
23
|
+
sensitiveKeyPattern: /token|secret|password|passwd|authorization|cookie|credential|api[-_]?key|email|body|session|phone|header/i,
|
|
24
|
+
severityNumbers: {
|
|
25
|
+
[EdgeLogLevel.Info]: 9,
|
|
26
|
+
[EdgeLogLevel.Warn]: 13,
|
|
27
|
+
[EdgeLogLevel.Error]: 17,
|
|
28
|
+
},
|
|
29
|
+
signalPath: '/v1/logs',
|
|
30
|
+
trailingSlashesPattern: /\/+$/,
|
|
31
|
+
};
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { HttpAuthScheme } from '../common/constants/http-auth-scheme.js';
|
|
2
|
+
import { HttpContentType } from '../common/constants/http-content-type.js';
|
|
3
|
+
import { HttpHeader } from '../common/constants/http-header.js';
|
|
4
|
+
import { HttpMethod } from '../common/constants/http-method.js';
|
|
5
|
+
import { EdgeLogsConfig } from './edge-logs-config.js';
|
|
6
|
+
export class EdgeLogsService {
|
|
7
|
+
static isOff(value) {
|
|
8
|
+
if (typeof value !== 'string')
|
|
9
|
+
return true;
|
|
10
|
+
return EdgeLogsConfig.offValues.includes(value.trim());
|
|
11
|
+
}
|
|
12
|
+
static baseUrl(host) {
|
|
13
|
+
if (EdgeLogsService.isOff(host))
|
|
14
|
+
return null;
|
|
15
|
+
const trimmed = host.trim().replace(EdgeLogsConfig.trailingSlashesPattern, '');
|
|
16
|
+
const withScheme = EdgeLogsConfig.schemePattern.test(trimmed)
|
|
17
|
+
? trimmed
|
|
18
|
+
: `${EdgeLogsConfig.defaultScheme}${trimmed}`;
|
|
19
|
+
return URL.canParse(withScheme) ? withScheme : null;
|
|
20
|
+
}
|
|
21
|
+
static endpoint(host) {
|
|
22
|
+
const base = EdgeLogsService.baseUrl(host);
|
|
23
|
+
return base === null ? null : `${base}${EdgeLogsConfig.signalPath}`;
|
|
24
|
+
}
|
|
25
|
+
static isEnabled(options) {
|
|
26
|
+
return EdgeLogsService.endpoint(options.host) !== null && !EdgeLogsService.isOff(options.token);
|
|
27
|
+
}
|
|
28
|
+
static enqueue(options, entry) {
|
|
29
|
+
if (!EdgeLogsService.isEnabled(options))
|
|
30
|
+
return false;
|
|
31
|
+
EdgeLogsService.buffer.push(entry);
|
|
32
|
+
if (EdgeLogsService.buffer.length > EdgeLogsConfig.maxBufferedEntries)
|
|
33
|
+
EdgeLogsService.buffer.shift();
|
|
34
|
+
return true;
|
|
35
|
+
}
|
|
36
|
+
static pending() {
|
|
37
|
+
return EdgeLogsService.buffer.length;
|
|
38
|
+
}
|
|
39
|
+
static reset() {
|
|
40
|
+
EdgeLogsService.buffer = [];
|
|
41
|
+
}
|
|
42
|
+
static async flush(options) {
|
|
43
|
+
const entries = EdgeLogsService.buffer;
|
|
44
|
+
EdgeLogsService.buffer = [];
|
|
45
|
+
const url = EdgeLogsService.endpoint(options.host);
|
|
46
|
+
if (entries.length === 0 || url === null || EdgeLogsService.isOff(options.token))
|
|
47
|
+
return false;
|
|
48
|
+
const controller = new AbortController();
|
|
49
|
+
const timer = setTimeout(() => controller.abort(), EdgeLogsConfig.flushTimeoutMilliseconds);
|
|
50
|
+
try {
|
|
51
|
+
const response = await fetch(url, {
|
|
52
|
+
body: JSON.stringify(EdgeLogsService.payload(options, entries)),
|
|
53
|
+
headers: {
|
|
54
|
+
[HttpHeader.authorization]: `${HttpAuthScheme.bearerPrefix}${options.token.trim()}`,
|
|
55
|
+
[HttpHeader.contentType]: HttpContentType.json,
|
|
56
|
+
},
|
|
57
|
+
method: HttpMethod.Post,
|
|
58
|
+
signal: controller.signal,
|
|
59
|
+
});
|
|
60
|
+
return response.ok;
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
finally {
|
|
66
|
+
clearTimeout(timer);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
static payload(options, entries) {
|
|
70
|
+
const environment = typeof options.environment === 'string' && options.environment.trim() !== ''
|
|
71
|
+
? options.environment.trim()
|
|
72
|
+
: EdgeLogsConfig.defaultEnvironment;
|
|
73
|
+
return {
|
|
74
|
+
resourceLogs: [
|
|
75
|
+
{
|
|
76
|
+
resource: {
|
|
77
|
+
attributes: [
|
|
78
|
+
EdgeLogsService.attribute(EdgeLogsConfig.resourceKeys.serviceName, options.serviceName),
|
|
79
|
+
EdgeLogsService.attribute(EdgeLogsConfig.resourceKeys.serviceNamespace, options.serviceNamespace),
|
|
80
|
+
EdgeLogsService.attribute(EdgeLogsConfig.resourceKeys.serviceVersion, options.serviceVersion),
|
|
81
|
+
EdgeLogsService.attribute(EdgeLogsConfig.resourceKeys.environment, environment),
|
|
82
|
+
],
|
|
83
|
+
},
|
|
84
|
+
scopeLogs: [
|
|
85
|
+
{
|
|
86
|
+
scope: { name: EdgeLogsConfig.scopeName },
|
|
87
|
+
logRecords: entries.map((entry) => EdgeLogsService.record(entry)),
|
|
88
|
+
},
|
|
89
|
+
],
|
|
90
|
+
},
|
|
91
|
+
],
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
static record(entry) {
|
|
95
|
+
const timestamp = typeof entry.timestamp === 'number' ? entry.timestamp : Date.now();
|
|
96
|
+
const attributes = EdgeLogsService.sanitize(entry.attributes === undefined ? {} : entry.attributes);
|
|
97
|
+
return {
|
|
98
|
+
attributes: Object.keys(attributes).map((key) => EdgeLogsService.attribute(key, attributes[key])),
|
|
99
|
+
body: { stringValue: EdgeLogsService.text(entry.event) },
|
|
100
|
+
severityNumber: EdgeLogsConfig.severityNumbers[entry.level],
|
|
101
|
+
severityText: entry.level,
|
|
102
|
+
timeUnixNano: `${Math.floor(timestamp)}${EdgeLogsConfig.nanosPerMillisecondSuffix}`,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
static sanitize(source, depth = 0) {
|
|
106
|
+
const result = {};
|
|
107
|
+
Object.keys(source).forEach((key) => {
|
|
108
|
+
result[key] = EdgeLogsConfig.sensitiveKeyPattern.test(key)
|
|
109
|
+
? EdgeLogsConfig.redactedValue
|
|
110
|
+
: EdgeLogsService.value(source[key], depth);
|
|
111
|
+
});
|
|
112
|
+
return result;
|
|
113
|
+
}
|
|
114
|
+
static text(value) {
|
|
115
|
+
return value
|
|
116
|
+
.replace(EdgeLogsConfig.bearerPattern, EdgeLogsConfig.redactedValue)
|
|
117
|
+
.replace(EdgeLogsConfig.emailPattern, EdgeLogsConfig.redactedValue)
|
|
118
|
+
.replace(EdgeLogsConfig.queryPattern, '$1')
|
|
119
|
+
.slice(0, EdgeLogsConfig.maxTextLength);
|
|
120
|
+
}
|
|
121
|
+
static value(value, depth) {
|
|
122
|
+
if (value === null || value === undefined)
|
|
123
|
+
return '';
|
|
124
|
+
if (typeof value === 'number' || typeof value === 'boolean')
|
|
125
|
+
return value;
|
|
126
|
+
if (typeof value === 'string')
|
|
127
|
+
return EdgeLogsService.text(value);
|
|
128
|
+
if (value instanceof Error)
|
|
129
|
+
return EdgeLogsService.text(`${value.name}: ${value.message}`);
|
|
130
|
+
if (depth >= EdgeLogsConfig.maxDepth)
|
|
131
|
+
return EdgeLogsConfig.redactedValue;
|
|
132
|
+
if (Array.isArray(value))
|
|
133
|
+
return EdgeLogsService.text(JSON.stringify(value.map((item) => EdgeLogsService.value(item, depth + 1))));
|
|
134
|
+
if (typeof value === 'object')
|
|
135
|
+
return EdgeLogsService.text(JSON.stringify(EdgeLogsService.sanitize(value, depth + 1)));
|
|
136
|
+
return EdgeLogsService.text(String(value));
|
|
137
|
+
}
|
|
138
|
+
static attribute(key, value) {
|
|
139
|
+
return { key, value: EdgeLogsService.attributeValue(value) };
|
|
140
|
+
}
|
|
141
|
+
static attributeValue(value) {
|
|
142
|
+
if (typeof value === 'boolean')
|
|
143
|
+
return { boolValue: value };
|
|
144
|
+
if (typeof value === 'number' && Number.isFinite(value))
|
|
145
|
+
return Number.isInteger(value) ? { intValue: String(value) } : { doubleValue: value };
|
|
146
|
+
return { stringValue: String(value) };
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
EdgeLogsService.buffer = [];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { EdgeLogAttribute } from './edge-log-attribute';
|
|
2
|
+
import { EdgeLogAttributeValue } from './edge-log-attribute-value';
|
|
3
|
+
export interface EdgeLogRecord {
|
|
4
|
+
timeUnixNano: string;
|
|
5
|
+
severityNumber: number;
|
|
6
|
+
severityText: string;
|
|
7
|
+
body: EdgeLogAttributeValue;
|
|
8
|
+
attributes: EdgeLogAttribute[];
|
|
9
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pallasoft/ps-utilities",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.21.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/esm/index.js",
|
|
@@ -19,6 +19,12 @@
|
|
|
19
19
|
"require": "./dist/server/index.js",
|
|
20
20
|
"default": "./dist/server/index.js"
|
|
21
21
|
},
|
|
22
|
+
"./edge-logs": {
|
|
23
|
+
"types": "./dist/edge-logs/index.d.ts",
|
|
24
|
+
"module": "./dist/esm/edge-logs/index.js",
|
|
25
|
+
"require": "./dist/edge-logs/index.js",
|
|
26
|
+
"default": "./dist/edge-logs/index.js"
|
|
27
|
+
},
|
|
22
28
|
"./build": {
|
|
23
29
|
"types": "./dist/build/index.d.ts",
|
|
24
30
|
"require": "./dist/build/index.js",
|
|
@@ -109,6 +115,9 @@
|
|
|
109
115
|
},
|
|
110
116
|
"typesVersions": {
|
|
111
117
|
"*": {
|
|
118
|
+
"edge-logs": [
|
|
119
|
+
"dist/edge-logs/index.d.ts"
|
|
120
|
+
],
|
|
112
121
|
"server": [
|
|
113
122
|
"dist/server/index.d.ts"
|
|
114
123
|
],
|