h1v3 0.7.2 → 0.7.4
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/browser/client/context.js +2 -1
- package/dist/browser/client/id.js +1 -1
- package/dist/browser/client/logger.js +32 -26
- package/package.json +1 -1
- package/src/client/node.js +1 -1
- package/src/{event-store/configuration.js → configuration/configure-eventStore.js} +4 -10
- package/src/configuration/configure-metadata-endpoint.js +48 -0
- package/src/{configuration.js → configuration/configure-o11y-store.js} +65 -86
- package/src/{load-configuration.js → configuration/load-configuration.js} +2 -2
- package/src/{rules.js → configuration/rules.js} +1 -1
- package/src/exec-eventstore.js +1 -1
- package/src/index.js +4 -6
- package/src/membership/team-details/store.js +1 -1
- package/src/membership/team-membership/store.js +1 -1
- package/src/membership/user-profile/store.js +1 -1
- package/src/membership/user-teams/store.js +1 -1
- package/src/membership/userInvites/store.js +1 -1
- package/src/observability/index.js +13 -11
- package/src/system/main.js +1 -1
- /package/src/{paths.js → configuration/paths.js} +0 -0
|
@@ -26,7 +26,8 @@ export async function inject({ database, authentication, metaURL, handleError =
|
|
|
26
26
|
if (!metaURL) throw new Error("Missing metaURL");
|
|
27
27
|
if (!authentication) throw new Error("Missing authentication");
|
|
28
28
|
|
|
29
|
-
const meta = await fetch(metaURL).then(resp => resp.json())
|
|
29
|
+
// const meta = await fetch(metaURL).then(resp => resp.json())
|
|
30
|
+
const { default: meta } = await import(metaURL, { with: { type: "json" } });
|
|
30
31
|
|
|
31
32
|
const log = logger(database, authentication, meta.o11y.path);
|
|
32
33
|
const teamMembershipStoreFactory = ({ tid }) => eventStore(database, authentication, populateParameters({ tid }, meta.team.membership.path));
|
|
@@ -14,25 +14,35 @@ function munge(attributes) {
|
|
|
14
14
|
export function logger(database, authentication, path, defaultAttributes) {
|
|
15
15
|
|
|
16
16
|
const { db, ref, set } = database;
|
|
17
|
+
const { auth } = authentication;
|
|
17
18
|
|
|
18
|
-
async function recordLog(
|
|
19
|
-
|
|
20
|
-
const span_id = generateSpanId();
|
|
21
|
-
console.log(defaultAttributes, sharedAttributes, attributes);
|
|
22
|
-
const data = {
|
|
23
|
-
meta: { uid: authentication.auth.currentUser.uid },
|
|
24
|
-
body,
|
|
25
|
-
trace_id,
|
|
26
|
-
span_id,
|
|
27
|
-
severity_text: level,
|
|
28
|
-
time_client_ms: Date.now(),
|
|
29
|
-
attributes: munge({ ...defaultAttributes, ...sharedAttributes, ...attributes })
|
|
30
|
-
};
|
|
31
|
-
if (parent_id) data.parent_id = parent_id;
|
|
32
|
-
const refPath = path.replace("$id", timeId());
|
|
33
|
-
console.log("Logging", data, "to", refPath);
|
|
34
|
-
return await set(ref(db, refPath), data);
|
|
19
|
+
async function recordLog(traceId, level, sharedAttributes, { message, parentSpanId, spanId, attributes }) {
|
|
35
20
|
|
|
21
|
+
let data;
|
|
22
|
+
try {
|
|
23
|
+
|
|
24
|
+
const uid = auth?.currentUser?.uid;
|
|
25
|
+
if (!uid) throw new Error("No current user id. Is the user logged in?");
|
|
26
|
+
|
|
27
|
+
spanId = spanId || generateSpanId();
|
|
28
|
+
data = {
|
|
29
|
+
meta: { uid },
|
|
30
|
+
message,
|
|
31
|
+
traceId,
|
|
32
|
+
spanId,
|
|
33
|
+
severity_text: level,
|
|
34
|
+
time_client_ms: Date.now(),
|
|
35
|
+
attributes: munge({ ...defaultAttributes, ...sharedAttributes, ...attributes })
|
|
36
|
+
};
|
|
37
|
+
if (parentSpanId) data.parentSpanId = parentSpanId;
|
|
38
|
+
const refPath = path.replace("$id", `${traceId}-${spanId}`);
|
|
39
|
+
return await set(ref(db, refPath), data);
|
|
40
|
+
|
|
41
|
+
} catch(err) {
|
|
42
|
+
|
|
43
|
+
console.error("Error dispatching o11y message", data, err);
|
|
44
|
+
|
|
45
|
+
}
|
|
36
46
|
|
|
37
47
|
}
|
|
38
48
|
|
|
@@ -41,17 +51,13 @@ export function logger(database, authentication, path, defaultAttributes) {
|
|
|
41
51
|
context(sharedAttributes) {
|
|
42
52
|
|
|
43
53
|
const id = generateTraceId();
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
info: recordLog.bind(this, id, "INFO", sharedAttributes),
|
|
49
|
-
warn: recordLog.bind(this, id, "WARN", sharedAttributes),
|
|
50
|
-
error: recordLog.bind(this, id, "ERROR", sharedAttributes),
|
|
51
|
-
fatal: recordLog.bind(this, id, "FATAL", sharedAttributes)
|
|
52
|
-
};
|
|
54
|
+
const ret = { id };
|
|
55
|
+
for(const x of ["debug", "info", "notice", "warning", "error", "critical", "alert", "emergency"])
|
|
56
|
+
ret[x] = recordLog.bind(this, id, x.toUpperCase(), sharedAttributes);
|
|
57
|
+
return ret;
|
|
53
58
|
|
|
54
59
|
}
|
|
60
|
+
|
|
55
61
|
};
|
|
56
62
|
|
|
57
63
|
}
|
package/package.json
CHANGED
package/src/client/node.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { EVENT_STORE_META } from "../
|
|
1
|
+
import { EVENT_STORE_META } from "../configuration/configure-eventStore.js";
|
|
2
2
|
import { eventStore as eventStoreModular } from "../../dist/browser/client/event-store.js";
|
|
3
3
|
|
|
4
4
|
function adaptDatabase(db) {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { EVENTS } from "../../dist/browser/client/event-store.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { refPathToTriggerPath } from "./paths.js";
|
|
3
|
+
import { updateProjections } from "../event-store/projections.js";
|
|
4
|
+
|
|
4
5
|
|
|
5
6
|
export const EVENT_STORE_META = Symbol("Event store configuration metadata");
|
|
6
7
|
|
|
@@ -34,11 +35,4 @@ export function configureEventStore({ ref, projections, ...rest }, { onValueWrit
|
|
|
34
35
|
);
|
|
35
36
|
|
|
36
37
|
}
|
|
37
|
-
|
|
38
|
-
configureEventStore.inject = ({ onValueWritten, observe, paths, region, instance }) =>
|
|
39
|
-
|
|
40
|
-
(eventStoreFactory, ...args) =>
|
|
41
|
-
|
|
42
|
-
configureEventStore(eventStoreFactory(paths, ...args), { onValueWritten, observe, region, instance });
|
|
43
|
-
|
|
44
|
-
|
|
38
|
+
configureEventStore.inject = ({ onValueWritten, observe, paths, region, instance }) => (eventStoreFactory, ...args) => configureEventStore(eventStoreFactory(paths, ...args), { onValueWritten, observe, region, instance });
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { loadConfigurationFromModule } from "./load-configuration.js";
|
|
2
|
+
|
|
3
|
+
function buildConfigDigest(module, paths) {
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
const refConfigMap = loadConfigurationFromModule(module)
|
|
7
|
+
.flatMap(x => x.map(y => y[1]))
|
|
8
|
+
.reduce((index, config) => ({ ...index, [config.ref]: config }), {});
|
|
9
|
+
|
|
10
|
+
function patchForPath(map) {
|
|
11
|
+
|
|
12
|
+
const ret = {
|
|
13
|
+
...map
|
|
14
|
+
};
|
|
15
|
+
const mappedConfig = refConfigMap[map.path];
|
|
16
|
+
for (const [x, y] of Object.entries(ret).filter(([_, v]) => typeof v === "object")) {
|
|
17
|
+
|
|
18
|
+
ret[x] = patchForPath(y);
|
|
19
|
+
|
|
20
|
+
}
|
|
21
|
+
if (mappedConfig && (mappedConfig.read || mappedConfig.write)) {
|
|
22
|
+
|
|
23
|
+
ret.projections = mappedConfig.projections;
|
|
24
|
+
ret.eventTypes = mappedConfig.eventTypes;
|
|
25
|
+
|
|
26
|
+
}
|
|
27
|
+
return ret;
|
|
28
|
+
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return patchForPath(paths);
|
|
32
|
+
|
|
33
|
+
}
|
|
34
|
+
const publicFor1Day = "public, max-age=86400";
|
|
35
|
+
|
|
36
|
+
export function configureMetadataEndpoint({ module, paths, onRequest, region, cacheControl = publicFor1Day }) {
|
|
37
|
+
|
|
38
|
+
const digest = buildConfigDigest(module, paths);
|
|
39
|
+
return onRequest(
|
|
40
|
+
{ region },
|
|
41
|
+
async (_, res) => {
|
|
42
|
+
|
|
43
|
+
res.header("Cache-Control", cacheControl).send(digest);
|
|
44
|
+
|
|
45
|
+
}
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
}
|
|
@@ -1,72 +1,8 @@
|
|
|
1
|
-
import { loadConfigurationFromModule } from "./load-configuration.js";
|
|
2
1
|
import { refPathToTriggerPath } from "./paths.js";
|
|
3
|
-
import { all,
|
|
2
|
+
import { all, assertNewDataHasString, assertNewDataHasOneOf, assertNewDataHasLowercaseHexCharacters, assertNewDataFieldDoesNotMatch, assertNewDataDoesNotHave, any, assertNewDataHasNumber } from "./rules.js";
|
|
4
3
|
|
|
5
|
-
export const RAW_STORE_META = Symbol("Raw database metadata");
|
|
6
|
-
|
|
7
|
-
export function configureConfigStore(paths, _onValueWritten, _observe) {
|
|
8
|
-
|
|
9
|
-
if (!paths?.config?.path) throw new Error("Missing: paths.config.path");
|
|
10
|
-
return {
|
|
11
|
-
[RAW_STORE_META]: {
|
|
12
|
-
raw: true,
|
|
13
|
-
ref: paths.config.path,
|
|
14
|
-
read: true,
|
|
15
|
-
write: false
|
|
16
|
-
}
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
function buildConfigDigest(module, paths) {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
const refConfigMap =
|
|
25
|
-
loadConfigurationFromModule(module)
|
|
26
|
-
.flatMap(x => x.map(y => y[1]))
|
|
27
|
-
.reduce((index, config) => ({ ...index, [config.ref]: config }), {});
|
|
28
|
-
|
|
29
|
-
function patchForPath(map) {
|
|
30
|
-
|
|
31
|
-
const ret = {
|
|
32
|
-
...map
|
|
33
|
-
};
|
|
34
|
-
const mappedConfig = refConfigMap[map.path];
|
|
35
|
-
for (const [x, y] of Object.entries(ret).filter(([_, v]) => typeof v === "object")) {
|
|
36
|
-
|
|
37
|
-
ret[x] = patchForPath(y);
|
|
38
|
-
|
|
39
|
-
}
|
|
40
|
-
if (mappedConfig && (mappedConfig.read || mappedConfig.write)) {
|
|
41
|
-
|
|
42
|
-
ret.projections = mappedConfig.projections;
|
|
43
|
-
ret.eventTypes = mappedConfig.eventTypes;
|
|
44
|
-
|
|
45
|
-
}
|
|
46
|
-
return ret;
|
|
47
|
-
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
return patchForPath(paths);
|
|
51
|
-
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
const publicFor1Day = "public, max-age=86400";
|
|
55
|
-
|
|
56
|
-
export function configureMetadataEndpoint({ module, paths, onRequest, region, cacheControl = publicFor1Day }) {
|
|
57
|
-
|
|
58
|
-
const digest = buildConfigDigest(module, paths);
|
|
59
|
-
return onRequest(
|
|
60
|
-
{ region },
|
|
61
|
-
async (_, res) => {
|
|
62
|
-
|
|
63
|
-
res.header("Cache-Control", cacheControl).send(digest);
|
|
64
|
-
|
|
65
|
-
}
|
|
66
|
-
);
|
|
67
|
-
|
|
68
|
-
}
|
|
69
4
|
|
|
5
|
+
export const RAW_STORE_META = Symbol("Raw database metadata");
|
|
70
6
|
const googleLogLevels = ["DEBUG", "INFO", "NOTICE", "WARNING", "ERROR", "CRITICAL", "ALERT", "EMERGENCY"];
|
|
71
7
|
|
|
72
8
|
function decideSeverity(newData) {
|
|
@@ -75,13 +11,15 @@ function decideSeverity(newData) {
|
|
|
75
11
|
return googleLogLevels.includes(text) ? text : "INFO";
|
|
76
12
|
|
|
77
13
|
}
|
|
14
|
+
const DISPATCHED = "DISPATCHED";
|
|
15
|
+
const BLOCKED = "BLOCKED";
|
|
78
16
|
|
|
79
17
|
/*
|
|
80
18
|
|
|
81
19
|
message, severity, // required
|
|
82
20
|
traceId, spanId, timestamp, // advised
|
|
83
21
|
logData, // optional log line
|
|
84
|
-
spanStart, spanEnd, spanAttributes // optional trace attributes
|
|
22
|
+
spanStart, spanEnd, spanAttributes, parentSpanId // optional trace attributes
|
|
85
23
|
|
|
86
24
|
*/
|
|
87
25
|
function handleO11yEventWritten(observe, e) {
|
|
@@ -91,31 +29,72 @@ function handleO11yEventWritten(observe, e) {
|
|
|
91
29
|
if (!newData.time_server_ms) {
|
|
92
30
|
|
|
93
31
|
const now = new Date();
|
|
94
|
-
const time_server_ms = now.valueOf();
|
|
95
32
|
const timestamp = now.toISOString();
|
|
96
|
-
const
|
|
33
|
+
const time_server_ms = now.valueOf();
|
|
34
|
+
const { traceId, spanId, parentSpanId, ...rest } = newData;
|
|
97
35
|
|
|
98
|
-
const {
|
|
99
|
-
const
|
|
36
|
+
const { id } = e.params;
|
|
37
|
+
const [id_traceId, id_spanId] = id.split("-");
|
|
38
|
+
let action;
|
|
39
|
+
if (traceId !== id_traceId || spanId !== id_spanId) {
|
|
40
|
+
|
|
41
|
+
action = blockEvent({ message: "Mismatched event id", timestamp, details: { id, traceId, spanId }});
|
|
42
|
+
|
|
43
|
+
} else if (!newData?.meta?.uid) {
|
|
100
44
|
|
|
45
|
+
action = blockEvent({ message: "Missing / invalid uid", timestamp, details: { uid: newData?.meta?.uid } });
|
|
46
|
+
|
|
47
|
+
} else {
|
|
48
|
+
|
|
49
|
+
action = dispatch({ rest, time_server_ms, traceId, spanId, parentSpanId, timestamp });
|
|
50
|
+
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
after.ref.update({
|
|
54
|
+
time_server_ms,
|
|
55
|
+
timestamp,
|
|
56
|
+
action
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
function dispatch({ rest, time_server_ms, traceId, spanId, parentSpanId, timestamp }) {
|
|
63
|
+
|
|
64
|
+
const message = newData?.message || "Missing log message";
|
|
65
|
+
const uid = newData.meta?.uid;
|
|
66
|
+
const logData = { ...rest, time_server_ms };
|
|
101
67
|
observe({
|
|
102
68
|
message,
|
|
103
69
|
severity: decideSeverity(newData),
|
|
104
70
|
|
|
105
|
-
traceId
|
|
106
|
-
spanId
|
|
71
|
+
traceId,
|
|
72
|
+
spanId,
|
|
73
|
+
parentSpanId,
|
|
107
74
|
timestamp,
|
|
108
75
|
|
|
109
|
-
logData
|
|
76
|
+
logData,
|
|
77
|
+
spanAttributes: { "user.id": uid }
|
|
78
|
+
});
|
|
79
|
+
return DISPATCHED;
|
|
80
|
+
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function blockEvent({ message, timestamp, details }) {
|
|
110
84
|
|
|
85
|
+
observe({
|
|
86
|
+
message: `O11y event blocked: ${message}`,
|
|
87
|
+
severity: "CRITICAL",
|
|
88
|
+
timestamp,
|
|
89
|
+
logData: { ...details, newData }
|
|
111
90
|
});
|
|
112
|
-
|
|
91
|
+
return BLOCKED;
|
|
113
92
|
|
|
114
93
|
}
|
|
115
94
|
|
|
116
95
|
}
|
|
117
96
|
|
|
118
|
-
export function
|
|
97
|
+
export function configureO11yStore({ paths, onValueWritten, observe, region, instance }) {
|
|
119
98
|
|
|
120
99
|
if (!paths) throw new Error("Missing paths");
|
|
121
100
|
if (!onValueWritten) throw new Error("Missing onValueWritten");
|
|
@@ -139,29 +118,30 @@ export function configureLoggingStore({ paths, onValueWritten, observe, region,
|
|
|
139
118
|
read: false,
|
|
140
119
|
write: all(
|
|
141
120
|
// required
|
|
142
|
-
assertNewDataHasString("
|
|
121
|
+
assertNewDataHasString("message", 500, 1),
|
|
143
122
|
assertNewDataHasOneOf("severity_text", ...googleLogLevels),
|
|
144
123
|
// trace context
|
|
145
124
|
all(
|
|
146
|
-
assertNewDataHasLowercaseHexCharacters("
|
|
147
|
-
assertNewDataFieldDoesNotMatch("
|
|
125
|
+
assertNewDataHasLowercaseHexCharacters("traceId", 32),
|
|
126
|
+
assertNewDataFieldDoesNotMatch("traceId", "0*")
|
|
148
127
|
),
|
|
149
128
|
all(
|
|
150
|
-
assertNewDataHasLowercaseHexCharacters("
|
|
151
|
-
assertNewDataFieldDoesNotMatch("
|
|
129
|
+
assertNewDataHasLowercaseHexCharacters("spanId", 16),
|
|
130
|
+
assertNewDataFieldDoesNotMatch("spanId", "0*")
|
|
152
131
|
),
|
|
153
|
-
// forbid server time faking
|
|
132
|
+
// forbid server time and action faking
|
|
154
133
|
assertNewDataDoesNotHave("time_server_ms"),
|
|
134
|
+
assertNewDataDoesNotHave("action"),
|
|
155
135
|
// optional bits
|
|
156
136
|
any(
|
|
157
137
|
assertNewDataDoesNotHave("time_client_ms"),
|
|
158
138
|
assertNewDataHasNumber("time_client_ms")
|
|
159
139
|
),
|
|
160
140
|
any(
|
|
161
|
-
assertNewDataDoesNotHave("
|
|
141
|
+
assertNewDataDoesNotHave("parentSpanId"),
|
|
162
142
|
all(
|
|
163
|
-
assertNewDataHasLowercaseHexCharacters("
|
|
164
|
-
assertNewDataFieldDoesNotMatch("
|
|
143
|
+
assertNewDataHasLowercaseHexCharacters("parentSpanId", 16),
|
|
144
|
+
assertNewDataFieldDoesNotMatch("parentSpanId", "0*")
|
|
165
145
|
)
|
|
166
146
|
)
|
|
167
147
|
)
|
|
@@ -170,4 +150,3 @@ export function configureLoggingStore({ paths, onValueWritten, observe, region,
|
|
|
170
150
|
);
|
|
171
151
|
|
|
172
152
|
}
|
|
173
|
-
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { resolve } from "path";
|
|
2
2
|
import { pathToFileURL } from "url";
|
|
3
|
-
import { EVENT_STORE_META } from "./
|
|
4
|
-
import { RAW_STORE_META } from "./
|
|
3
|
+
import { EVENT_STORE_META } from "./configure-eventStore.js";
|
|
4
|
+
import { RAW_STORE_META } from "./configure-o11y-store.js";
|
|
5
5
|
|
|
6
6
|
export async function loadConfiguration(argv) {
|
|
7
7
|
|
package/src/exec-eventstore.js
CHANGED
package/src/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
export { PROJECTIONS, EVENTS } from "../dist/browser/client/event-store.js";
|
|
2
2
|
|
|
3
|
-
export * from "./
|
|
4
|
-
|
|
5
|
-
export * from "./configuration.js";
|
|
3
|
+
export * from "./configuration/configure-eventStore.js";
|
|
4
|
+
export * from "./configuration/configure-metadata-endpoint.js";
|
|
5
|
+
export * from "./configuration/configure-o11y-store.js";
|
|
6
6
|
|
|
7
7
|
export const passThroughView = {
|
|
8
8
|
"?": (view, e, key) => {
|
|
@@ -24,7 +24,7 @@ export * as userTeams from "./membership/user-teams/store.js";
|
|
|
24
24
|
|
|
25
25
|
export * as userInvites from "./membership/userInvites/store.js";
|
|
26
26
|
|
|
27
|
-
export * as rules from "./rules.js";
|
|
27
|
+
export * as rules from "./configuration/rules.js";
|
|
28
28
|
|
|
29
29
|
export function explodePathVars(expr) {
|
|
30
30
|
|
|
@@ -34,5 +34,3 @@ export function explodePathVars(expr) {
|
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
export * as o11y from "./observability/index.js";
|
|
37
|
-
|
|
38
|
-
export { loadConfigurationFromModule } from "./load-configuration.js";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { assertUserIsMe } from "../../rules.js";
|
|
1
|
+
import { assertUserIsMe } from "../../configuration/rules.js";
|
|
2
2
|
import { verifyStorePaths } from "../team-details/verify-store-paths.js";
|
|
3
3
|
import { eventTypes } from "./events.js";
|
|
4
4
|
import current from "./projections/current.js";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { assertUserIsMe } from "../../rules.js";
|
|
1
|
+
import { assertUserIsMe } from "../../configuration/rules.js";
|
|
2
2
|
import { verifyStorePaths } from "../team-details/verify-store-paths.js";
|
|
3
3
|
import { eventTypes } from "./events.js";
|
|
4
4
|
import current from "./projections/current.js";
|
|
@@ -2,7 +2,7 @@ import { eventTypes, ACCEPTED_INVITATION, REJECTED_INVITATION } from "./events.j
|
|
|
2
2
|
import pending from "./projections/pending.js";
|
|
3
3
|
import { PROJECTIONS } from "../../index.js";
|
|
4
4
|
import { verifyStorePaths } from "../team-details/verify-store-paths.js";
|
|
5
|
-
import { all, any, assertEventIsOfType, assertDataFieldIsMyVerifiedEmail, assertMyVerifiedEmail, not, assertNewDataHas } from "../../rules.js";
|
|
5
|
+
import { all, any, assertEventIsOfType, assertDataFieldIsMyVerifiedEmail, assertMyVerifiedEmail, not, assertNewDataHas } from "../../configuration/rules.js";
|
|
6
6
|
|
|
7
7
|
const assertAcceptedOrRejectedEvent = assertEventIsOfType(
|
|
8
8
|
ACCEPTED_INVITATION,
|
|
@@ -9,7 +9,7 @@ export function provider({ trace, projectId, serviceName, log }) {
|
|
|
9
9
|
message, severity, // required
|
|
10
10
|
traceId, spanId, timestamp, // advised
|
|
11
11
|
logData, // optional log line
|
|
12
|
-
spanStart, spanEnd, spanAttributes // optional trace attributes
|
|
12
|
+
spanStart, spanEnd, spanAttributes, parentSpanId // optional trace attributes
|
|
13
13
|
}) => {
|
|
14
14
|
|
|
15
15
|
if (!message) throw new Error("Missing message");
|
|
@@ -30,7 +30,7 @@ export function provider({ trace, projectId, serviceName, log }) {
|
|
|
30
30
|
const startTime = asISOString(spanStart);
|
|
31
31
|
const endTime = asISOString(spanEnd);
|
|
32
32
|
|
|
33
|
-
await createSpan({ trace }, { serviceName, projectTraceSpanName, message, spanId, startTime, endTime, spanAttributes });
|
|
33
|
+
await createSpan({ trace }, { parentSpanId, serviceName, projectTraceSpanName, message, spanId, startTime, endTime, spanAttributes });
|
|
34
34
|
await writeLogLine({ log, projectId }, { tracePath, spanId, severity, timestamp, message, logData });
|
|
35
35
|
|
|
36
36
|
};
|
|
@@ -92,23 +92,25 @@ async function writeLogLine({ log, projectId }, { message, tracePath, spanId, se
|
|
|
92
92
|
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
-
async function createSpan({ trace }, { serviceName, projectTraceSpanName, spanId, startTime, endTime, spanAttributes, message }) {
|
|
95
|
+
async function createSpan({ trace }, { serviceName, projectTraceSpanName, spanId, parentSpanId, startTime, endTime, spanAttributes, message }) {
|
|
96
96
|
|
|
97
97
|
const attributes = toTraceAttributes({
|
|
98
98
|
"service.name": serviceName,
|
|
99
99
|
message,
|
|
100
100
|
...spanAttributes
|
|
101
101
|
});
|
|
102
|
+
const requestBody = {
|
|
103
|
+
attributes,
|
|
104
|
+
name: projectTraceSpanName,
|
|
105
|
+
spanId,
|
|
106
|
+
displayName: { value: serviceName },
|
|
107
|
+
startTime,
|
|
108
|
+
endTime
|
|
109
|
+
};
|
|
110
|
+
if (parentSpanId) requestBody.parentSpanId = parentSpanId;
|
|
102
111
|
await trace.projects.traces.spans.createSpan({
|
|
103
112
|
name: projectTraceSpanName,
|
|
104
|
-
requestBody
|
|
105
|
-
attributes,
|
|
106
|
-
name: projectTraceSpanName,
|
|
107
|
-
spanId,
|
|
108
|
-
displayName: { value: serviceName },
|
|
109
|
-
startTime,
|
|
110
|
-
endTime
|
|
111
|
-
}
|
|
113
|
+
requestBody
|
|
112
114
|
});
|
|
113
115
|
|
|
114
116
|
}
|
package/src/system/main.js
CHANGED
|
File without changes
|