@redthreadlabs/tracelog-schema 0.3.0 → 0.4.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/keys.d.ts +6 -6
- package/dist/kinds.d.ts +12 -4
- package/dist/kinds.js +8 -1
- package/dist/wire.d.ts +131 -46
- package/package.json +1 -1
package/dist/keys.d.ts
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
* for the live snapshot. `buildKey` and `parseKey` are exact inverses so the
|
|
16
16
|
* agent and viewer never drift on this layout.
|
|
17
17
|
*/
|
|
18
|
-
export interface
|
|
18
|
+
export interface ObjectKeyVars {
|
|
19
19
|
channel: string;
|
|
20
20
|
interval: string;
|
|
21
21
|
host: string;
|
|
@@ -24,7 +24,7 @@ export interface KeyVars {
|
|
|
24
24
|
/** the live, still-being-written snapshot */
|
|
25
25
|
current?: boolean;
|
|
26
26
|
}
|
|
27
|
-
export interface
|
|
27
|
+
export interface ParsedObjectKey {
|
|
28
28
|
key: string;
|
|
29
29
|
channel: string;
|
|
30
30
|
interval: string;
|
|
@@ -37,12 +37,12 @@ export interface ParsedKey {
|
|
|
37
37
|
etag?: string;
|
|
38
38
|
}
|
|
39
39
|
/** Build a log object's key. Pass `gzip` to append the `.gz` suffix. */
|
|
40
|
-
export declare function buildKey(vars:
|
|
40
|
+
export declare function buildKey(vars: ObjectKeyVars, gzip?: boolean): string;
|
|
41
41
|
/**
|
|
42
42
|
* Parse a log object's key back into its parts, or null if it is not a log
|
|
43
43
|
* file in the known grammar (e.g. a sidecar `.meta.json`, or anything else).
|
|
44
44
|
*/
|
|
45
|
-
export declare function parseKey(key: string, size?: number, lastModified?: Date, etag?: string):
|
|
45
|
+
export declare function parseKey(key: string, size?: number, lastModified?: Date, etag?: string): ParsedObjectKey | null;
|
|
46
46
|
/**
|
|
47
47
|
* The UTC time span an interval label covers: daily `YYYY-MM-DD` → 24 h,
|
|
48
48
|
* hourly `YYYY-MM-DDTHH` → 1 h. Unknown grammar → null (callers should be
|
|
@@ -50,14 +50,14 @@ export declare function parseKey(key: string, size?: number, lastModified?: Date
|
|
|
50
50
|
*/
|
|
51
51
|
export declare function intervalSpan(interval: string): [number, number] | null;
|
|
52
52
|
/** Whether a file's interval overlaps [startMs, endMs]. Unknown layout → kept. */
|
|
53
|
-
export declare function overlapsRange(file: Pick<
|
|
53
|
+
export declare function overlapsRange(file: Pick<ParsedObjectKey, 'interval'>, startMs: number, endMs: number): boolean;
|
|
54
54
|
/**
|
|
55
55
|
* Drop `_current` snapshots shadowed by their finalized file: if the finalized
|
|
56
56
|
* key exists, ignore the (briefly surviving) `_current`. A `_current` with no
|
|
57
57
|
* finalized sibling is kept — it is either live (today) or a dead host's only
|
|
58
58
|
* copy.
|
|
59
59
|
*/
|
|
60
|
-
export declare function dedupeCurrents<T extends Pick<
|
|
60
|
+
export declare function dedupeCurrents<T extends Pick<ParsedObjectKey, 'channel' | 'interval' | 'host' | 'seq' | 'current'>>(files: T[]): T[];
|
|
61
61
|
/**
|
|
62
62
|
* Normalize a hostname into the host label used in keys. EC2 internal
|
|
63
63
|
* hostnames (`ip-A-B-C-D[.…]`) become the dotted IP — which avoids embedding
|
package/dist/kinds.d.ts
CHANGED
|
@@ -1,9 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The record kinds
|
|
3
|
-
*
|
|
4
|
-
*
|
|
2
|
+
* The DATA record kinds — the single top-level key of a data NDJSON line:
|
|
3
|
+
* `{ "<kind>": { ...fields... } }`. These are what the sidecar histogram counts.
|
|
4
|
+
* `metadata` is deliberately NOT here: it's a dimension/context record, not data
|
|
5
|
+
* (see {@link METADATA_KIND}).
|
|
5
6
|
*/
|
|
6
7
|
export type RecordKind = 'transaction' | 'span' | 'error' | 'event' | 'metricset';
|
|
7
8
|
export declare const RECORD_KINDS: readonly RecordKind[];
|
|
8
|
-
/**
|
|
9
|
+
/**
|
|
10
|
+
* The `metadata` line's kind: `{ "metadata": <RecordOrigin> }` — it carries a
|
|
11
|
+
* RecordOrigin (service + environment), not data. It appears in two scopes:
|
|
12
|
+
* - the per-file header (file-scoped — the writer's origin), and
|
|
13
|
+
* - in-stream (lifetime-scoped — a client's per-launch origin, keyed by
|
|
14
|
+
* `lifetime_id`), which records join to.
|
|
15
|
+
* Excluded from RECORD_KINDS and the sidecar histogram (it isn't a data record).
|
|
16
|
+
*/
|
|
9
17
|
export declare const METADATA_KIND = "metadata";
|
package/dist/kinds.js
CHANGED
|
@@ -12,5 +12,12 @@ exports.RECORD_KINDS = [
|
|
|
12
12
|
'event',
|
|
13
13
|
'metricset',
|
|
14
14
|
];
|
|
15
|
-
/**
|
|
15
|
+
/**
|
|
16
|
+
* The `metadata` line's kind: `{ "metadata": <RecordOrigin> }` — it carries a
|
|
17
|
+
* RecordOrigin (service + environment), not data. It appears in two scopes:
|
|
18
|
+
* - the per-file header (file-scoped — the writer's origin), and
|
|
19
|
+
* - in-stream (lifetime-scoped — a client's per-launch origin, keyed by
|
|
20
|
+
* `lifetime_id`), which records join to.
|
|
21
|
+
* Excluded from RECORD_KINDS and the sidecar histogram (it isn't a data record).
|
|
22
|
+
*/
|
|
16
23
|
exports.METADATA_KIND = 'metadata';
|
package/dist/wire.d.ts
CHANGED
|
@@ -1,30 +1,69 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The wire format for the `POST /logs` ingest endpoint: what a remote client
|
|
3
|
-
* (browser, React Native) sends
|
|
4
|
-
*
|
|
5
|
-
*
|
|
3
|
+
* (browser, React Native) sends. Defined here so the client SDK, the server, and
|
|
4
|
+
* the viewer all share one definition.
|
|
5
|
+
*
|
|
6
|
+
* The wire records ARE (modulo a few server-stamped fields) the on-disk records,
|
|
7
|
+
* in the same units — timestamps are epoch MICROSECONDS, durations are
|
|
8
|
+
* MILLISECONDS — so the ingest endpoint forwards them as-is rather than
|
|
9
|
+
* unwrapping and re-wrapping each one. The server's only per-record job is to
|
|
10
|
+
* stamp batch-level facts it owns (lifetime_id, context.user from the JWT, the
|
|
11
|
+
* source IP) and write to the channel.
|
|
6
12
|
*/
|
|
7
13
|
export type JsonValue = string | number | boolean | null | JsonValue[] | {
|
|
8
14
|
[key: string]: JsonValue;
|
|
9
15
|
};
|
|
10
16
|
export type LogLevel = 'debug' | 'info' | 'warn' | 'error';
|
|
11
|
-
export interface
|
|
12
|
-
client: ClientInfo;
|
|
17
|
+
export interface RecordBatch {
|
|
13
18
|
user_id?: string;
|
|
14
|
-
|
|
19
|
+
/**
|
|
20
|
+
* Opaque, consumer-defined identifier for the device or installation — an
|
|
21
|
+
* app's own id, a hardware id, whatever the consumer chooses. The framework
|
|
22
|
+
* treats it as an opaque string and never interprets it.
|
|
23
|
+
*/
|
|
15
24
|
device_id?: string;
|
|
16
|
-
|
|
17
|
-
|
|
25
|
+
/**
|
|
26
|
+
* Id for this SDK lifetime (one app launch / process run), generated by the
|
|
27
|
+
* SDK. The join key between records and the once-per-lifetime `metadata`
|
|
28
|
+
* record that carries this launch's RecordOrigin.
|
|
29
|
+
*/
|
|
30
|
+
lifetime_id?: string;
|
|
31
|
+
/**
|
|
32
|
+
* This lifetime's RecordOrigin (service + environment). Sent on the first
|
|
33
|
+
* batch of a launch and again when it changes; the server writes it as an
|
|
34
|
+
* in-stream `metadata` record keyed by `lifetime_id`.
|
|
35
|
+
*/
|
|
36
|
+
origin?: RecordOrigin;
|
|
37
|
+
events: EventRecord[];
|
|
38
|
+
transactions: TransactionRecord[];
|
|
39
|
+
spans: SpanRecord[];
|
|
18
40
|
}
|
|
19
|
-
|
|
41
|
+
/**
|
|
42
|
+
* Per-record context, shared by every record kind. `labels` is the arbitrary
|
|
43
|
+
* key-value attribute bag; `user` is the identity the record is attributed to.
|
|
44
|
+
* Mirrors the agent's native `context.labels` / `context.user`.
|
|
45
|
+
*/
|
|
46
|
+
export interface RecordContext {
|
|
47
|
+
/** Arbitrary key-value attributes. */
|
|
48
|
+
labels?: Record<string, JsonValue>;
|
|
49
|
+
/** The user this record is attributed to. */
|
|
50
|
+
user?: {
|
|
51
|
+
id?: string;
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* A discrete log entry — something that happened at an instant: a log line or a
|
|
56
|
+
* behavioral event, carrying a level, message, and context labels. Events are
|
|
57
|
+
* NOT timed: a timed operation is a transaction/span, never an event with a
|
|
58
|
+
* duration.
|
|
59
|
+
*/
|
|
60
|
+
export interface EventRecord {
|
|
20
61
|
/** Event category, e.g. 'auth', 'billing', 'startup'. Default: 'client-log' */
|
|
21
62
|
type: string;
|
|
22
|
-
/** Epoch
|
|
63
|
+
/** Epoch microseconds */
|
|
23
64
|
timestamp: number;
|
|
24
65
|
level: LogLevel;
|
|
25
66
|
message: string;
|
|
26
|
-
/** Duration in milliseconds (for timed events that aren't span-shaped) */
|
|
27
|
-
duration?: number;
|
|
28
67
|
/** Serialized error info. `code` is the structured error code. */
|
|
29
68
|
error?: {
|
|
30
69
|
message: string;
|
|
@@ -32,8 +71,10 @@ export interface LogEventItem {
|
|
|
32
71
|
code?: string;
|
|
33
72
|
stack?: string;
|
|
34
73
|
};
|
|
35
|
-
/**
|
|
36
|
-
|
|
74
|
+
/** UI locale at record time, e.g. 'en-US'. Can change mid-launch, so per-event. */
|
|
75
|
+
locale?: string;
|
|
76
|
+
/** Labels + user (see RecordContext). */
|
|
77
|
+
context?: RecordContext;
|
|
37
78
|
/**
|
|
38
79
|
* Minutes east of UTC at the moment the event was recorded (ISO-8601 sign:
|
|
39
80
|
* `localWallClock = UTC + tz_offset`). Captured per-event because buffered
|
|
@@ -42,55 +83,99 @@ export interface LogEventItem {
|
|
|
42
83
|
*/
|
|
43
84
|
tz_offset?: number;
|
|
44
85
|
}
|
|
45
|
-
|
|
46
|
-
|
|
86
|
+
/**
|
|
87
|
+
* A root timed operation — the top of a trace (a request, a job, an agent run).
|
|
88
|
+
* Recorded as a `transaction`. Child work hangs off it as {@link SpanRecord}s.
|
|
89
|
+
*/
|
|
90
|
+
export interface TransactionRecord {
|
|
91
|
+
/** 16-char hex ID, generated client-side. Also the trace's root id. */
|
|
47
92
|
id: string;
|
|
48
|
-
/** 32-char hex trace ID, shared by
|
|
93
|
+
/** 32-char hex trace ID, shared by the whole trace */
|
|
49
94
|
trace_id: string;
|
|
50
|
-
/**
|
|
51
|
-
root_id: string;
|
|
52
|
-
/** 16-char hex ID of parent perf (absent for root perfs) */
|
|
53
|
-
parent_id?: string;
|
|
54
|
-
/** Operation name, e.g. 'content-store-startup' */
|
|
95
|
+
/** Operation name, e.g. 'parallel-search' */
|
|
55
96
|
name: string;
|
|
56
|
-
/**
|
|
97
|
+
/** Transaction type, e.g. 'request', 'agent', 'app'. Default: 'app' */
|
|
57
98
|
type: string;
|
|
58
|
-
/** Start time, epoch
|
|
99
|
+
/** Start time, epoch microseconds */
|
|
59
100
|
timestamp: number;
|
|
60
101
|
/** Duration in milliseconds */
|
|
61
102
|
duration: number;
|
|
62
103
|
outcome: 'success' | 'failure' | 'unknown';
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
/** Minutes east of UTC at record time (see LogEventItem.tz_offset). */
|
|
104
|
+
/** Labels + user (see RecordContext). */
|
|
105
|
+
context?: RecordContext;
|
|
106
|
+
/** Minutes east of UTC at record time (see EventRecord.tz_offset). */
|
|
67
107
|
tz_offset?: number;
|
|
68
108
|
}
|
|
69
|
-
|
|
70
|
-
|
|
109
|
+
/**
|
|
110
|
+
* A timed sub-operation within a transaction — recorded as a `span`. Always has
|
|
111
|
+
* a parent (its transaction, or another span) and belongs to one transaction.
|
|
112
|
+
*/
|
|
113
|
+
export interface SpanRecord {
|
|
114
|
+
/** 16-char hex ID, generated client-side */
|
|
115
|
+
id: string;
|
|
116
|
+
/** 32-char hex trace ID, shared by the whole trace */
|
|
117
|
+
trace_id: string;
|
|
118
|
+
/** ID of the transaction (trace root) this span belongs to */
|
|
119
|
+
transaction_id: string;
|
|
120
|
+
/** 16-char hex ID of the immediate parent (the transaction or another span) */
|
|
121
|
+
parent_id: string;
|
|
122
|
+
/** Operation name, e.g. 'search:hanzi' */
|
|
71
123
|
name: string;
|
|
72
|
-
/**
|
|
73
|
-
|
|
74
|
-
|
|
124
|
+
/** Span type, e.g. 'db', 'external', 'app'. Default: 'app' */
|
|
125
|
+
type: string;
|
|
126
|
+
/** Start time, epoch microseconds */
|
|
127
|
+
timestamp: number;
|
|
128
|
+
/** Duration in milliseconds */
|
|
129
|
+
duration: number;
|
|
130
|
+
outcome: 'success' | 'failure' | 'unknown';
|
|
131
|
+
/** Labels + user (see RecordContext). */
|
|
132
|
+
context?: RecordContext;
|
|
133
|
+
/** Minutes east of UTC at record time (see EventRecord.tz_offset). */
|
|
134
|
+
tz_offset?: number;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Describes who/what produced records — a service and its environment. Carried
|
|
138
|
+
* by a `metadata` record in two scopes: the per-file header (the writer's
|
|
139
|
+
* origin, file-scoped) and, for a client, in-stream once per launch keyed by
|
|
140
|
+
* `lifetime_id`. Records don't carry the origin; they carry `lifetime_id` (or,
|
|
141
|
+
* server-side, sit in the file) and join to it.
|
|
142
|
+
*
|
|
143
|
+
* `service` + `runtime` are the common core; `host` is server-flavored; `device`
|
|
144
|
+
* is client-flavored. (locale/timezone are NOT here — they can change mid-launch,
|
|
145
|
+
* so they live per-record: `EventRecord.locale` and `tz_offset`.)
|
|
146
|
+
*/
|
|
147
|
+
export interface RecordOrigin {
|
|
148
|
+
/** The SDK lifetime (app launch / process run) this RecordOrigin describes. Join key. */
|
|
149
|
+
lifetime_id?: string;
|
|
150
|
+
/** Application / service name + version. */
|
|
151
|
+
service: {
|
|
75
152
|
name: string;
|
|
76
153
|
version: string;
|
|
77
154
|
};
|
|
78
|
-
|
|
79
|
-
model?: string;
|
|
80
|
-
brand?: string;
|
|
81
|
-
type: string;
|
|
82
|
-
};
|
|
155
|
+
/** Runtime, e.g. 'react-native', 'node', 'browser'. */
|
|
83
156
|
runtime: {
|
|
84
157
|
name: string;
|
|
85
158
|
version: string;
|
|
86
159
|
};
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
160
|
+
os?: {
|
|
161
|
+
name: string;
|
|
162
|
+
version: string;
|
|
163
|
+
};
|
|
164
|
+
/** Server-flavored: the host the service runs on. */
|
|
165
|
+
host?: {
|
|
166
|
+
name?: string;
|
|
167
|
+
};
|
|
168
|
+
/** Client-flavored: the device the app runs on. */
|
|
169
|
+
device?: {
|
|
170
|
+
model?: string;
|
|
171
|
+
brand?: string;
|
|
172
|
+
type?: string;
|
|
173
|
+
/** Device performance tier. */
|
|
174
|
+
year_class?: number;
|
|
175
|
+
screen?: {
|
|
176
|
+
width: number;
|
|
177
|
+
height: number;
|
|
178
|
+
pixel_ratio: number;
|
|
179
|
+
};
|
|
91
180
|
};
|
|
92
|
-
locale?: string;
|
|
93
|
-
/** IANA timezone name for the session, e.g. 'America/New_York'. */
|
|
94
|
-
timezone?: string;
|
|
95
|
-
device_year_class?: number;
|
|
96
181
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@redthreadlabs/tracelog-schema",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Shared contract for the tracelog suite: record kinds, S3 key layout, metadata sidecar, and the /logs wire format",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"registry": "https://registry.npmjs.org/",
|