sloplog 0.0.3
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 +204 -0
- package/dist/codegen.d.ts +43 -0
- package/dist/codegen.js +500 -0
- package/dist/collectors/betterstack.d.ts +47 -0
- package/dist/collectors/betterstack.js +74 -0
- package/dist/collectors/composite.d.ts +1 -0
- package/dist/collectors/composite.js +1 -0
- package/dist/collectors/file.d.ts +1 -0
- package/dist/collectors/file.js +1 -0
- package/dist/collectors/filtered.d.ts +1 -0
- package/dist/collectors/filtered.js +1 -0
- package/dist/collectors/index.d.ts +102 -0
- package/dist/collectors/index.js +127 -0
- package/dist/collectors/sentry.d.ts +46 -0
- package/dist/collectors/sentry.js +45 -0
- package/dist/collectors/stdio.d.ts +1 -0
- package/dist/collectors/stdio.js +1 -0
- package/dist/generated/partials.d.ts +40 -0
- package/dist/generated/partials.js +3 -0
- package/dist/index.d.ts +199 -0
- package/dist/index.js +354 -0
- package/dist/originator/index.d.ts +150 -0
- package/dist/originator/index.js +217 -0
- package/dist/partials.d.ts +154 -0
- package/dist/partials.js +52 -0
- package/dist/registry.d.ts +89 -0
- package/dist/registry.js +44 -0
- package/dist/wevt-0.0.1-py3-none-any.whl +0 -0
- package/dist/wevt-0.0.1.tar.gz +0 -0
- package/dist/wevt-0.0.2-py3-none-any.whl +0 -0
- package/dist/wevt-0.0.2.tar.gz +0 -0
- package/package.json +101 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
import { extractPartialMetadata } from './registry.js';
|
|
2
|
+
/**
|
|
3
|
+
* Generate a nano ID for unique identifiers
|
|
4
|
+
*/
|
|
5
|
+
function nanoId() {
|
|
6
|
+
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_';
|
|
7
|
+
let result = '';
|
|
8
|
+
for (let i = 0; i < 21; i++) {
|
|
9
|
+
result += chars[Math.floor(Math.random() * chars.length)];
|
|
10
|
+
}
|
|
11
|
+
return result;
|
|
12
|
+
}
|
|
13
|
+
/** Current sloplog library version (propagated onto Service). */
|
|
14
|
+
export const SLOPLOG_VERSION = '0.0.2';
|
|
15
|
+
/** Default language marker when Service.sloplogLanguage is not set. */
|
|
16
|
+
const SLOPLOG_LANGUAGE = 'typescript';
|
|
17
|
+
function isOriginatorResult(input) {
|
|
18
|
+
return (typeof input === 'object' &&
|
|
19
|
+
input !== null &&
|
|
20
|
+
'originator' in input &&
|
|
21
|
+
'traceId' in input &&
|
|
22
|
+
typeof input.traceId === 'string');
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Create a Service payload with sloplog defaults applied.
|
|
26
|
+
*/
|
|
27
|
+
export function service(details) {
|
|
28
|
+
return {
|
|
29
|
+
...details,
|
|
30
|
+
sloplogVersion: details.sloplogVersion ?? SLOPLOG_VERSION,
|
|
31
|
+
sloplogLanguage: details.sloplogLanguage ?? SLOPLOG_LANGUAGE,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
// Re-export originator types and functions
|
|
35
|
+
export {
|
|
36
|
+
// Constants
|
|
37
|
+
ORIGINATOR_HEADER, TRACE_ID_HEADER,
|
|
38
|
+
// Functions
|
|
39
|
+
httpOriginator, nodeHttpOriginator, cronOriginator, tracingHeaders, extractTracingContext, } from './originator/index.js';
|
|
40
|
+
// Collectors are exposed via subpath exports (sloplog/collectors/*).
|
|
41
|
+
// Re-export built-in partials registry and types
|
|
42
|
+
export { builtInPartials, builtInRegistry, builtInPartialMetadata } from './partials.js';
|
|
43
|
+
/**
|
|
44
|
+
* Zod-based DSL for defining wide event partials
|
|
45
|
+
* Restricted to only allow specific primitive types for cross-language compatibility
|
|
46
|
+
*/
|
|
47
|
+
export { z, partial, registry, extractPartialMetadata } from './registry.js';
|
|
48
|
+
// Re-export codegen functions
|
|
49
|
+
export { generateTypeScript, generatePython, generateJsonSchema } from './codegen.js';
|
|
50
|
+
export { config } from './codegen.js';
|
|
51
|
+
/**
|
|
52
|
+
* Core WideEvent class.
|
|
53
|
+
* Create one WideEvent per request or unit of work and add partials as you go.
|
|
54
|
+
* Use log() for structured partials or for lightweight log_message entries.
|
|
55
|
+
* @param R pass in a valid Registry type, which defines the wide event partials you may pass in
|
|
56
|
+
*/
|
|
57
|
+
export class WideEvent {
|
|
58
|
+
eventId;
|
|
59
|
+
traceId;
|
|
60
|
+
collector;
|
|
61
|
+
/** All partials - singular as objects, repeatable as arrays */
|
|
62
|
+
partials = new Map();
|
|
63
|
+
service;
|
|
64
|
+
originator;
|
|
65
|
+
openSpans = new Map();
|
|
66
|
+
/** Metadata about partials (repeatable, alwaysSample) */
|
|
67
|
+
partialMetadata;
|
|
68
|
+
/** Whether this event should always be sampled */
|
|
69
|
+
_alwaysSample = false;
|
|
70
|
+
/**
|
|
71
|
+
* Create a wide event
|
|
72
|
+
*
|
|
73
|
+
* @param service Service that the wide event is being emitted on
|
|
74
|
+
* @param originator Originator (i.e. request, schedule, etc) of the wide event
|
|
75
|
+
* @param collector Location to collect/flush logs to
|
|
76
|
+
* @param options Optional configuration including traceId and partialMetadata
|
|
77
|
+
*/
|
|
78
|
+
constructor(service, originator, collector, options = {}) {
|
|
79
|
+
this.eventId = `evt_${nanoId()}`;
|
|
80
|
+
this.traceId = options.traceId || `trace_${nanoId()}`;
|
|
81
|
+
this.service = {
|
|
82
|
+
...service,
|
|
83
|
+
sloplogVersion: service.sloplogVersion ?? SLOPLOG_VERSION,
|
|
84
|
+
sloplogLanguage: service.sloplogLanguage ?? SLOPLOG_LANGUAGE,
|
|
85
|
+
};
|
|
86
|
+
this.originator = originator;
|
|
87
|
+
this.collector = collector;
|
|
88
|
+
this.partialMetadata = options.partialMetadata ?? new Map();
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Check if this event should always be sampled
|
|
92
|
+
*/
|
|
93
|
+
get alwaysSample() {
|
|
94
|
+
return this._alwaysSample;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Manually mark this event to always be sampled
|
|
98
|
+
*/
|
|
99
|
+
markAlwaysSample() {
|
|
100
|
+
this._alwaysSample = true;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Add a partial to a wide event.
|
|
104
|
+
* For singular partials, this overwrites any existing partial of the same type.
|
|
105
|
+
* For repeatable partials, this appends to the array.
|
|
106
|
+
* If the partial has alwaysSample=true, the event will be marked to always be sampled.
|
|
107
|
+
* Overwriting a singular partial records a sloplog_usage_error.
|
|
108
|
+
*
|
|
109
|
+
* @param partial wide event partial to add
|
|
110
|
+
*/
|
|
111
|
+
partial(partial) {
|
|
112
|
+
this.addPartialInternal(partial);
|
|
113
|
+
}
|
|
114
|
+
log(arg1, arg2, arg3) {
|
|
115
|
+
if (typeof arg1 !== 'string') {
|
|
116
|
+
this.addPartialInternal(arg1);
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
let data;
|
|
120
|
+
if (typeof arg2 === 'string') {
|
|
121
|
+
data = arg2;
|
|
122
|
+
}
|
|
123
|
+
else if (arg2 !== undefined) {
|
|
124
|
+
try {
|
|
125
|
+
data = JSON.stringify(arg2);
|
|
126
|
+
}
|
|
127
|
+
catch {
|
|
128
|
+
this.addUsageError('log_message_stringify_error', 'Failed to stringify log data');
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
const level = arg3 ?? 'info';
|
|
132
|
+
this.addPartialInternal({
|
|
133
|
+
type: 'log_message',
|
|
134
|
+
message: arg1,
|
|
135
|
+
level,
|
|
136
|
+
...(data !== undefined ? { data } : {}),
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Add an error partial from an Error or message.
|
|
141
|
+
*/
|
|
142
|
+
error(error, code) {
|
|
143
|
+
if (typeof error === 'object' && error !== null) {
|
|
144
|
+
const maybePartial = error;
|
|
145
|
+
if (maybePartial.type === 'error' && typeof maybePartial.message === 'string') {
|
|
146
|
+
this.addPartialInternal(error);
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
const payload = {
|
|
151
|
+
type: 'error',
|
|
152
|
+
message: this.formatErrorMessage(error),
|
|
153
|
+
};
|
|
154
|
+
if (error instanceof Error && error.stack) {
|
|
155
|
+
payload.stack = error.stack;
|
|
156
|
+
}
|
|
157
|
+
else if (typeof error === 'object' &&
|
|
158
|
+
error !== null &&
|
|
159
|
+
typeof error.stack === 'string') {
|
|
160
|
+
payload.stack = error.stack;
|
|
161
|
+
}
|
|
162
|
+
const errorCode = typeof code === 'number'
|
|
163
|
+
? code
|
|
164
|
+
: typeof error === 'object' &&
|
|
165
|
+
error !== null &&
|
|
166
|
+
typeof error.code === 'number'
|
|
167
|
+
? error.code
|
|
168
|
+
: undefined;
|
|
169
|
+
if (typeof errorCode === 'number') {
|
|
170
|
+
payload.code = errorCode;
|
|
171
|
+
}
|
|
172
|
+
this.addPartialInternal(payload);
|
|
173
|
+
}
|
|
174
|
+
formatErrorMessage(error) {
|
|
175
|
+
if (typeof error === 'string') {
|
|
176
|
+
return error;
|
|
177
|
+
}
|
|
178
|
+
if (error instanceof Error) {
|
|
179
|
+
return error.message || 'Unknown error';
|
|
180
|
+
}
|
|
181
|
+
if (typeof error === 'object' && error !== null) {
|
|
182
|
+
const maybeMessage = error.message;
|
|
183
|
+
if (typeof maybeMessage === 'string') {
|
|
184
|
+
return maybeMessage;
|
|
185
|
+
}
|
|
186
|
+
try {
|
|
187
|
+
const serialized = JSON.stringify(error);
|
|
188
|
+
return typeof serialized === 'string' ? serialized : 'Unknown error';
|
|
189
|
+
}
|
|
190
|
+
catch {
|
|
191
|
+
return 'Unknown error';
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
return String(error);
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Time a span around a callback and emit a span partial.
|
|
198
|
+
* Unended spans are recorded as sloplog_usage_error on flush.
|
|
199
|
+
*/
|
|
200
|
+
async span(name, fn) {
|
|
201
|
+
this.spanStart(name);
|
|
202
|
+
try {
|
|
203
|
+
return await fn();
|
|
204
|
+
}
|
|
205
|
+
finally {
|
|
206
|
+
this.spanEnd(name);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Start a span by name
|
|
211
|
+
*/
|
|
212
|
+
spanStart(name) {
|
|
213
|
+
const startedAt = Date.now();
|
|
214
|
+
const existing = this.openSpans.get(name);
|
|
215
|
+
if (existing) {
|
|
216
|
+
existing.push(startedAt);
|
|
217
|
+
}
|
|
218
|
+
else {
|
|
219
|
+
this.openSpans.set(name, [startedAt]);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* End a span by name
|
|
224
|
+
* Ending a span that was never started records a sloplog_usage_error.
|
|
225
|
+
*/
|
|
226
|
+
spanEnd(name) {
|
|
227
|
+
const existing = this.openSpans.get(name);
|
|
228
|
+
if (!existing || existing.length === 0) {
|
|
229
|
+
this.addUsageError('span_end_without_start', `Span "${name}" ended without start`, {
|
|
230
|
+
spanName: name,
|
|
231
|
+
});
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
const startedAt = existing.pop();
|
|
235
|
+
if (startedAt === undefined) {
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
if (existing.length === 0) {
|
|
239
|
+
this.openSpans.delete(name);
|
|
240
|
+
}
|
|
241
|
+
const endedAt = Date.now();
|
|
242
|
+
const durationMs = endedAt - startedAt;
|
|
243
|
+
this.addPartialInternal({
|
|
244
|
+
type: 'span',
|
|
245
|
+
name,
|
|
246
|
+
startedAt,
|
|
247
|
+
endedAt,
|
|
248
|
+
durationMs,
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Get the current state of the wide event as a log object
|
|
253
|
+
*/
|
|
254
|
+
toLog() {
|
|
255
|
+
const result = {
|
|
256
|
+
eventId: this.eventId,
|
|
257
|
+
traceId: this.traceId,
|
|
258
|
+
service: this.service,
|
|
259
|
+
originator: this.originator,
|
|
260
|
+
};
|
|
261
|
+
for (const [key, value] of this.partials) {
|
|
262
|
+
result[key] = value;
|
|
263
|
+
}
|
|
264
|
+
return result;
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Emit the full wide log to the collector.
|
|
268
|
+
* Any usage errors (e.g. unended spans, partial overwrites) are emitted
|
|
269
|
+
* as sloplog_usage_error partials before flushing.
|
|
270
|
+
*/
|
|
271
|
+
async flush() {
|
|
272
|
+
this.recordOpenSpans();
|
|
273
|
+
await this.collector.flush({
|
|
274
|
+
eventId: this.eventId,
|
|
275
|
+
traceId: this.traceId,
|
|
276
|
+
originator: this.originator,
|
|
277
|
+
service: this.service,
|
|
278
|
+
}, this.partials, { alwaysSample: this._alwaysSample });
|
|
279
|
+
}
|
|
280
|
+
addPartialInternal(partial) {
|
|
281
|
+
const metadata = this.partialMetadata.get(partial.type);
|
|
282
|
+
const isRepeatable = metadata?.repeatable ?? this.isRepeatableFallback(partial.type);
|
|
283
|
+
if (metadata?.alwaysSample || this.isAlwaysSampleFallback(partial.type)) {
|
|
284
|
+
this._alwaysSample = true;
|
|
285
|
+
}
|
|
286
|
+
if (isRepeatable) {
|
|
287
|
+
this.appendRepeatablePartial(partial.type, partial);
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
if (this.partials.has(partial.type)) {
|
|
291
|
+
this.addUsageError('partial_overwrite', `Partial "${partial.type}" was overwritten`, {
|
|
292
|
+
partialType: partial.type,
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
this.partials.set(partial.type, partial);
|
|
296
|
+
}
|
|
297
|
+
appendRepeatablePartial(type, partial) {
|
|
298
|
+
const existing = this.partials.get(type);
|
|
299
|
+
if (Array.isArray(existing)) {
|
|
300
|
+
existing.push(partial);
|
|
301
|
+
return;
|
|
302
|
+
}
|
|
303
|
+
if (existing) {
|
|
304
|
+
this.partials.set(type, [existing, partial]);
|
|
305
|
+
return;
|
|
306
|
+
}
|
|
307
|
+
this.partials.set(type, [partial]);
|
|
308
|
+
}
|
|
309
|
+
isRepeatableFallback(type) {
|
|
310
|
+
return (type === 'error' ||
|
|
311
|
+
type === 'log_message' ||
|
|
312
|
+
type === 'span' ||
|
|
313
|
+
type === 'sloplog_usage_error');
|
|
314
|
+
}
|
|
315
|
+
isAlwaysSampleFallback(type) {
|
|
316
|
+
return type === 'error';
|
|
317
|
+
}
|
|
318
|
+
addUsageError(kind, message, details = {}) {
|
|
319
|
+
this.appendRepeatablePartial('sloplog_usage_error', {
|
|
320
|
+
type: 'sloplog_usage_error',
|
|
321
|
+
kind,
|
|
322
|
+
message,
|
|
323
|
+
...details,
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
recordOpenSpans() {
|
|
327
|
+
if (this.openSpans.size === 0) {
|
|
328
|
+
return;
|
|
329
|
+
}
|
|
330
|
+
for (const [name, starts] of this.openSpans) {
|
|
331
|
+
for (const startedAt of starts) {
|
|
332
|
+
this.addUsageError('span_unended', `Span "${name}" was started but never ended`, {
|
|
333
|
+
spanName: name,
|
|
334
|
+
startedAt,
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
this.openSpans.clear();
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
/**
|
|
342
|
+
* Create a WideEvent instance. Prefer this factory over class construction.
|
|
343
|
+
* Provide the registry first to infer partial types and repeatable metadata.
|
|
344
|
+
* originator can be a raw Originator or the { originator, traceId } result from httpOriginator().
|
|
345
|
+
*/
|
|
346
|
+
export function wideEvent(registry, service, originator, collector, options = {}) {
|
|
347
|
+
const resolvedOriginator = isOriginatorResult(originator) ? originator.originator : originator;
|
|
348
|
+
const traceId = options.traceId ?? (isOriginatorResult(originator) ? originator.traceId : undefined);
|
|
349
|
+
const partialMetadata = options.partialMetadata ?? extractPartialMetadata(registry);
|
|
350
|
+
return new WideEvent(service, resolvedOriginator, collector, {
|
|
351
|
+
traceId,
|
|
352
|
+
partialMetadata,
|
|
353
|
+
});
|
|
354
|
+
}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Originator module - functions for creating originators from various sources
|
|
3
|
+
*/
|
|
4
|
+
/** HTTP method types */
|
|
5
|
+
export type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'HEAD' | 'OPTIONS';
|
|
6
|
+
/**
|
|
7
|
+
* Base originator interface - an external thing that triggered your service
|
|
8
|
+
* This is like a trace that can cross service boundaries
|
|
9
|
+
*/
|
|
10
|
+
export interface Originator {
|
|
11
|
+
/** Unique identifier for this originator chain (propagates across services) */
|
|
12
|
+
originatorId: string;
|
|
13
|
+
/** Type discriminator for the originator */
|
|
14
|
+
type: string;
|
|
15
|
+
/** Timestamp when the originator was created (Unix ms) */
|
|
16
|
+
timestamp: number;
|
|
17
|
+
/** Parent originator ID if this is a child span */
|
|
18
|
+
parentId?: string;
|
|
19
|
+
[key: string]: unknown;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* HTTP request originator
|
|
23
|
+
*/
|
|
24
|
+
export interface HttpOriginator extends Originator {
|
|
25
|
+
type: 'http';
|
|
26
|
+
method: HttpMethod;
|
|
27
|
+
path: string;
|
|
28
|
+
/** Query string (without leading ?) */
|
|
29
|
+
query?: string;
|
|
30
|
+
/** Request headers */
|
|
31
|
+
headers?: Record<string, string>;
|
|
32
|
+
/** Client IP address */
|
|
33
|
+
clientIp?: string;
|
|
34
|
+
/** User agent string */
|
|
35
|
+
userAgent?: string;
|
|
36
|
+
/** Content type of the request */
|
|
37
|
+
contentType?: string;
|
|
38
|
+
/** Content length in bytes */
|
|
39
|
+
contentLength?: number;
|
|
40
|
+
/** HTTP protocol version (e.g., "1.1", "2") */
|
|
41
|
+
httpVersion?: string;
|
|
42
|
+
/** Host header value */
|
|
43
|
+
host?: string;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* WebSocket message originator
|
|
47
|
+
*/
|
|
48
|
+
export interface WebSocketOriginator extends Originator {
|
|
49
|
+
type: 'websocket';
|
|
50
|
+
/** WebSocket session/connection ID */
|
|
51
|
+
sessionId: string;
|
|
52
|
+
/** Message source identifier */
|
|
53
|
+
source: string;
|
|
54
|
+
/** Message type (e.g., "text", "binary") */
|
|
55
|
+
messageType?: 'text' | 'binary';
|
|
56
|
+
/** Size of the message in bytes */
|
|
57
|
+
messageSize?: number;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Cron/scheduled task originator
|
|
61
|
+
*/
|
|
62
|
+
export interface CronOriginator extends Originator {
|
|
63
|
+
type: 'cron';
|
|
64
|
+
/** Cron expression (e.g., "0 0 * * *") */
|
|
65
|
+
cron: string;
|
|
66
|
+
/** Name of the scheduled job */
|
|
67
|
+
jobName?: string;
|
|
68
|
+
/** Scheduled execution time (Unix ms) */
|
|
69
|
+
scheduledTime?: number;
|
|
70
|
+
}
|
|
71
|
+
/** Header name for propagating originator ID across services */
|
|
72
|
+
export declare const ORIGINATOR_HEADER = "x-sloplog-originator";
|
|
73
|
+
/** Header name for propagating trace ID across services */
|
|
74
|
+
export declare const TRACE_ID_HEADER = "x-sloplog-trace-id";
|
|
75
|
+
/**
|
|
76
|
+
* Tracing context to propagate across services
|
|
77
|
+
*/
|
|
78
|
+
export interface TracingContext {
|
|
79
|
+
/** The trace ID (stays constant across the entire distributed trace) */
|
|
80
|
+
traceId: string;
|
|
81
|
+
/** The originator ID of the calling service (becomes parentId in the callee) */
|
|
82
|
+
originatorId: string;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Create headers for propagating tracing context to downstream services
|
|
86
|
+
*/
|
|
87
|
+
export declare function tracingHeaders(context: TracingContext): Record<string, string>;
|
|
88
|
+
/**
|
|
89
|
+
* Extract tracing context from incoming request headers
|
|
90
|
+
* Returns null if no tracing headers are present
|
|
91
|
+
*/
|
|
92
|
+
export declare function extractTracingContext(headers: Record<string, string | string[] | undefined>): TracingContext | null;
|
|
93
|
+
/**
|
|
94
|
+
* Options for creating an HTTP originator
|
|
95
|
+
*/
|
|
96
|
+
export interface HttpOriginatorOptions {
|
|
97
|
+
/** Override the originator ID (useful when continuing a trace) */
|
|
98
|
+
originatorId?: string;
|
|
99
|
+
/** Parent originator ID (for child originators) */
|
|
100
|
+
parentId?: string;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Result of creating an originator from an incoming request
|
|
104
|
+
* Contains both the originator and the extracted traceId (if any)
|
|
105
|
+
*/
|
|
106
|
+
export interface OriginatorFromRequestResult {
|
|
107
|
+
/** The created HTTP originator */
|
|
108
|
+
originator: HttpOriginator;
|
|
109
|
+
/** The trace ID extracted from headers, or a newly generated one */
|
|
110
|
+
traceId: string;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Create an HTTP originator from a Web Fetch API Request
|
|
114
|
+
* Extracts tracing context from headers if present:
|
|
115
|
+
* - traceId: extracted from x-sloplog-trace-id header, or generated if not present
|
|
116
|
+
* - parentId: set to the incoming x-sloplog-originator header value (the caller's originatorId),
|
|
117
|
+
* or can be explicitly provided via options.parentId
|
|
118
|
+
*/
|
|
119
|
+
export declare function httpOriginator(request: Request, options?: HttpOriginatorOptions): OriginatorFromRequestResult;
|
|
120
|
+
/**
|
|
121
|
+
* Node.js IncomingMessage-like interface
|
|
122
|
+
*/
|
|
123
|
+
export interface NodeIncomingMessage {
|
|
124
|
+
method?: string;
|
|
125
|
+
url?: string;
|
|
126
|
+
headers: Record<string, string | string[] | undefined>;
|
|
127
|
+
httpVersion?: string;
|
|
128
|
+
socket?: {
|
|
129
|
+
remoteAddress?: string;
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Create an HTTP originator from a Node.js IncomingMessage (http/https/express)
|
|
134
|
+
* Extracts tracing context from headers if present:
|
|
135
|
+
* - traceId: extracted from x-sloplog-trace-id header, or generated if not present
|
|
136
|
+
* - parentId: set to the incoming x-sloplog-originator header value (the caller's originatorId),
|
|
137
|
+
* or can be explicitly provided via options.parentId
|
|
138
|
+
*/
|
|
139
|
+
export declare function nodeHttpOriginator(request: NodeIncomingMessage, options?: HttpOriginatorOptions): OriginatorFromRequestResult;
|
|
140
|
+
/**
|
|
141
|
+
* Options for creating a cron originator
|
|
142
|
+
*/
|
|
143
|
+
export interface CronOriginatorOptions {
|
|
144
|
+
/** Parent originator ID (for child originators) */
|
|
145
|
+
parentId?: string;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Create a cron originator for scheduled tasks
|
|
149
|
+
*/
|
|
150
|
+
export declare function cronOriginator(cron: string, jobName?: string, options?: CronOriginatorOptions): CronOriginator;
|