@twin.org/logging-service 0.0.2-next.3 → 0.0.3-next.2
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/es/index.js +7 -0
- package/dist/es/index.js.map +1 -0
- package/dist/{esm/index.mjs → es/loggingRoutes.js} +7 -103
- package/dist/es/loggingRoutes.js.map +1 -0
- package/dist/es/loggingService.js +94 -0
- package/dist/es/loggingService.js.map +1 -0
- package/dist/es/models/ILoggingServiceConstructorOptions.js +4 -0
- package/dist/es/models/ILoggingServiceConstructorOptions.js.map +1 -0
- package/dist/es/restEntryPoints.js +10 -0
- package/dist/es/restEntryPoints.js.map +1 -0
- package/dist/types/index.d.ts +4 -4
- package/dist/types/loggingService.d.ts +6 -1
- package/docs/changelog.md +40 -0
- package/docs/open-api/spec.json +33 -26
- package/docs/reference/classes/LoggingService.md +18 -0
- package/package.json +6 -8
- package/dist/cjs/index.cjs +0 -249
package/dist/es/index.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// Copyright 2024 IOTA Stiftung.
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0.
|
|
3
|
+
export * from "./loggingRoutes.js";
|
|
4
|
+
export * from "./loggingService.js";
|
|
5
|
+
export * from "./models/ILoggingServiceConstructorOptions.js";
|
|
6
|
+
export * from "./restEntryPoints.js";
|
|
7
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,uCAAuC;AACvC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,+CAA+C,CAAC;AAC9D,cAAc,sBAAsB,CAAC","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nexport * from \"./loggingRoutes.js\";\nexport * from \"./loggingService.js\";\nexport * from \"./models/ILoggingServiceConstructorOptions.js\";\nexport * from \"./restEntryPoints.js\";\n"]}
|
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { HttpStatusCode } from
|
|
3
|
-
import { LogicalOperator, ComparisonOperator, SortDirection } from '@twin.org/entity';
|
|
4
|
-
import { LoggingConnectorFactory } from '@twin.org/logging-models';
|
|
5
|
-
|
|
1
|
+
import { ComponentFactory, Coerce, Guards } from "@twin.org/core";
|
|
2
|
+
import { HttpStatusCode } from "@twin.org/web";
|
|
6
3
|
/**
|
|
7
4
|
* The source used when communicating about these routes.
|
|
8
5
|
*/
|
|
@@ -10,7 +7,7 @@ const ROUTES_SOURCE = "loggingRoutes";
|
|
|
10
7
|
/**
|
|
11
8
|
* The tag to associate with the routes.
|
|
12
9
|
*/
|
|
13
|
-
const tagsLogging = [
|
|
10
|
+
export const tagsLogging = [
|
|
14
11
|
{
|
|
15
12
|
name: "Logging",
|
|
16
13
|
description: "Endpoints which are modelled to access a logging contract."
|
|
@@ -22,7 +19,7 @@ const tagsLogging = [
|
|
|
22
19
|
* @param componentName The name of the component to use in the routes stored in the ComponentFactory.
|
|
23
20
|
* @returns The generated routes.
|
|
24
21
|
*/
|
|
25
|
-
function generateRestRoutesLogging(baseRouteName, componentName) {
|
|
22
|
+
export function generateRestRoutesLogging(baseRouteName, componentName) {
|
|
26
23
|
const createRoute = {
|
|
27
24
|
operationId: "loggingEntryCreate",
|
|
28
25
|
summary: "Create a log entry",
|
|
@@ -123,7 +120,7 @@ function generateRestRoutesLogging(baseRouteName, componentName) {
|
|
|
123
120
|
* @param request The request.
|
|
124
121
|
* @returns The response object with additional http response properties.
|
|
125
122
|
*/
|
|
126
|
-
async function loggingCreate(httpRequestContext, componentName, request) {
|
|
123
|
+
export async function loggingCreate(httpRequestContext, componentName, request) {
|
|
127
124
|
Guards.object(ROUTES_SOURCE, "request", request);
|
|
128
125
|
Guards.object(ROUTES_SOURCE, "request.body", request.body);
|
|
129
126
|
const component = ComponentFactory.get(componentName);
|
|
@@ -139,104 +136,11 @@ async function loggingCreate(httpRequestContext, componentName, request) {
|
|
|
139
136
|
* @param request The request.
|
|
140
137
|
* @returns The response object with additional http response properties.
|
|
141
138
|
*/
|
|
142
|
-
async function loggingList(httpRequestContext, componentName, request) {
|
|
139
|
+
export async function loggingList(httpRequestContext, componentName, request) {
|
|
143
140
|
const component = ComponentFactory.get(componentName);
|
|
144
141
|
const itemsAndCursor = await component.query(request?.query?.level, request?.query?.source, Coerce.number(request?.query?.timeStart), Coerce.number(request?.query?.timeEnd), request?.query?.cursor, Coerce.number(request?.query?.limit));
|
|
145
142
|
return {
|
|
146
143
|
body: itemsAndCursor
|
|
147
144
|
};
|
|
148
145
|
}
|
|
149
|
-
|
|
150
|
-
// Copyright 2024 IOTA Stiftung.
|
|
151
|
-
// SPDX-License-Identifier: Apache-2.0.
|
|
152
|
-
/**
|
|
153
|
-
* Service for performing logging operations to a connector.
|
|
154
|
-
*/
|
|
155
|
-
class LoggingService {
|
|
156
|
-
/**
|
|
157
|
-
* Runtime name for the class.
|
|
158
|
-
*/
|
|
159
|
-
static CLASS_NAME = "LoggingService";
|
|
160
|
-
/**
|
|
161
|
-
* Logging connector used by the service.
|
|
162
|
-
* @internal
|
|
163
|
-
*/
|
|
164
|
-
_loggingConnector;
|
|
165
|
-
/**
|
|
166
|
-
* Create a new instance of LoggingService.
|
|
167
|
-
* @param options The options for the connector.
|
|
168
|
-
*/
|
|
169
|
-
constructor(options) {
|
|
170
|
-
this._loggingConnector = LoggingConnectorFactory.get(options?.loggingConnectorType ?? "logging");
|
|
171
|
-
}
|
|
172
|
-
/**
|
|
173
|
-
* Log an entry to the connector.
|
|
174
|
-
* @param logEntry The entry to log.
|
|
175
|
-
* @returns Nothing.
|
|
176
|
-
*/
|
|
177
|
-
async log(logEntry) {
|
|
178
|
-
Guards.object(LoggingService.CLASS_NAME, "logEntry", logEntry);
|
|
179
|
-
await this._loggingConnector.log(logEntry);
|
|
180
|
-
}
|
|
181
|
-
/**
|
|
182
|
-
* Query the log entries.
|
|
183
|
-
* @param level The level of the log entries.
|
|
184
|
-
* @param source The source of the log entries.
|
|
185
|
-
* @param timeStart The inclusive time as the start of the log entries.
|
|
186
|
-
* @param timeEnd The inclusive time as the end of the log entries.
|
|
187
|
-
* @param cursor The cursor to request the next chunk of entities.
|
|
188
|
-
* @param limit Limit the number of entities to return.
|
|
189
|
-
* @returns All the entities for the storage matching the conditions,
|
|
190
|
-
* and a cursor which can be used to request more entities.
|
|
191
|
-
*/
|
|
192
|
-
async query(level, source, timeStart, timeEnd, cursor, limit) {
|
|
193
|
-
const condition = {
|
|
194
|
-
conditions: [],
|
|
195
|
-
logicalOperator: LogicalOperator.And
|
|
196
|
-
};
|
|
197
|
-
if (Is.stringValue(level)) {
|
|
198
|
-
condition.conditions.push({
|
|
199
|
-
property: "level",
|
|
200
|
-
comparison: ComparisonOperator.Equals,
|
|
201
|
-
value: level
|
|
202
|
-
});
|
|
203
|
-
}
|
|
204
|
-
if (Is.stringValue(source)) {
|
|
205
|
-
condition.conditions.push({
|
|
206
|
-
property: "source",
|
|
207
|
-
comparison: ComparisonOperator.Equals,
|
|
208
|
-
value: source
|
|
209
|
-
});
|
|
210
|
-
}
|
|
211
|
-
if (Is.number(timeStart)) {
|
|
212
|
-
condition.conditions.push({
|
|
213
|
-
property: "ts",
|
|
214
|
-
comparison: ComparisonOperator.GreaterThanOrEqual,
|
|
215
|
-
value: timeStart
|
|
216
|
-
});
|
|
217
|
-
}
|
|
218
|
-
if (Is.number(timeEnd)) {
|
|
219
|
-
condition.conditions.push({
|
|
220
|
-
property: "ts",
|
|
221
|
-
comparison: ComparisonOperator.LessThanOrEqual,
|
|
222
|
-
value: timeEnd
|
|
223
|
-
});
|
|
224
|
-
}
|
|
225
|
-
if (Is.function(this._loggingConnector?.query)) {
|
|
226
|
-
const result = await this._loggingConnector.query(condition, [{ property: "ts", sortDirection: SortDirection.Descending }], undefined, cursor, limit);
|
|
227
|
-
return { entities: result.entities, cursor: result.cursor };
|
|
228
|
-
}
|
|
229
|
-
return { entities: [] };
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
const restEntryPoints = [
|
|
234
|
-
{
|
|
235
|
-
name: "logging",
|
|
236
|
-
defaultBaseRoute: "logging",
|
|
237
|
-
tags: tagsLogging,
|
|
238
|
-
generateRoutes: generateRestRoutesLogging
|
|
239
|
-
}
|
|
240
|
-
];
|
|
241
|
-
|
|
242
|
-
export { LoggingService, generateRestRoutesLogging, loggingCreate, loggingList, restEntryPoints, tagsLogging };
|
|
146
|
+
//# sourceMappingURL=loggingRoutes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loggingRoutes.js","sourceRoot":"","sources":["../../src/loggingRoutes.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAQlE,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAE/C;;GAEG;AACH,MAAM,aAAa,GAAG,eAAe,CAAC;AAEtC;;GAEG;AACH,MAAM,CAAC,MAAM,WAAW,GAAW;IAClC;QACC,IAAI,EAAE,SAAS;QACf,WAAW,EAAE,4DAA4D;KACzE;CACD,CAAC;AAEF;;;;;GAKG;AACH,MAAM,UAAU,yBAAyB,CACxC,aAAqB,EACrB,aAAqB;IAErB,MAAM,WAAW,GAA0D;QAC1E,WAAW,EAAE,oBAAoB;QACjC,OAAO,EAAE,oBAAoB;QAC7B,GAAG,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI;QACxB,MAAM,EAAE,MAAM;QACd,IAAI,EAAE,GAAG,aAAa,GAAG;QACzB,OAAO,EAAE,KAAK,EAAE,kBAAkB,EAAE,OAAO,EAAE,EAAE,CAC9C,aAAa,CAAC,kBAAkB,EAAE,aAAa,EAAE,OAAO,CAAC;QAC1D,WAAW,EAAE;YACZ,IAAI,yBAAiC;YACrC,QAAQ,EAAE;gBACT;oBACC,EAAE,EAAE,+BAA+B;oBACnC,OAAO,EAAE;wBACR,IAAI,EAAE;4BACL,KAAK,EAAE,MAAM;4BACb,OAAO,EAAE,gCAAgC;4BACzC,MAAM,EAAE,QAAQ;4BAChB,EAAE,EAAE,aAAa;yBACjB;qBACD;iBACD;gBACD;oBACC,EAAE,EAAE,gCAAgC;oBACpC,OAAO,EAAE;wBACR,IAAI,EAAE;4BACL,KAAK,EAAE,MAAM;4BACb,OAAO,EAAE,0BAA0B;4BACnC,MAAM,EAAE,QAAQ;4BAChB,EAAE,EAAE,aAAa;4BACjB,KAAK,EAAE;gCACN,IAAI,EAAE,cAAc;gCACpB,OAAO,EAAE,iBAAiB;gCAC1B,UAAU,EAAE;oCACX,GAAG,EAAE,KAAK;iCACV;6BACD;yBACD;qBACD;iBACD;aACD;SACD;QACD,YAAY,EAAE;YACb;gBACC,IAAI,sBAA8B;aAClC;SACD;KACD,CAAC;IAEF,MAAM,SAAS,GAA0D;QACxE,WAAW,EAAE,oBAAoB;QACjC,OAAO,EAAE,+BAA+B;QACxC,GAAG,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI;QACxB,MAAM,EAAE,KAAK;QACb,IAAI,EAAE,GAAG,aAAa,GAAG;QACzB,OAAO,EAAE,KAAK,EAAE,kBAAkB,EAAE,OAAO,EAAE,EAAE,CAC9C,WAAW,CAAC,kBAAkB,EAAE,aAAa,EAAE,OAAO,CAAC;QACxD,WAAW,EAAE;YACZ,IAAI,uBAA+B;YACnC,QAAQ,EAAE;gBACT;oBACC,EAAE,EAAE,2BAA2B;oBAC/B,OAAO,EAAE;wBACR,KAAK,EAAE;4BACN,KAAK,EAAE,MAAM;yBACb;qBACD;iBACD;aACD;SACD;QACD,YAAY,EAAE;YACb;gBACC,IAAI,wBAAgC;gBACpC,QAAQ,EAAE;oBACT;wBACC,EAAE,EAAE,qBAAqB;wBACzB,QAAQ,EAAE;4BACT,IAAI,EAAE;gCACL,QAAQ,EAAE;oCACT;wCACC,KAAK,EAAE,MAAM;wCACb,OAAO,EAAE,gCAAgC;wCACzC,MAAM,EAAE,QAAQ;wCAChB,EAAE,EAAE,aAAa;qCACjB;iCACD;gCACD,MAAM,EAAE,GAAG;6BACX;yBACD;qBACD;iBACD;aACD;SACD;KACD,CAAC;IAEF,OAAO,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;AACjC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAClC,kBAAuC,EACvC,aAAqB,EACrB,OAA8B;IAE9B,MAAM,CAAC,MAAM,CAAwB,aAAa,aAAmB,OAAO,CAAC,CAAC;IAC9E,MAAM,CAAC,MAAM,CAAgC,aAAa,kBAAwB,OAAO,CAAC,IAAI,CAAC,CAAC;IAChG,MAAM,SAAS,GAAG,gBAAgB,CAAC,GAAG,CAAoB,aAAa,CAAC,CAAC;IACzE,MAAM,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAClC,OAAO;QACN,UAAU,EAAE,cAAc,CAAC,SAAS;KACpC,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAChC,kBAAuC,EACvC,aAAqB,EACrB,OAA4B;IAE5B,MAAM,SAAS,GAAG,gBAAgB,CAAC,GAAG,CAAoB,aAAa,CAAC,CAAC;IAEzE,MAAM,cAAc,GAAG,MAAM,SAAS,CAAC,KAAK,CAC3C,OAAO,EAAE,KAAK,EAAE,KAAK,EACrB,OAAO,EAAE,KAAK,EAAE,MAAM,EACtB,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,KAAK,EAAE,SAAS,CAAC,EACxC,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,EACtC,OAAO,EAAE,KAAK,EAAE,MAAM,EACtB,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,CACpC,CAAC;IACF,OAAO;QACN,IAAI,EAAE,cAAc;KACpB,CAAC;AACH,CAAC","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport type {\n\tIHttpRequestContext,\n\tINoContentResponse,\n\tIRestRoute,\n\tITag\n} from \"@twin.org/api-models\";\nimport { ComponentFactory, Coerce, Guards } from \"@twin.org/core\";\nimport type {\n\tILoggingComponent,\n\tILoggingCreateRequest,\n\tILoggingListRequest,\n\tILoggingListResponse\n} from \"@twin.org/logging-models\";\nimport { nameof } from \"@twin.org/nameof\";\nimport { HttpStatusCode } from \"@twin.org/web\";\n\n/**\n * The source used when communicating about these routes.\n */\nconst ROUTES_SOURCE = \"loggingRoutes\";\n\n/**\n * The tag to associate with the routes.\n */\nexport const tagsLogging: ITag[] = [\n\t{\n\t\tname: \"Logging\",\n\t\tdescription: \"Endpoints which are modelled to access a logging contract.\"\n\t}\n];\n\n/**\n * The REST routes for logging.\n * @param baseRouteName Prefix to prepend to the paths.\n * @param componentName The name of the component to use in the routes stored in the ComponentFactory.\n * @returns The generated routes.\n */\nexport function generateRestRoutesLogging(\n\tbaseRouteName: string,\n\tcomponentName: string\n): IRestRoute[] {\n\tconst createRoute: IRestRoute<ILoggingCreateRequest, INoContentResponse> = {\n\t\toperationId: \"loggingEntryCreate\",\n\t\tsummary: \"Create a log entry\",\n\t\ttag: tagsLogging[0].name,\n\t\tmethod: \"POST\",\n\t\tpath: `${baseRouteName}/`,\n\t\thandler: async (httpRequestContext, request) =>\n\t\t\tloggingCreate(httpRequestContext, componentName, request),\n\t\trequestType: {\n\t\t\ttype: nameof<ILoggingCreateRequest>(),\n\t\t\texamples: [\n\t\t\t\t{\n\t\t\t\t\tid: \"loggingEntryCreateInfoExample\",\n\t\t\t\t\trequest: {\n\t\t\t\t\t\tbody: {\n\t\t\t\t\t\t\tlevel: \"info\",\n\t\t\t\t\t\t\tmessage: \"This is an information message\",\n\t\t\t\t\t\t\tsource: \"source\",\n\t\t\t\t\t\t\tts: 1715252922273\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tid: \"loggingEntryCreateErrorExample\",\n\t\t\t\t\trequest: {\n\t\t\t\t\t\tbody: {\n\t\t\t\t\t\t\tlevel: \"info\",\n\t\t\t\t\t\t\tmessage: \"This is an error message\",\n\t\t\t\t\t\t\tsource: \"source\",\n\t\t\t\t\t\t\tts: 1715252922273,\n\t\t\t\t\t\t\terror: {\n\t\t\t\t\t\t\t\tname: \"GeneralError\",\n\t\t\t\t\t\t\t\tmessage: \"component.error\",\n\t\t\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\t\t\tfoo: \"bar\"\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t]\n\t\t},\n\t\tresponseType: [\n\t\t\t{\n\t\t\t\ttype: nameof<INoContentResponse>()\n\t\t\t}\n\t\t]\n\t};\n\n\tconst listRoute: IRestRoute<ILoggingListRequest, ILoggingListResponse> = {\n\t\toperationId: \"loggingListEntries\",\n\t\tsummary: \"Get a list of the log entries\",\n\t\ttag: tagsLogging[0].name,\n\t\tmethod: \"GET\",\n\t\tpath: `${baseRouteName}/`,\n\t\thandler: async (httpRequestContext, request) =>\n\t\t\tloggingList(httpRequestContext, componentName, request),\n\t\trequestType: {\n\t\t\ttype: nameof<ILoggingListRequest>(),\n\t\t\texamples: [\n\t\t\t\t{\n\t\t\t\t\tid: \"loggingListRequestExample\",\n\t\t\t\t\trequest: {\n\t\t\t\t\t\tquery: {\n\t\t\t\t\t\t\tlevel: \"info\"\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t]\n\t\t},\n\t\tresponseType: [\n\t\t\t{\n\t\t\t\ttype: nameof<ILoggingListResponse>(),\n\t\t\t\texamples: [\n\t\t\t\t\t{\n\t\t\t\t\t\tid: \"listResponseExample\",\n\t\t\t\t\t\tresponse: {\n\t\t\t\t\t\t\tbody: {\n\t\t\t\t\t\t\t\tentities: [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tlevel: \"info\",\n\t\t\t\t\t\t\t\t\t\tmessage: \"This is an information message\",\n\t\t\t\t\t\t\t\t\t\tsource: \"source\",\n\t\t\t\t\t\t\t\t\t\tts: 1715252922273\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\tcursor: \"1\"\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t}\n\t\t]\n\t};\n\n\treturn [createRoute, listRoute];\n}\n\n/**\n * Create a new log entry.\n * @param httpRequestContext The request context for the API.\n * @param componentName The name of the component to use in the routes.\n * @param request The request.\n * @returns The response object with additional http response properties.\n */\nexport async function loggingCreate(\n\thttpRequestContext: IHttpRequestContext,\n\tcomponentName: string,\n\trequest: ILoggingCreateRequest\n): Promise<INoContentResponse> {\n\tGuards.object<ILoggingCreateRequest>(ROUTES_SOURCE, nameof(request), request);\n\tGuards.object<ILoggingCreateRequest[\"body\"]>(ROUTES_SOURCE, nameof(request.body), request.body);\n\tconst component = ComponentFactory.get<ILoggingComponent>(componentName);\n\tawait component.log(request.body);\n\treturn {\n\t\tstatusCode: HttpStatusCode.noContent\n\t};\n}\n\n/**\n * Get a list of the logging entries.\n * @param httpRequestContext The request context for the API.\n * @param componentName The name of the component to use in the routes.\n * @param request The request.\n * @returns The response object with additional http response properties.\n */\nexport async function loggingList(\n\thttpRequestContext: IHttpRequestContext,\n\tcomponentName: string,\n\trequest: ILoggingListRequest\n): Promise<ILoggingListResponse> {\n\tconst component = ComponentFactory.get<ILoggingComponent>(componentName);\n\n\tconst itemsAndCursor = await component.query(\n\t\trequest?.query?.level,\n\t\trequest?.query?.source,\n\t\tCoerce.number(request?.query?.timeStart),\n\t\tCoerce.number(request?.query?.timeEnd),\n\t\trequest?.query?.cursor,\n\t\tCoerce.number(request?.query?.limit)\n\t);\n\treturn {\n\t\tbody: itemsAndCursor\n\t};\n}\n"]}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
// Copyright 2024 IOTA Stiftung.
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0.
|
|
3
|
+
import { Guards, Is } from "@twin.org/core";
|
|
4
|
+
import { ComparisonOperator, LogicalOperator, SortDirection } from "@twin.org/entity";
|
|
5
|
+
import { LoggingConnectorFactory } from "@twin.org/logging-models";
|
|
6
|
+
/**
|
|
7
|
+
* Service for performing logging operations to a connector.
|
|
8
|
+
*/
|
|
9
|
+
export class LoggingService {
|
|
10
|
+
/**
|
|
11
|
+
* Runtime name for the class.
|
|
12
|
+
*/
|
|
13
|
+
static CLASS_NAME = "LoggingService";
|
|
14
|
+
/**
|
|
15
|
+
* Logging connector used by the service.
|
|
16
|
+
* @internal
|
|
17
|
+
*/
|
|
18
|
+
_loggingConnector;
|
|
19
|
+
/**
|
|
20
|
+
* Create a new instance of LoggingService.
|
|
21
|
+
* @param options The options for the connector.
|
|
22
|
+
*/
|
|
23
|
+
constructor(options) {
|
|
24
|
+
this._loggingConnector = LoggingConnectorFactory.get(options?.loggingConnectorType ?? "logging");
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Returns the class name of the component.
|
|
28
|
+
* @returns The class name of the component.
|
|
29
|
+
*/
|
|
30
|
+
className() {
|
|
31
|
+
return LoggingService.CLASS_NAME;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Log an entry to the connector.
|
|
35
|
+
* @param logEntry The entry to log.
|
|
36
|
+
* @returns Nothing.
|
|
37
|
+
*/
|
|
38
|
+
async log(logEntry) {
|
|
39
|
+
Guards.object(LoggingService.CLASS_NAME, "logEntry", logEntry);
|
|
40
|
+
await this._loggingConnector.log(logEntry);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Query the log entries.
|
|
44
|
+
* @param level The level of the log entries.
|
|
45
|
+
* @param source The source of the log entries.
|
|
46
|
+
* @param timeStart The inclusive time as the start of the log entries.
|
|
47
|
+
* @param timeEnd The inclusive time as the end of the log entries.
|
|
48
|
+
* @param cursor The cursor to request the next chunk of entities.
|
|
49
|
+
* @param limit Limit the number of entities to return.
|
|
50
|
+
* @returns All the entities for the storage matching the conditions,
|
|
51
|
+
* and a cursor which can be used to request more entities.
|
|
52
|
+
*/
|
|
53
|
+
async query(level, source, timeStart, timeEnd, cursor, limit) {
|
|
54
|
+
const condition = {
|
|
55
|
+
conditions: [],
|
|
56
|
+
logicalOperator: LogicalOperator.And
|
|
57
|
+
};
|
|
58
|
+
if (Is.stringValue(level)) {
|
|
59
|
+
condition.conditions.push({
|
|
60
|
+
property: "level",
|
|
61
|
+
comparison: ComparisonOperator.Equals,
|
|
62
|
+
value: level
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
if (Is.stringValue(source)) {
|
|
66
|
+
condition.conditions.push({
|
|
67
|
+
property: "source",
|
|
68
|
+
comparison: ComparisonOperator.Equals,
|
|
69
|
+
value: source
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
if (Is.number(timeStart)) {
|
|
73
|
+
condition.conditions.push({
|
|
74
|
+
property: "ts",
|
|
75
|
+
comparison: ComparisonOperator.GreaterThanOrEqual,
|
|
76
|
+
value: timeStart
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
if (Is.number(timeEnd)) {
|
|
80
|
+
condition.conditions.push({
|
|
81
|
+
property: "ts",
|
|
82
|
+
comparison: ComparisonOperator.LessThanOrEqual,
|
|
83
|
+
value: timeEnd
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
const queryConnector = this._loggingConnector?.query?.bind(this._loggingConnector);
|
|
87
|
+
if (Is.function(queryConnector)) {
|
|
88
|
+
const result = await queryConnector(condition, [{ property: "ts", sortDirection: SortDirection.Descending }], undefined, cursor, limit);
|
|
89
|
+
return { entities: result.entities, cursor: result.cursor };
|
|
90
|
+
}
|
|
91
|
+
return { entities: [] };
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=loggingService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loggingService.js","sourceRoot":"","sources":["../../src/loggingService.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport { Guards, Is } from \"@twin.org/core\";\nimport {\n\tComparisonOperator,\n\tLogicalOperator,\n\tSortDirection,\n\ttype EntityCondition\n} from \"@twin.org/entity\";\nimport {\n\tLoggingConnectorFactory,\n\ttype ILogEntry,\n\ttype ILoggingComponent,\n\ttype ILoggingConnector,\n\ttype LogLevel\n} from \"@twin.org/logging-models\";\nimport { nameof } from \"@twin.org/nameof\";\nimport type { ILoggingServiceConstructorOptions } from \"./models/ILoggingServiceConstructorOptions.js\";\n\n/**\n * Service for performing logging operations to a connector.\n */\nexport class LoggingService implements ILoggingComponent {\n\t/**\n\t * Runtime name for the class.\n\t */\n\tpublic static readonly CLASS_NAME: string = nameof<LoggingService>();\n\n\t/**\n\t * Logging connector used by the service.\n\t * @internal\n\t */\n\tprivate readonly _loggingConnector: ILoggingConnector;\n\n\t/**\n\t * Create a new instance of LoggingService.\n\t * @param options The options for the connector.\n\t */\n\tconstructor(options?: ILoggingServiceConstructorOptions) {\n\t\tthis._loggingConnector = LoggingConnectorFactory.get(\n\t\t\toptions?.loggingConnectorType ?? \"logging\"\n\t\t);\n\t}\n\n\t/**\n\t * Returns the class name of the component.\n\t * @returns The class name of the component.\n\t */\n\tpublic className(): string {\n\t\treturn LoggingService.CLASS_NAME;\n\t}\n\n\t/**\n\t * Log an entry to the connector.\n\t * @param logEntry The entry to log.\n\t * @returns Nothing.\n\t */\n\tpublic async log(logEntry: ILogEntry): Promise<void> {\n\t\tGuards.object<ILogEntry>(LoggingService.CLASS_NAME, nameof(logEntry), logEntry);\n\n\t\tawait this._loggingConnector.log(logEntry);\n\t}\n\n\t/**\n\t * Query the log entries.\n\t * @param level The level of the log entries.\n\t * @param source The source of the log entries.\n\t * @param timeStart The inclusive time as the start of the log entries.\n\t * @param timeEnd The inclusive time as the end of the log entries.\n\t * @param cursor The cursor to request the next chunk of entities.\n\t * @param limit Limit the number of entities to return.\n\t * @returns All the entities for the storage matching the conditions,\n\t * and a cursor which can be used to request more entities.\n\t */\n\tpublic async query(\n\t\tlevel?: LogLevel,\n\t\tsource?: string,\n\t\ttimeStart?: number,\n\t\ttimeEnd?: number,\n\t\tcursor?: string,\n\t\tlimit?: number\n\t): Promise<{\n\t\t/**\n\t\t * The entities, which can be partial if a limited keys list was provided.\n\t\t */\n\t\tentities: ILogEntry[];\n\t\t/**\n\t\t * An optional cursor, when defined can be used to call find to get more entities.\n\t\t */\n\t\tcursor?: string;\n\t}> {\n\t\tconst condition: EntityCondition<Omit<ILogEntry, \"error\" | \"data\">> = {\n\t\t\tconditions: [],\n\t\t\tlogicalOperator: LogicalOperator.And\n\t\t};\n\n\t\tif (Is.stringValue(level)) {\n\t\t\tcondition.conditions.push({\n\t\t\t\tproperty: \"level\",\n\t\t\t\tcomparison: ComparisonOperator.Equals,\n\t\t\t\tvalue: level\n\t\t\t});\n\t\t}\n\n\t\tif (Is.stringValue(source)) {\n\t\t\tcondition.conditions.push({\n\t\t\t\tproperty: \"source\",\n\t\t\t\tcomparison: ComparisonOperator.Equals,\n\t\t\t\tvalue: source\n\t\t\t});\n\t\t}\n\n\t\tif (Is.number(timeStart)) {\n\t\t\tcondition.conditions.push({\n\t\t\t\tproperty: \"ts\",\n\t\t\t\tcomparison: ComparisonOperator.GreaterThanOrEqual,\n\t\t\t\tvalue: timeStart\n\t\t\t});\n\t\t}\n\n\t\tif (Is.number(timeEnd)) {\n\t\t\tcondition.conditions.push({\n\t\t\t\tproperty: \"ts\",\n\t\t\t\tcomparison: ComparisonOperator.LessThanOrEqual,\n\t\t\t\tvalue: timeEnd\n\t\t\t});\n\t\t}\n\n\t\tconst queryConnector = this._loggingConnector?.query?.bind(this._loggingConnector);\n\t\tif (Is.function(queryConnector)) {\n\t\t\tconst result = await queryConnector(\n\t\t\t\tcondition,\n\t\t\t\t[{ property: \"ts\", sortDirection: SortDirection.Descending }],\n\t\t\t\tundefined,\n\t\t\t\tcursor,\n\t\t\t\tlimit\n\t\t\t);\n\n\t\t\treturn { entities: result.entities as ILogEntry[], cursor: result.cursor };\n\t\t}\n\n\t\treturn { entities: [] };\n\t}\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ILoggingServiceConstructorOptions.js","sourceRoot":"","sources":["../../../src/models/ILoggingServiceConstructorOptions.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,uCAAuC","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\n\n/**\n * Options for the logging service constructor.\n */\nexport interface ILoggingServiceConstructorOptions {\n\t/**\n\t * The type of the logging connector to use.\n\t * @default logging\n\t */\n\tloggingConnectorType?: string;\n}\n"]}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { generateRestRoutesLogging, tagsLogging } from "./loggingRoutes.js";
|
|
2
|
+
export const restEntryPoints = [
|
|
3
|
+
{
|
|
4
|
+
name: "logging",
|
|
5
|
+
defaultBaseRoute: "logging",
|
|
6
|
+
tags: tagsLogging,
|
|
7
|
+
generateRoutes: generateRestRoutesLogging
|
|
8
|
+
}
|
|
9
|
+
];
|
|
10
|
+
//# sourceMappingURL=restEntryPoints.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"restEntryPoints.js","sourceRoot":"","sources":["../../src/restEntryPoints.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,yBAAyB,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAE5E,MAAM,CAAC,MAAM,eAAe,GAA2B;IACtD;QACC,IAAI,EAAE,SAAS;QACf,gBAAgB,EAAE,SAAS;QAC3B,IAAI,EAAE,WAAW;QACjB,cAAc,EAAE,yBAAyB;KACzC;CACD,CAAC","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport type { IRestRouteEntryPoint } from \"@twin.org/api-models\";\nimport { generateRestRoutesLogging, tagsLogging } from \"./loggingRoutes.js\";\n\nexport const restEntryPoints: IRestRouteEntryPoint[] = [\n\t{\n\t\tname: \"logging\",\n\t\tdefaultBaseRoute: \"logging\",\n\t\ttags: tagsLogging,\n\t\tgenerateRoutes: generateRestRoutesLogging\n\t}\n];\n"]}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export * from "./loggingRoutes";
|
|
2
|
-
export * from "./loggingService";
|
|
3
|
-
export * from "./models/ILoggingServiceConstructorOptions";
|
|
4
|
-
export * from "./restEntryPoints";
|
|
1
|
+
export * from "./loggingRoutes.js";
|
|
2
|
+
export * from "./loggingService.js";
|
|
3
|
+
export * from "./models/ILoggingServiceConstructorOptions.js";
|
|
4
|
+
export * from "./restEntryPoints.js";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type ILogEntry, type ILoggingComponent, type LogLevel } from "@twin.org/logging-models";
|
|
2
|
-
import type { ILoggingServiceConstructorOptions } from "./models/ILoggingServiceConstructorOptions";
|
|
2
|
+
import type { ILoggingServiceConstructorOptions } from "./models/ILoggingServiceConstructorOptions.js";
|
|
3
3
|
/**
|
|
4
4
|
* Service for performing logging operations to a connector.
|
|
5
5
|
*/
|
|
@@ -13,6 +13,11 @@ export declare class LoggingService implements ILoggingComponent {
|
|
|
13
13
|
* @param options The options for the connector.
|
|
14
14
|
*/
|
|
15
15
|
constructor(options?: ILoggingServiceConstructorOptions);
|
|
16
|
+
/**
|
|
17
|
+
* Returns the class name of the component.
|
|
18
|
+
* @returns The class name of the component.
|
|
19
|
+
*/
|
|
20
|
+
className(): string;
|
|
16
21
|
/**
|
|
17
22
|
* Log an entry to the connector.
|
|
18
23
|
* @param logEntry The entry to log.
|
package/docs/changelog.md
CHANGED
|
@@ -1,5 +1,45 @@
|
|
|
1
1
|
# @twin.org/logging-service - Changelog
|
|
2
2
|
|
|
3
|
+
## [0.0.3-next.2](https://github.com/twinfoundation/logging/compare/logging-service-v0.0.3-next.1...logging-service-v0.0.3-next.2) (2026-03-02)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Bug Fixes
|
|
7
|
+
|
|
8
|
+
* api data types ([8d37cab](https://github.com/twinfoundation/logging/commit/8d37cab7ec759f079b6480bcc27d739357dbc392))
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Dependencies
|
|
12
|
+
|
|
13
|
+
* The following workspace dependencies were updated
|
|
14
|
+
* dependencies
|
|
15
|
+
* @twin.org/logging-models bumped from 0.0.3-next.1 to 0.0.3-next.2
|
|
16
|
+
|
|
17
|
+
## [0.0.3-next.1](https://github.com/twinfoundation/logging/compare/logging-service-v0.0.3-next.0...logging-service-v0.0.3-next.1) (2025-11-10)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
### Features
|
|
21
|
+
|
|
22
|
+
* add context id features ([#33](https://github.com/twinfoundation/logging/issues/33)) ([38e982c](https://github.com/twinfoundation/logging/commit/38e982c9f009019fc02b67d919444b52657c9021))
|
|
23
|
+
* add production release automation ([5dbcad8](https://github.com/twinfoundation/logging/commit/5dbcad8b105d749947c4fda19c814373cee2a172))
|
|
24
|
+
* add validate-locales ([df53f13](https://github.com/twinfoundation/logging/commit/df53f1331394f2f9333e91e4995a88dded90e484))
|
|
25
|
+
* eslint migration to flat config ([1f9fdde](https://github.com/twinfoundation/logging/commit/1f9fddedfdcce9942afed431d9460a0f22092744))
|
|
26
|
+
* remove unused namespace ([7eb6575](https://github.com/twinfoundation/logging/commit/7eb65758fbdc9a42f68d149702ba03c000556325))
|
|
27
|
+
* update dependencies ([976fc06](https://github.com/twinfoundation/logging/commit/976fc06976c4899769486b7cb2e827c407d7fc89))
|
|
28
|
+
* update framework core ([aac823c](https://github.com/twinfoundation/logging/commit/aac823c2ead88843618b8a82b308d5a793411764))
|
|
29
|
+
* use shared store mechanism ([#20](https://github.com/twinfoundation/logging/issues/20)) ([bbacd31](https://github.com/twinfoundation/logging/commit/bbacd31af991d82d84294ad432a40830692880ca))
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
### Bug Fixes
|
|
33
|
+
|
|
34
|
+
* query params force coercion ([71c5329](https://github.com/twinfoundation/logging/commit/71c53292d300acae0369bd7937c5ca3ab5430689))
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
### Dependencies
|
|
38
|
+
|
|
39
|
+
* The following workspace dependencies were updated
|
|
40
|
+
* dependencies
|
|
41
|
+
* @twin.org/logging-models bumped from 0.0.3-next.0 to 0.0.3-next.1
|
|
42
|
+
|
|
3
43
|
## [0.0.2-next.3](https://github.com/twinfoundation/logging/compare/logging-service-v0.0.2-next.2...logging-service-v0.0.2-next.3) (2025-10-09)
|
|
4
44
|
|
|
5
45
|
|
package/docs/open-api/spec.json
CHANGED
|
@@ -164,10 +164,7 @@
|
|
|
164
164
|
"in": "query",
|
|
165
165
|
"required": false,
|
|
166
166
|
"schema": {
|
|
167
|
-
"type":
|
|
168
|
-
"number",
|
|
169
|
-
"string"
|
|
170
|
-
]
|
|
167
|
+
"type": "string"
|
|
171
168
|
}
|
|
172
169
|
},
|
|
173
170
|
{
|
|
@@ -176,10 +173,7 @@
|
|
|
176
173
|
"in": "query",
|
|
177
174
|
"required": false,
|
|
178
175
|
"schema": {
|
|
179
|
-
"type":
|
|
180
|
-
"number",
|
|
181
|
-
"string"
|
|
182
|
-
]
|
|
176
|
+
"type": "string"
|
|
183
177
|
}
|
|
184
178
|
},
|
|
185
179
|
{
|
|
@@ -327,7 +321,6 @@
|
|
|
327
321
|
"name",
|
|
328
322
|
"message"
|
|
329
323
|
],
|
|
330
|
-
"additionalProperties": false,
|
|
331
324
|
"description": "Model to describe serialized error."
|
|
332
325
|
},
|
|
333
326
|
"LogEntry": {
|
|
@@ -362,32 +355,47 @@
|
|
|
362
355
|
"source",
|
|
363
356
|
"message"
|
|
364
357
|
],
|
|
365
|
-
"additionalProperties": false,
|
|
366
358
|
"description": "Interface describing a log entry."
|
|
367
359
|
},
|
|
368
360
|
"LogLevel": {
|
|
369
|
-
"
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
361
|
+
"anyOf": [
|
|
362
|
+
{
|
|
363
|
+
"type": "string",
|
|
364
|
+
"const": "info",
|
|
365
|
+
"description": "Info."
|
|
366
|
+
},
|
|
367
|
+
{
|
|
368
|
+
"type": "string",
|
|
369
|
+
"const": "error",
|
|
370
|
+
"description": "Error."
|
|
371
|
+
},
|
|
372
|
+
{
|
|
373
|
+
"type": "string",
|
|
374
|
+
"const": "warn",
|
|
375
|
+
"description": "Warn."
|
|
376
|
+
},
|
|
377
|
+
{
|
|
378
|
+
"type": "string",
|
|
379
|
+
"const": "trace",
|
|
380
|
+
"description": "Trace."
|
|
381
|
+
},
|
|
382
|
+
{
|
|
383
|
+
"type": "string",
|
|
384
|
+
"const": "debug",
|
|
385
|
+
"description": "Debug."
|
|
386
|
+
}
|
|
376
387
|
],
|
|
377
|
-
"description": "
|
|
388
|
+
"description": "The log levels."
|
|
378
389
|
},
|
|
379
390
|
"LoggingListResponse": {
|
|
380
391
|
"type": "object",
|
|
381
392
|
"properties": {
|
|
382
393
|
"entities": {
|
|
383
394
|
"type": "array",
|
|
384
|
-
"items":
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
"$ref": "#/components/schemas/LogEntry"
|
|
389
|
-
}
|
|
390
|
-
]
|
|
395
|
+
"items": {
|
|
396
|
+
"$ref": "#/components/schemas/LogEntry"
|
|
397
|
+
},
|
|
398
|
+
"description": "The entities, which can be partial if a limited keys list was provided."
|
|
391
399
|
},
|
|
392
400
|
"cursor": {
|
|
393
401
|
"type": "string",
|
|
@@ -397,7 +405,6 @@
|
|
|
397
405
|
"required": [
|
|
398
406
|
"entities"
|
|
399
407
|
],
|
|
400
|
-
"additionalProperties": false,
|
|
401
408
|
"description": "The response payload."
|
|
402
409
|
}
|
|
403
410
|
},
|
|
@@ -36,6 +36,24 @@ Runtime name for the class.
|
|
|
36
36
|
|
|
37
37
|
## Methods
|
|
38
38
|
|
|
39
|
+
### className()
|
|
40
|
+
|
|
41
|
+
> **className**(): `string`
|
|
42
|
+
|
|
43
|
+
Returns the class name of the component.
|
|
44
|
+
|
|
45
|
+
#### Returns
|
|
46
|
+
|
|
47
|
+
`string`
|
|
48
|
+
|
|
49
|
+
The class name of the component.
|
|
50
|
+
|
|
51
|
+
#### Implementation of
|
|
52
|
+
|
|
53
|
+
`ILoggingComponent.className`
|
|
54
|
+
|
|
55
|
+
***
|
|
56
|
+
|
|
39
57
|
### log()
|
|
40
58
|
|
|
41
59
|
> **log**(`logEntry`): `Promise`\<`void`\>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@twin.org/logging-service",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.3-next.2",
|
|
4
4
|
"description": "Logging contract implementation and REST endpoint definitions",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -17,24 +17,22 @@
|
|
|
17
17
|
"@twin.org/api-models": "next",
|
|
18
18
|
"@twin.org/core": "next",
|
|
19
19
|
"@twin.org/entity": "next",
|
|
20
|
-
"@twin.org/logging-models": "0.0.
|
|
20
|
+
"@twin.org/logging-models": "0.0.3-next.2",
|
|
21
21
|
"@twin.org/nameof": "next",
|
|
22
22
|
"@twin.org/web": "next"
|
|
23
23
|
},
|
|
24
|
-
"main": "./dist/
|
|
25
|
-
"module": "./dist/esm/index.mjs",
|
|
24
|
+
"main": "./dist/es/index.js",
|
|
26
25
|
"types": "./dist/types/index.d.ts",
|
|
27
26
|
"exports": {
|
|
28
27
|
".": {
|
|
29
28
|
"types": "./dist/types/index.d.ts",
|
|
30
|
-
"
|
|
31
|
-
"
|
|
29
|
+
"import": "./dist/es/index.js",
|
|
30
|
+
"default": "./dist/es/index.js"
|
|
32
31
|
},
|
|
33
32
|
"./locales/*.json": "./locales/*.json"
|
|
34
33
|
},
|
|
35
34
|
"files": [
|
|
36
|
-
"dist/
|
|
37
|
-
"dist/esm",
|
|
35
|
+
"dist/es",
|
|
38
36
|
"dist/types",
|
|
39
37
|
"locales",
|
|
40
38
|
"docs"
|
package/dist/cjs/index.cjs
DELETED
|
@@ -1,249 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
var core = require('@twin.org/core');
|
|
4
|
-
var web = require('@twin.org/web');
|
|
5
|
-
var entity = require('@twin.org/entity');
|
|
6
|
-
var loggingModels = require('@twin.org/logging-models');
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* The source used when communicating about these routes.
|
|
10
|
-
*/
|
|
11
|
-
const ROUTES_SOURCE = "loggingRoutes";
|
|
12
|
-
/**
|
|
13
|
-
* The tag to associate with the routes.
|
|
14
|
-
*/
|
|
15
|
-
const tagsLogging = [
|
|
16
|
-
{
|
|
17
|
-
name: "Logging",
|
|
18
|
-
description: "Endpoints which are modelled to access a logging contract."
|
|
19
|
-
}
|
|
20
|
-
];
|
|
21
|
-
/**
|
|
22
|
-
* The REST routes for logging.
|
|
23
|
-
* @param baseRouteName Prefix to prepend to the paths.
|
|
24
|
-
* @param componentName The name of the component to use in the routes stored in the ComponentFactory.
|
|
25
|
-
* @returns The generated routes.
|
|
26
|
-
*/
|
|
27
|
-
function generateRestRoutesLogging(baseRouteName, componentName) {
|
|
28
|
-
const createRoute = {
|
|
29
|
-
operationId: "loggingEntryCreate",
|
|
30
|
-
summary: "Create a log entry",
|
|
31
|
-
tag: tagsLogging[0].name,
|
|
32
|
-
method: "POST",
|
|
33
|
-
path: `${baseRouteName}/`,
|
|
34
|
-
handler: async (httpRequestContext, request) => loggingCreate(httpRequestContext, componentName, request),
|
|
35
|
-
requestType: {
|
|
36
|
-
type: "ILoggingCreateRequest",
|
|
37
|
-
examples: [
|
|
38
|
-
{
|
|
39
|
-
id: "loggingEntryCreateInfoExample",
|
|
40
|
-
request: {
|
|
41
|
-
body: {
|
|
42
|
-
level: "info",
|
|
43
|
-
message: "This is an information message",
|
|
44
|
-
source: "source",
|
|
45
|
-
ts: 1715252922273
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
},
|
|
49
|
-
{
|
|
50
|
-
id: "loggingEntryCreateErrorExample",
|
|
51
|
-
request: {
|
|
52
|
-
body: {
|
|
53
|
-
level: "info",
|
|
54
|
-
message: "This is an error message",
|
|
55
|
-
source: "source",
|
|
56
|
-
ts: 1715252922273,
|
|
57
|
-
error: {
|
|
58
|
-
name: "GeneralError",
|
|
59
|
-
message: "component.error",
|
|
60
|
-
properties: {
|
|
61
|
-
foo: "bar"
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
]
|
|
68
|
-
},
|
|
69
|
-
responseType: [
|
|
70
|
-
{
|
|
71
|
-
type: "INoContentResponse"
|
|
72
|
-
}
|
|
73
|
-
]
|
|
74
|
-
};
|
|
75
|
-
const listRoute = {
|
|
76
|
-
operationId: "loggingListEntries",
|
|
77
|
-
summary: "Get a list of the log entries",
|
|
78
|
-
tag: tagsLogging[0].name,
|
|
79
|
-
method: "GET",
|
|
80
|
-
path: `${baseRouteName}/`,
|
|
81
|
-
handler: async (httpRequestContext, request) => loggingList(httpRequestContext, componentName, request),
|
|
82
|
-
requestType: {
|
|
83
|
-
type: "ILoggingListRequest",
|
|
84
|
-
examples: [
|
|
85
|
-
{
|
|
86
|
-
id: "loggingListRequestExample",
|
|
87
|
-
request: {
|
|
88
|
-
query: {
|
|
89
|
-
level: "info"
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
]
|
|
94
|
-
},
|
|
95
|
-
responseType: [
|
|
96
|
-
{
|
|
97
|
-
type: "ILoggingListResponse",
|
|
98
|
-
examples: [
|
|
99
|
-
{
|
|
100
|
-
id: "listResponseExample",
|
|
101
|
-
response: {
|
|
102
|
-
body: {
|
|
103
|
-
entities: [
|
|
104
|
-
{
|
|
105
|
-
level: "info",
|
|
106
|
-
message: "This is an information message",
|
|
107
|
-
source: "source",
|
|
108
|
-
ts: 1715252922273
|
|
109
|
-
}
|
|
110
|
-
],
|
|
111
|
-
cursor: "1"
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
]
|
|
116
|
-
}
|
|
117
|
-
]
|
|
118
|
-
};
|
|
119
|
-
return [createRoute, listRoute];
|
|
120
|
-
}
|
|
121
|
-
/**
|
|
122
|
-
* Create a new log entry.
|
|
123
|
-
* @param httpRequestContext The request context for the API.
|
|
124
|
-
* @param componentName The name of the component to use in the routes.
|
|
125
|
-
* @param request The request.
|
|
126
|
-
* @returns The response object with additional http response properties.
|
|
127
|
-
*/
|
|
128
|
-
async function loggingCreate(httpRequestContext, componentName, request) {
|
|
129
|
-
core.Guards.object(ROUTES_SOURCE, "request", request);
|
|
130
|
-
core.Guards.object(ROUTES_SOURCE, "request.body", request.body);
|
|
131
|
-
const component = core.ComponentFactory.get(componentName);
|
|
132
|
-
await component.log(request.body);
|
|
133
|
-
return {
|
|
134
|
-
statusCode: web.HttpStatusCode.noContent
|
|
135
|
-
};
|
|
136
|
-
}
|
|
137
|
-
/**
|
|
138
|
-
* Get a list of the logging entries.
|
|
139
|
-
* @param httpRequestContext The request context for the API.
|
|
140
|
-
* @param componentName The name of the component to use in the routes.
|
|
141
|
-
* @param request The request.
|
|
142
|
-
* @returns The response object with additional http response properties.
|
|
143
|
-
*/
|
|
144
|
-
async function loggingList(httpRequestContext, componentName, request) {
|
|
145
|
-
const component = core.ComponentFactory.get(componentName);
|
|
146
|
-
const itemsAndCursor = await component.query(request?.query?.level, request?.query?.source, core.Coerce.number(request?.query?.timeStart), core.Coerce.number(request?.query?.timeEnd), request?.query?.cursor, core.Coerce.number(request?.query?.limit));
|
|
147
|
-
return {
|
|
148
|
-
body: itemsAndCursor
|
|
149
|
-
};
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
// Copyright 2024 IOTA Stiftung.
|
|
153
|
-
// SPDX-License-Identifier: Apache-2.0.
|
|
154
|
-
/**
|
|
155
|
-
* Service for performing logging operations to a connector.
|
|
156
|
-
*/
|
|
157
|
-
class LoggingService {
|
|
158
|
-
/**
|
|
159
|
-
* Runtime name for the class.
|
|
160
|
-
*/
|
|
161
|
-
static CLASS_NAME = "LoggingService";
|
|
162
|
-
/**
|
|
163
|
-
* Logging connector used by the service.
|
|
164
|
-
* @internal
|
|
165
|
-
*/
|
|
166
|
-
_loggingConnector;
|
|
167
|
-
/**
|
|
168
|
-
* Create a new instance of LoggingService.
|
|
169
|
-
* @param options The options for the connector.
|
|
170
|
-
*/
|
|
171
|
-
constructor(options) {
|
|
172
|
-
this._loggingConnector = loggingModels.LoggingConnectorFactory.get(options?.loggingConnectorType ?? "logging");
|
|
173
|
-
}
|
|
174
|
-
/**
|
|
175
|
-
* Log an entry to the connector.
|
|
176
|
-
* @param logEntry The entry to log.
|
|
177
|
-
* @returns Nothing.
|
|
178
|
-
*/
|
|
179
|
-
async log(logEntry) {
|
|
180
|
-
core.Guards.object(LoggingService.CLASS_NAME, "logEntry", logEntry);
|
|
181
|
-
await this._loggingConnector.log(logEntry);
|
|
182
|
-
}
|
|
183
|
-
/**
|
|
184
|
-
* Query the log entries.
|
|
185
|
-
* @param level The level of the log entries.
|
|
186
|
-
* @param source The source of the log entries.
|
|
187
|
-
* @param timeStart The inclusive time as the start of the log entries.
|
|
188
|
-
* @param timeEnd The inclusive time as the end of the log entries.
|
|
189
|
-
* @param cursor The cursor to request the next chunk of entities.
|
|
190
|
-
* @param limit Limit the number of entities to return.
|
|
191
|
-
* @returns All the entities for the storage matching the conditions,
|
|
192
|
-
* and a cursor which can be used to request more entities.
|
|
193
|
-
*/
|
|
194
|
-
async query(level, source, timeStart, timeEnd, cursor, limit) {
|
|
195
|
-
const condition = {
|
|
196
|
-
conditions: [],
|
|
197
|
-
logicalOperator: entity.LogicalOperator.And
|
|
198
|
-
};
|
|
199
|
-
if (core.Is.stringValue(level)) {
|
|
200
|
-
condition.conditions.push({
|
|
201
|
-
property: "level",
|
|
202
|
-
comparison: entity.ComparisonOperator.Equals,
|
|
203
|
-
value: level
|
|
204
|
-
});
|
|
205
|
-
}
|
|
206
|
-
if (core.Is.stringValue(source)) {
|
|
207
|
-
condition.conditions.push({
|
|
208
|
-
property: "source",
|
|
209
|
-
comparison: entity.ComparisonOperator.Equals,
|
|
210
|
-
value: source
|
|
211
|
-
});
|
|
212
|
-
}
|
|
213
|
-
if (core.Is.number(timeStart)) {
|
|
214
|
-
condition.conditions.push({
|
|
215
|
-
property: "ts",
|
|
216
|
-
comparison: entity.ComparisonOperator.GreaterThanOrEqual,
|
|
217
|
-
value: timeStart
|
|
218
|
-
});
|
|
219
|
-
}
|
|
220
|
-
if (core.Is.number(timeEnd)) {
|
|
221
|
-
condition.conditions.push({
|
|
222
|
-
property: "ts",
|
|
223
|
-
comparison: entity.ComparisonOperator.LessThanOrEqual,
|
|
224
|
-
value: timeEnd
|
|
225
|
-
});
|
|
226
|
-
}
|
|
227
|
-
if (core.Is.function(this._loggingConnector?.query)) {
|
|
228
|
-
const result = await this._loggingConnector.query(condition, [{ property: "ts", sortDirection: entity.SortDirection.Descending }], undefined, cursor, limit);
|
|
229
|
-
return { entities: result.entities, cursor: result.cursor };
|
|
230
|
-
}
|
|
231
|
-
return { entities: [] };
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
const restEntryPoints = [
|
|
236
|
-
{
|
|
237
|
-
name: "logging",
|
|
238
|
-
defaultBaseRoute: "logging",
|
|
239
|
-
tags: tagsLogging,
|
|
240
|
-
generateRoutes: generateRestRoutesLogging
|
|
241
|
-
}
|
|
242
|
-
];
|
|
243
|
-
|
|
244
|
-
exports.LoggingService = LoggingService;
|
|
245
|
-
exports.generateRestRoutesLogging = generateRestRoutesLogging;
|
|
246
|
-
exports.loggingCreate = loggingCreate;
|
|
247
|
-
exports.loggingList = loggingList;
|
|
248
|
-
exports.restEntryPoints = restEntryPoints;
|
|
249
|
-
exports.tagsLogging = tagsLogging;
|