@twin.org/logging-service 0.0.1-next.10
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/LICENSE +201 -0
- package/README.md +21 -0
- package/dist/cjs/index.cjs +259 -0
- package/dist/esm/index.mjs +252 -0
- package/dist/types/index.d.ts +4 -0
- package/dist/types/loggingRoutes.d.ts +29 -0
- package/dist/types/loggingService.d.ts +48 -0
- package/dist/types/models/ILoggingServiceConstructorOptions.d.ts +10 -0
- package/dist/types/restEntryPoints.d.ts +2 -0
- package/docs/changelog.md +5 -0
- package/docs/examples.md +1 -0
- package/docs/open-api/spec.json +403 -0
- package/docs/reference/classes/LoggingService.md +134 -0
- package/docs/reference/functions/generateRestRoutesLogging.md +25 -0
- package/docs/reference/functions/loggingCreate.md +31 -0
- package/docs/reference/functions/loggingList.md +31 -0
- package/docs/reference/index.md +20 -0
- package/docs/reference/interfaces/ILoggingServiceConstructorOptions.md +17 -0
- package/docs/reference/variables/restEntryPoints.md +3 -0
- package/docs/reference/variables/tagsLogging.md +5 -0
- package/locales/en.json +1 -0
- package/package.json +42 -0
@@ -0,0 +1,252 @@
|
|
1
|
+
import { Guards, ComponentFactory, Coerce, Is } from '@twin.org/core';
|
2
|
+
import { HttpStatusCode } from '@twin.org/web';
|
3
|
+
import { LogicalOperator, ComparisonOperator, SortDirection } from '@twin.org/entity';
|
4
|
+
import { LoggingConnectorFactory } from '@twin.org/logging-models';
|
5
|
+
|
6
|
+
/**
|
7
|
+
* The source used when communicating about these routes.
|
8
|
+
*/
|
9
|
+
const ROUTES_SOURCE = "loggingRoutes";
|
10
|
+
/**
|
11
|
+
* The tag to associate with the routes.
|
12
|
+
*/
|
13
|
+
const tagsLogging = [
|
14
|
+
{
|
15
|
+
name: "Logging",
|
16
|
+
description: "Endpoints which are modelled to access a logging contract."
|
17
|
+
}
|
18
|
+
];
|
19
|
+
/**
|
20
|
+
* The REST routes for logging.
|
21
|
+
* @param baseRouteName Prefix to prepend to the paths.
|
22
|
+
* @param componentName The name of the component to use in the routes stored in the ComponentFactory.
|
23
|
+
* @returns The generated routes.
|
24
|
+
*/
|
25
|
+
function generateRestRoutesLogging(baseRouteName, componentName) {
|
26
|
+
const createRoute = {
|
27
|
+
operationId: "loggingEntryCreate",
|
28
|
+
summary: "Create a log entry",
|
29
|
+
tag: tagsLogging[0].name,
|
30
|
+
method: "POST",
|
31
|
+
path: `${baseRouteName}/`,
|
32
|
+
handler: async (httpRequestContext, request) => loggingCreate(httpRequestContext, componentName, request),
|
33
|
+
requestType: {
|
34
|
+
type: "ILoggingCreateRequest",
|
35
|
+
examples: [
|
36
|
+
{
|
37
|
+
id: "loggingEntryCreateInfoExample",
|
38
|
+
request: {
|
39
|
+
body: {
|
40
|
+
level: "info",
|
41
|
+
message: "This is an information message",
|
42
|
+
source: "source",
|
43
|
+
ts: 1715252922273
|
44
|
+
}
|
45
|
+
}
|
46
|
+
},
|
47
|
+
{
|
48
|
+
id: "loggingEntryCreateErrorExample",
|
49
|
+
request: {
|
50
|
+
body: {
|
51
|
+
level: "info",
|
52
|
+
message: "This is an error message",
|
53
|
+
source: "source",
|
54
|
+
ts: 1715252922273,
|
55
|
+
error: {
|
56
|
+
name: "GeneralError",
|
57
|
+
message: "component.error",
|
58
|
+
properties: {
|
59
|
+
foo: "bar"
|
60
|
+
}
|
61
|
+
}
|
62
|
+
}
|
63
|
+
}
|
64
|
+
}
|
65
|
+
]
|
66
|
+
},
|
67
|
+
responseType: [
|
68
|
+
{
|
69
|
+
type: "INoContentResponse"
|
70
|
+
}
|
71
|
+
]
|
72
|
+
};
|
73
|
+
const listRoute = {
|
74
|
+
operationId: "loggingListEntries",
|
75
|
+
summary: "Get a list of the log entries",
|
76
|
+
tag: tagsLogging[0].name,
|
77
|
+
method: "GET",
|
78
|
+
path: `${baseRouteName}/`,
|
79
|
+
handler: async (httpRequestContext, request) => loggingList(httpRequestContext, componentName, request),
|
80
|
+
requestType: {
|
81
|
+
type: "ILoggingListRequest",
|
82
|
+
examples: [
|
83
|
+
{
|
84
|
+
id: "loggingListRequestExample",
|
85
|
+
request: {
|
86
|
+
query: {
|
87
|
+
level: "info"
|
88
|
+
}
|
89
|
+
}
|
90
|
+
}
|
91
|
+
]
|
92
|
+
},
|
93
|
+
responseType: [
|
94
|
+
{
|
95
|
+
type: "ILoggingListResponse",
|
96
|
+
examples: [
|
97
|
+
{
|
98
|
+
id: "listResponseExample",
|
99
|
+
response: {
|
100
|
+
body: {
|
101
|
+
entities: [
|
102
|
+
{
|
103
|
+
level: "info",
|
104
|
+
message: "This is an information message",
|
105
|
+
source: "source",
|
106
|
+
ts: 1715252922273
|
107
|
+
}
|
108
|
+
],
|
109
|
+
cursor: "1"
|
110
|
+
}
|
111
|
+
}
|
112
|
+
}
|
113
|
+
]
|
114
|
+
}
|
115
|
+
]
|
116
|
+
};
|
117
|
+
return [createRoute, listRoute];
|
118
|
+
}
|
119
|
+
/**
|
120
|
+
* Create a new log entry.
|
121
|
+
* @param httpRequestContext The request context for the API.
|
122
|
+
* @param componentName The name of the component to use in the routes.
|
123
|
+
* @param request The request.
|
124
|
+
* @returns The response object with additional http response properties.
|
125
|
+
*/
|
126
|
+
async function loggingCreate(httpRequestContext, componentName, request) {
|
127
|
+
Guards.object(ROUTES_SOURCE, "request", request);
|
128
|
+
Guards.object(ROUTES_SOURCE, "request.body", request.body);
|
129
|
+
const component = ComponentFactory.get(componentName);
|
130
|
+
await component.log(request.body);
|
131
|
+
return {
|
132
|
+
statusCode: HttpStatusCode.noContent
|
133
|
+
};
|
134
|
+
}
|
135
|
+
/**
|
136
|
+
* Get a list of the logging entries.
|
137
|
+
* @param httpRequestContext The request context for the API.
|
138
|
+
* @param componentName The name of the component to use in the routes.
|
139
|
+
* @param request The request.
|
140
|
+
* @returns The response object with additional http response properties.
|
141
|
+
*/
|
142
|
+
async function loggingList(httpRequestContext, componentName, request) {
|
143
|
+
const component = ComponentFactory.get(componentName);
|
144
|
+
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?.pageSize));
|
145
|
+
return {
|
146
|
+
body: itemsAndCursor
|
147
|
+
};
|
148
|
+
}
|
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
|
+
* The namespace for the logging component.
|
158
|
+
*/
|
159
|
+
static NAMESPACE = "logging";
|
160
|
+
/**
|
161
|
+
* Runtime name for the class.
|
162
|
+
*/
|
163
|
+
CLASS_NAME = "LoggingService";
|
164
|
+
/**
|
165
|
+
* Logging connector used by the service.
|
166
|
+
* @internal
|
167
|
+
*/
|
168
|
+
_loggingConnector;
|
169
|
+
/**
|
170
|
+
* Create a new instance of LoggingService.
|
171
|
+
* @param options The options for the connector.
|
172
|
+
*/
|
173
|
+
constructor(options) {
|
174
|
+
this._loggingConnector = LoggingConnectorFactory.get(options?.loggingConnectorType ?? "logging");
|
175
|
+
}
|
176
|
+
/**
|
177
|
+
* Log an entry to the connector.
|
178
|
+
* @param logEntry The entry to log.
|
179
|
+
* @returns Nothing.
|
180
|
+
*/
|
181
|
+
async log(logEntry) {
|
182
|
+
Guards.object(this.CLASS_NAME, "logEntry", logEntry);
|
183
|
+
await this._loggingConnector.log(logEntry);
|
184
|
+
}
|
185
|
+
/**
|
186
|
+
* Query the log entries.
|
187
|
+
* @param level The level of the log entries.
|
188
|
+
* @param source The source of the log entries.
|
189
|
+
* @param timeStart The inclusive time as the start of the log entries.
|
190
|
+
* @param timeEnd The inclusive time as the end of the log entries.
|
191
|
+
* @param cursor The cursor to request the next page of entities.
|
192
|
+
* @param pageSize The maximum number of entities in a page.
|
193
|
+
* @returns All the entities for the storage matching the conditions,
|
194
|
+
* and a cursor which can be used to request more entities.
|
195
|
+
* @throws NotImplementedError if the implementation does not support retrieval.
|
196
|
+
*/
|
197
|
+
async query(level, source, timeStart, timeEnd, cursor, pageSize) {
|
198
|
+
const condition = {
|
199
|
+
conditions: [],
|
200
|
+
logicalOperator: LogicalOperator.And
|
201
|
+
};
|
202
|
+
if (Is.stringValue(level)) {
|
203
|
+
condition.conditions.push({
|
204
|
+
property: "level",
|
205
|
+
comparison: ComparisonOperator.Equals,
|
206
|
+
value: level
|
207
|
+
});
|
208
|
+
}
|
209
|
+
if (Is.stringValue(source)) {
|
210
|
+
condition.conditions.push({
|
211
|
+
property: "source",
|
212
|
+
comparison: ComparisonOperator.Equals,
|
213
|
+
value: source
|
214
|
+
});
|
215
|
+
}
|
216
|
+
if (Is.number(timeStart)) {
|
217
|
+
condition.conditions.push({
|
218
|
+
property: "ts",
|
219
|
+
comparison: ComparisonOperator.GreaterThanOrEqual,
|
220
|
+
value: timeStart
|
221
|
+
});
|
222
|
+
}
|
223
|
+
if (Is.number(timeEnd)) {
|
224
|
+
condition.conditions.push({
|
225
|
+
property: "ts",
|
226
|
+
comparison: ComparisonOperator.LessThanOrEqual,
|
227
|
+
value: timeEnd
|
228
|
+
});
|
229
|
+
}
|
230
|
+
const result = await this._loggingConnector.query(condition, [
|
231
|
+
{
|
232
|
+
property: "ts",
|
233
|
+
sortDirection: SortDirection.Descending
|
234
|
+
}
|
235
|
+
], undefined, cursor, pageSize);
|
236
|
+
return {
|
237
|
+
entities: result.entities,
|
238
|
+
cursor: result.cursor
|
239
|
+
};
|
240
|
+
}
|
241
|
+
}
|
242
|
+
|
243
|
+
const restEntryPoints = [
|
244
|
+
{
|
245
|
+
name: "logging",
|
246
|
+
defaultBaseRoute: "logging",
|
247
|
+
tags: tagsLogging,
|
248
|
+
generateRoutes: generateRestRoutesLogging
|
249
|
+
}
|
250
|
+
];
|
251
|
+
|
252
|
+
export { LoggingService, generateRestRoutesLogging, loggingCreate, loggingList, restEntryPoints, tagsLogging };
|
@@ -0,0 +1,29 @@
|
|
1
|
+
import type { IHttpRequestContext, INoContentResponse, IRestRoute, ITag } from "@twin.org/api-models";
|
2
|
+
import type { ILoggingCreateRequest, ILoggingListRequest, ILoggingListResponse } from "@twin.org/logging-models";
|
3
|
+
/**
|
4
|
+
* The tag to associate with the routes.
|
5
|
+
*/
|
6
|
+
export declare const tagsLogging: ITag[];
|
7
|
+
/**
|
8
|
+
* The REST routes for logging.
|
9
|
+
* @param baseRouteName Prefix to prepend to the paths.
|
10
|
+
* @param componentName The name of the component to use in the routes stored in the ComponentFactory.
|
11
|
+
* @returns The generated routes.
|
12
|
+
*/
|
13
|
+
export declare function generateRestRoutesLogging(baseRouteName: string, componentName: string): IRestRoute[];
|
14
|
+
/**
|
15
|
+
* Create a new log entry.
|
16
|
+
* @param httpRequestContext The request context for the API.
|
17
|
+
* @param componentName The name of the component to use in the routes.
|
18
|
+
* @param request The request.
|
19
|
+
* @returns The response object with additional http response properties.
|
20
|
+
*/
|
21
|
+
export declare function loggingCreate(httpRequestContext: IHttpRequestContext, componentName: string, request: ILoggingCreateRequest): Promise<INoContentResponse>;
|
22
|
+
/**
|
23
|
+
* Get a list of the logging entries.
|
24
|
+
* @param httpRequestContext The request context for the API.
|
25
|
+
* @param componentName The name of the component to use in the routes.
|
26
|
+
* @param request The request.
|
27
|
+
* @returns The response object with additional http response properties.
|
28
|
+
*/
|
29
|
+
export declare function loggingList(httpRequestContext: IHttpRequestContext, componentName: string, request: ILoggingListRequest): Promise<ILoggingListResponse>;
|
@@ -0,0 +1,48 @@
|
|
1
|
+
import { type ILogEntry, type ILoggingComponent, type LogLevel } from "@twin.org/logging-models";
|
2
|
+
import type { ILoggingServiceConstructorOptions } from "./models/ILoggingServiceConstructorOptions";
|
3
|
+
/**
|
4
|
+
* Service for performing logging operations to a connector.
|
5
|
+
*/
|
6
|
+
export declare class LoggingService implements ILoggingComponent {
|
7
|
+
/**
|
8
|
+
* The namespace for the logging component.
|
9
|
+
*/
|
10
|
+
static readonly NAMESPACE: string;
|
11
|
+
/**
|
12
|
+
* Runtime name for the class.
|
13
|
+
*/
|
14
|
+
readonly CLASS_NAME: string;
|
15
|
+
/**
|
16
|
+
* Create a new instance of LoggingService.
|
17
|
+
* @param options The options for the connector.
|
18
|
+
*/
|
19
|
+
constructor(options?: ILoggingServiceConstructorOptions);
|
20
|
+
/**
|
21
|
+
* Log an entry to the connector.
|
22
|
+
* @param logEntry The entry to log.
|
23
|
+
* @returns Nothing.
|
24
|
+
*/
|
25
|
+
log(logEntry: ILogEntry): Promise<void>;
|
26
|
+
/**
|
27
|
+
* Query the log entries.
|
28
|
+
* @param level The level of the log entries.
|
29
|
+
* @param source The source of the log entries.
|
30
|
+
* @param timeStart The inclusive time as the start of the log entries.
|
31
|
+
* @param timeEnd The inclusive time as the end of the log entries.
|
32
|
+
* @param cursor The cursor to request the next page of entities.
|
33
|
+
* @param pageSize The maximum number of entities in a page.
|
34
|
+
* @returns All the entities for the storage matching the conditions,
|
35
|
+
* and a cursor which can be used to request more entities.
|
36
|
+
* @throws NotImplementedError if the implementation does not support retrieval.
|
37
|
+
*/
|
38
|
+
query(level?: LogLevel, source?: string, timeStart?: number, timeEnd?: number, cursor?: string, pageSize?: number): Promise<{
|
39
|
+
/**
|
40
|
+
* The entities, which can be partial if a limited keys list was provided.
|
41
|
+
*/
|
42
|
+
entities: ILogEntry[];
|
43
|
+
/**
|
44
|
+
* An optional cursor, when defined can be used to call find to get more entities.
|
45
|
+
*/
|
46
|
+
cursor?: string;
|
47
|
+
}>;
|
48
|
+
}
|
package/docs/examples.md
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
# @twin.org/logging-service - Examples
|