@weave-js/core 0.10.0 → 0.12.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/.eslintrc.js +1 -1
- package/jest.config.js +1 -1
- package/lib/ExtendableError.js +33 -0
- package/lib/broker/context.js +58 -46
- package/lib/broker/{default-options.js → defaultOptions.js} +31 -13
- package/lib/broker/index.js +273 -251
- package/lib/buildRuntime.js +70 -0
- package/lib/cache/adapters/base.js +119 -0
- package/lib/cache/adapters/inMemory.js +154 -0
- package/lib/cache/adapters/inMemoryLru.js +140 -0
- package/lib/cache/adapters/index.js +10 -0
- package/lib/cache/getCacheKeyByObject.js +31 -0
- package/lib/cache/getPropertyFromDataOrMetadata.js +20 -0
- package/lib/cache/lock.js +34 -11
- package/lib/constants.js +11 -8
- package/lib/{error-handler.js → errorHandler.js} +8 -8
- package/lib/errors.js +46 -39
- package/lib/helper/{define-action.js → defineAction.js} +5 -3
- package/lib/helper/{define-broker-options.js → defineBrokerOptions.js} +4 -2
- package/lib/helper/{define-service.js → defineService.js} +6 -3
- package/lib/index.js +25 -22
- package/lib/logger/base.js +38 -29
- package/lib/logger/format/asHumanReadable.js +15 -14
- package/lib/logger/format/asJson.js +10 -10
- package/lib/logger/format/index.js +3 -3
- package/lib/logger/index.js +28 -25
- package/lib/logger/levels.js +23 -22
- package/lib/logger/tools.js +17 -13
- package/lib/logger/utils/colorize.js +23 -23
- package/lib/logger/utils/format.js +89 -65
- package/lib/metrics/common.js +47 -47
- package/lib/metrics/constants.js +44 -44
- package/lib/metrics/exporter/base.js +8 -8
- package/lib/metrics/exporter/event.js +20 -20
- package/lib/metrics/exporter/index.js +15 -15
- package/lib/metrics/index.js +2 -2
- package/lib/metrics/types/base.js +20 -20
- package/lib/metrics/types/counter.js +6 -6
- package/lib/metrics/types/gauge.js +24 -24
- package/lib/metrics/types/histogram.js +26 -26
- package/lib/metrics/types/index.js +6 -6
- package/lib/metrics/types/info.js +17 -17
- package/lib/middlewares/action-hooks/index.js +82 -34
- package/lib/middlewares/bulkhead/index.js +34 -33
- package/lib/middlewares/cache/index.js +106 -0
- package/lib/middlewares/circuit-breaker/index.js +85 -60
- package/lib/middlewares/context-tracker/index.js +39 -39
- package/lib/middlewares/error-handler/index.js +14 -14
- package/lib/middlewares/index.js +3 -2
- package/lib/middlewares/metrics/getMiddlewareWrapper.js +17 -17
- package/lib/middlewares/metrics/index.js +29 -29
- package/lib/middlewares/retry/index.js +15 -15
- package/lib/middlewares/timeout/index.js +18 -18
- package/lib/middlewares/tracing/index.js +50 -37
- package/lib/middlewares/tracing/tags.js +43 -0
- package/lib/middlewares/validator/index.js +32 -32
- package/lib/registry/{action-endpoint.js → actionEndpoint.js} +8 -8
- package/lib/registry/collections/{action-collection.js → actionCollection.js} +39 -35
- package/lib/registry/collections/{endpoint-collection.js → endpointCollection.js} +64 -65
- package/lib/registry/collections/{event-collection.js → eventCollection.js} +65 -69
- package/lib/registry/collections/{node-collection.js → nodeCollection.js} +45 -45
- package/lib/registry/collections/{service-collection.js → serviceCollection.js} +61 -55
- package/lib/registry/eventEndpoint.js +26 -0
- package/lib/registry/load-balancer/base.js +3 -3
- package/lib/registry/load-balancer/index.js +7 -7
- package/lib/registry/node.js +27 -27
- package/lib/registry/registry.js +147 -163
- package/lib/registry/service/parseAction.js +16 -16
- package/lib/registry/service/parseEvent.js +18 -18
- package/lib/registry/service/reduceMixins.js +10 -10
- package/lib/registry/service/service.js +72 -72
- package/lib/registry/{service-item.js → serviceItem.js} +21 -21
- package/lib/runtime/{init-action-invoker.js → initActionInvoker.js} +21 -21
- package/lib/runtime/initCache.js +19 -0
- package/lib/runtime/{init-context-factory.js → initContextFactory.js} +22 -22
- package/lib/runtime/{init-eventbus.js → initEventbus.js} +54 -53
- package/lib/runtime/{init-logger.js → initLogger.js} +11 -11
- package/lib/runtime/{init-metrics.js → initMetrics.js} +55 -54
- package/lib/runtime/{init-middleware-manager.js → initMiddlewareManager.js} +21 -21
- package/lib/runtime/{init-registry.js → initRegistry.js} +6 -6
- package/lib/runtime/initServiceManager.js +145 -0
- package/lib/runtime/{init-tracing.js → initTracing.js} +25 -24
- package/lib/runtime/{init-transport.js → initTransport.js} +5 -5
- package/lib/runtime/{init-uuid-factory.js → initUuidFactory.js} +4 -4
- package/lib/runtime/{init-validator.js → initValidator.js} +5 -5
- package/lib/tracing/collectors/base.js +29 -37
- package/lib/tracing/collectors/event.js +33 -33
- package/lib/tracing/collectors/index.js +16 -16
- package/lib/tracing/span.js +34 -32
- package/lib/tracing/time.js +8 -8
- package/lib/transport/InboundTransformStream.js +75 -0
- package/lib/transport/adapters/adapteBase.js +107 -0
- package/lib/transport/adapters/adapters.js +4 -4
- package/lib/transport/adapters/dummy/index.js +19 -19
- package/lib/transport/adapters/fromURI.js +13 -13
- package/lib/transport/adapters/getAdapterByName.js +5 -5
- package/lib/transport/adapters/index.js +12 -12
- package/lib/transport/adapters/tcp/discovery/codec.js +4 -4
- package/lib/transport/adapters/tcp/discovery/index.js +90 -76
- package/lib/transport/adapters/tcp/index.js +180 -175
- package/lib/transport/adapters/tcp/tcp-messagetypes.js +7 -7
- package/lib/transport/adapters/tcp/tcpReader.js +39 -38
- package/lib/transport/adapters/tcp/tcpWriteStream.js +26 -26
- package/lib/transport/adapters/tcp/tcpWriter.js +58 -58
- package/lib/transport/adapters/tcp/utils.js +12 -12
- package/lib/transport/createMessage.js +11 -0
- package/lib/transport/createTransport.js +377 -334
- package/lib/transport/errorPayloadFactory.js +15 -0
- package/lib/transport/messageHandlers.js +517 -0
- package/lib/transport/messageTypes.js +23 -0
- package/lib/types.js +95 -71
- package/lib/utils/index.js +2 -2
- package/lib/utils/options.js +47 -45
- package/lib/utils/{restore-error.js → restoreError.js} +4 -4
- package/package.json +6 -12
- package/CHANGELOG.md +0 -1334
- package/lib/build-runtime.js +0 -70
- package/lib/cache/base.js +0 -142
- package/lib/cache/index.js +0 -48
- package/lib/cache/memory.js +0 -121
- package/lib/middlewares/tracing/buildTags.js +0 -17
- package/lib/new-errors.js +0 -25
- package/lib/registry/event-endpoint.js +0 -26
- package/lib/runtime/init-cache.js +0 -10
- package/lib/runtime/init-service-manager.js +0 -128
- package/lib/tracing/collectors/console.js +0 -34
- package/lib/tracing/index.js +0 -3
- package/lib/tracing/tracer.js +0 -64
- package/lib/transport/adapters/adapter-base.js +0 -92
- package/lib/transport/message-handlers.js +0 -448
- package/lib/transport/message-types.js +0 -59
- package/lib/transport/message.js +0 -16
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
const { createServiceFromSchema } = require('../registry/service/service.js');
|
|
2
|
+
const { WeaveError } = require('../errors');
|
|
3
|
+
|
|
4
|
+
exports.initServiceManager = (runtime) => {
|
|
5
|
+
const { options, log, eventBus, transport, state, registry, handleError } = runtime;
|
|
6
|
+
|
|
7
|
+
// Internal service list
|
|
8
|
+
const serviceList = [];
|
|
9
|
+
|
|
10
|
+
const serviceChanged = (isLocalService = false) => {
|
|
11
|
+
// Send local notification.
|
|
12
|
+
eventBus.broadcastLocal('$services.changed', { isLocalService });
|
|
13
|
+
|
|
14
|
+
// If the service is a local service - send current node information to other nodes
|
|
15
|
+
if (state.isStarted && isLocalService && transport) {
|
|
16
|
+
transport.sendNodeInfo();
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
// const destroyService = (service) => Promise.resolve()
|
|
21
|
+
// .then(() => service.stop())
|
|
22
|
+
// .then(() => log.info(`Service "${service.name}" was stopped.`))
|
|
23
|
+
// .then(() => {
|
|
24
|
+
// registry.deregisterService(service.name, service.version)
|
|
25
|
+
// log.info(`Service "${service.name}" was deregistered.`)
|
|
26
|
+
// // Remove service from service store.
|
|
27
|
+
// serviceList.splice(serviceList.indexOf(service), 1)
|
|
28
|
+
// // Fire services changed event
|
|
29
|
+
// serviceChanged(true)
|
|
30
|
+
// return Promise.resolve()
|
|
31
|
+
// })
|
|
32
|
+
// .catch(error => log.error(error, `Unable to stop service "${service.name}"`))
|
|
33
|
+
|
|
34
|
+
// `onServiceFileChanged` only triggered by the file watcher
|
|
35
|
+
// const onServiceFileChanged = async (service) => {
|
|
36
|
+
// const filename = service.filename;
|
|
37
|
+
|
|
38
|
+
// // Clear the require cache
|
|
39
|
+
// Object.keys(require.cache).forEach(key => {
|
|
40
|
+
// if (key === filename) {
|
|
41
|
+
// delete require.cache[key];
|
|
42
|
+
// }
|
|
43
|
+
// });
|
|
44
|
+
|
|
45
|
+
// // Service has changed - 1. destroy the service, then reload it
|
|
46
|
+
// await destroyService(service);
|
|
47
|
+
// await runtime.broker.loadService(filename);
|
|
48
|
+
// };
|
|
49
|
+
|
|
50
|
+
Object.defineProperty(runtime, 'services', {
|
|
51
|
+
value: {
|
|
52
|
+
serviceList,
|
|
53
|
+
serviceChanged,
|
|
54
|
+
createService (schema) {
|
|
55
|
+
try {
|
|
56
|
+
const newService = createServiceFromSchema(runtime, schema);
|
|
57
|
+
|
|
58
|
+
// if the broker is already started, we need to start the service.
|
|
59
|
+
if (runtime.state.isStarted) {
|
|
60
|
+
newService.start().catch(error => log.error(`Unable to start service ${newService.name}: ${error}`));
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return newService;
|
|
64
|
+
} catch (error) {
|
|
65
|
+
log.error(error);
|
|
66
|
+
handleError(error);
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
/**
|
|
70
|
+
* Wait for services before continuing startup.
|
|
71
|
+
* @param {Array.<string>} serviceNames Names of the services
|
|
72
|
+
* @param {Number} timeout Time in Miliseconds before the broker stops.
|
|
73
|
+
* @param {Number} interval Time in Miliseconds to check for services.
|
|
74
|
+
* @returns {Promise} Promise
|
|
75
|
+
*/
|
|
76
|
+
waitForServices (serviceNames, timeout, interval = 500) {
|
|
77
|
+
if (!Array.isArray(serviceNames)) {
|
|
78
|
+
serviceNames = [serviceNames];
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const startTimestamp = Date.now();
|
|
82
|
+
return new Promise((resolve, reject) => {
|
|
83
|
+
// todo: add timout for service waiter
|
|
84
|
+
log.warn(`Waiting for services '${serviceNames.join(',')}'`);
|
|
85
|
+
|
|
86
|
+
const serviceCheck = () => {
|
|
87
|
+
const count = serviceNames.filter(serviceName => registry.hasService(serviceName));
|
|
88
|
+
|
|
89
|
+
log.warn(`${count.length} services of ${serviceNames.length} available. Waiting...`);
|
|
90
|
+
|
|
91
|
+
if (count.length === serviceNames.length) {
|
|
92
|
+
return resolve();
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (timeout && (Date.now() - startTimestamp) > timeout) {
|
|
96
|
+
return reject(new WeaveError('The waiting of the services is interrupted due to a timeout.', 500, 'WAIT_FOR_SERVICE', { services: serviceNames }));
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
options.waitForServiceInterval = setTimeout(serviceCheck, interval);
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
serviceCheck();
|
|
103
|
+
});
|
|
104
|
+
},
|
|
105
|
+
/**
|
|
106
|
+
* Destroy a service
|
|
107
|
+
* @param {Service} service Service
|
|
108
|
+
* @returns {Promise<any>} result
|
|
109
|
+
*/
|
|
110
|
+
async destroyService (service) {
|
|
111
|
+
try {
|
|
112
|
+
// Stop the service
|
|
113
|
+
await service.stop();
|
|
114
|
+
log.info(`Service "${service.name}" was stopped.`);
|
|
115
|
+
|
|
116
|
+
// Deregister the service and remove it from the service list
|
|
117
|
+
registry.deregisterService(service.name, service.version);
|
|
118
|
+
serviceList.splice(serviceList.indexOf(service), 1);
|
|
119
|
+
log.info(`Service "${service.name}" was deregistered.`);
|
|
120
|
+
serviceChanged(true);
|
|
121
|
+
} catch (error) {
|
|
122
|
+
log.error(error, `Unable to stop service "${service.name}"`);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Watch a Service object for changes.
|
|
127
|
+
* @param {Service} service Service object
|
|
128
|
+
* @return {void}
|
|
129
|
+
*/
|
|
130
|
+
// watchService: (service) => {
|
|
131
|
+
// if (service.filename && onServiceFileChanged) {
|
|
132
|
+
// // Create debounced service changed reference
|
|
133
|
+
// const debouncedOnServiceChange = debounce(onServiceFileChanged, 500);
|
|
134
|
+
|
|
135
|
+
// // Watch file changes
|
|
136
|
+
// const watcher = fs.watch(service.filename, (eventType, filename) => {
|
|
137
|
+
// log.info(`The Service ${service.name} has been changed. (${eventType}, ${filename})`);
|
|
138
|
+
// watcher.close();
|
|
139
|
+
// debouncedOnServiceChange(service);
|
|
140
|
+
// });
|
|
141
|
+
// }
|
|
142
|
+
// }
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
};
|
|
@@ -1,64 +1,65 @@
|
|
|
1
|
-
const { resolveCollector } = require('../tracing/collectors')
|
|
2
|
-
const { createSpan } = require('../tracing/span')
|
|
1
|
+
const { resolveCollector } = require('../tracing/collectors');
|
|
2
|
+
const { createSpan } = require('../tracing/span');
|
|
3
3
|
|
|
4
4
|
exports.initTracer = (runtime) => {
|
|
5
|
-
const options = runtime.options.tracing
|
|
6
|
-
const log = runtime.createLogger('TRACER')
|
|
7
|
-
let collectors = []
|
|
8
|
-
let samplingCounter = 0
|
|
5
|
+
const options = runtime.options.tracing;
|
|
6
|
+
const log = runtime.createLogger('TRACER');
|
|
7
|
+
let collectors = [];
|
|
8
|
+
let samplingCounter = 0;
|
|
9
9
|
|
|
10
10
|
Object.defineProperty(runtime, 'tracer', {
|
|
11
11
|
value: {
|
|
12
|
+
runtime,
|
|
13
|
+
options,
|
|
12
14
|
log,
|
|
13
15
|
async stop () {
|
|
14
16
|
if (collectors.length > 0) {
|
|
15
|
-
return await Promise.all(collectors.map(collector => collector.stop()))
|
|
17
|
+
return await Promise.all(collectors.map(collector => collector.stop()));
|
|
16
18
|
}
|
|
17
19
|
},
|
|
18
20
|
shouldSample (span) {
|
|
19
21
|
// check span priority
|
|
20
22
|
if (options.samplingRate === 0) {
|
|
21
|
-
return false
|
|
23
|
+
return false;
|
|
22
24
|
}
|
|
23
25
|
|
|
24
26
|
if (options.samplingRate === 1) {
|
|
25
|
-
return true
|
|
27
|
+
return true;
|
|
26
28
|
}
|
|
27
29
|
|
|
28
30
|
if (++samplingCounter * this.options.samplingRate >= 1) {
|
|
29
|
-
samplingCounter = 0
|
|
30
|
-
return true
|
|
31
|
+
samplingCounter = 0;
|
|
32
|
+
return true;
|
|
31
33
|
}
|
|
32
34
|
|
|
33
|
-
return false
|
|
35
|
+
return false;
|
|
34
36
|
},
|
|
35
37
|
invokeCollectorMethod (method, args) {
|
|
36
|
-
collectors.map(collector => collector[method].apply(collector, args))
|
|
38
|
+
collectors.map(collector => collector[method].apply(collector, args));
|
|
37
39
|
},
|
|
38
40
|
startSpan (name, options) {
|
|
39
41
|
const span = createSpan(this, name, Object.assign({
|
|
40
42
|
type: 'custom'
|
|
41
|
-
}, options))
|
|
43
|
+
}, options));
|
|
42
44
|
|
|
43
|
-
span.start()
|
|
45
|
+
span.start();
|
|
44
46
|
|
|
45
|
-
return span
|
|
47
|
+
return span;
|
|
46
48
|
}
|
|
47
49
|
}
|
|
48
|
-
})
|
|
50
|
+
});
|
|
49
51
|
|
|
50
52
|
// Init collectors
|
|
51
53
|
if (options.enabled) {
|
|
52
|
-
log.info('Tracer initialized.')
|
|
54
|
+
log.info('Tracer initialized.');
|
|
53
55
|
|
|
54
56
|
if (options.collectors) {
|
|
55
57
|
collectors = options.collectors
|
|
56
58
|
.map(entry => {
|
|
57
|
-
const initCollector = resolveCollector(runtime, entry, this)
|
|
58
|
-
|
|
59
|
-
initCollector
|
|
60
|
-
|
|
61
|
-
})
|
|
59
|
+
const initCollector = resolveCollector(runtime, entry, this);
|
|
60
|
+
initCollector.init(runtime);
|
|
61
|
+
return initCollector;
|
|
62
|
+
});
|
|
62
63
|
}
|
|
63
64
|
}
|
|
64
|
-
}
|
|
65
|
+
};
|
|
@@ -2,16 +2,16 @@
|
|
|
2
2
|
* @typedef {import('../types').TransportAdapter} TransportAdapter
|
|
3
3
|
**/
|
|
4
4
|
|
|
5
|
-
const { createTransport } = require('../transport/createTransport')
|
|
6
|
-
const TransportAdapters = require('../transport/adapters')
|
|
5
|
+
const { createTransport } = require('../transport/createTransport');
|
|
6
|
+
const TransportAdapters = require('../transport/adapters');
|
|
7
7
|
|
|
8
8
|
exports.initTransport = (runtime) => {
|
|
9
9
|
if (runtime.options.transport.adapter) {
|
|
10
10
|
/** @type {TransportAdapter} */
|
|
11
|
-
const adapter = TransportAdapters.resolve(runtime, runtime.options.transport)
|
|
11
|
+
const adapter = TransportAdapters.resolve(runtime, runtime.options.transport);
|
|
12
12
|
|
|
13
13
|
Object.defineProperty(runtime, 'transport', {
|
|
14
14
|
value: createTransport(runtime, adapter)
|
|
15
|
-
})
|
|
15
|
+
});
|
|
16
16
|
}
|
|
17
|
-
}
|
|
17
|
+
};
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* @typedef {import('../types.js').Runtime} Runtime
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
const { isFunction, uuid } = require('@weave-js/utils')
|
|
5
|
+
const { isFunction, uuid } = require('@weave-js/utils');
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Init uuid Generator and attach it to our runtime object.
|
|
@@ -10,7 +10,7 @@ const { isFunction, uuid } = require('@weave-js/utils')
|
|
|
10
10
|
* @returns {void}
|
|
11
11
|
*/
|
|
12
12
|
exports.initUUIDFactory = (runtime) => {
|
|
13
|
-
const { options } = runtime
|
|
13
|
+
const { options } = runtime;
|
|
14
14
|
|
|
15
|
-
runtime.generateUUID = (options.uuidFactory && isFunction(options.uuidFactory)) ? () => options.uuidFactory(runtime) : uuid
|
|
16
|
-
}
|
|
15
|
+
runtime.generateUUID = (options.uuidFactory && isFunction(options.uuidFactory)) ? () => options.uuidFactory(runtime) : uuid;
|
|
16
|
+
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Author: Kevin Ries (kevin@
|
|
2
|
+
* Author: Kevin Ries (kevin.ries@fachwerk.io)
|
|
3
3
|
* -----
|
|
4
4
|
* Copyright 2021 Fachwerk
|
|
5
5
|
*/
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* @typedef {import('../types.js').Runtime} Runtime
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
const ObjectValidator = require('@weave-js/validator')
|
|
11
|
+
const ObjectValidator = require('@weave-js/validator');
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* Init validator and attach it to our runtime object.
|
|
@@ -16,11 +16,11 @@ const ObjectValidator = require('@weave-js/validator')
|
|
|
16
16
|
* @returns {void}
|
|
17
17
|
*/
|
|
18
18
|
exports.initValidator = (runtime) => {
|
|
19
|
-
const validator = ObjectValidator()
|
|
19
|
+
const validator = ObjectValidator();
|
|
20
20
|
|
|
21
21
|
Object.defineProperty(runtime, 'validator', {
|
|
22
22
|
value: {
|
|
23
23
|
...validator
|
|
24
24
|
}
|
|
25
|
-
})
|
|
26
|
-
}
|
|
25
|
+
});
|
|
26
|
+
};
|
|
@@ -1,60 +1,52 @@
|
|
|
1
|
-
const { isObject } = require('@weave-js/utils')
|
|
2
|
-
const { WeaveError } = require('../../errors')
|
|
1
|
+
const { isObject, pick } = require('@weave-js/utils');
|
|
3
2
|
|
|
4
|
-
exports.createBaseTracingCollector = (
|
|
5
|
-
const baseTracingCollector = Object.create(null)
|
|
3
|
+
exports.createBaseTracingCollector = (runtime) => {
|
|
4
|
+
const baseTracingCollector = Object.create(null);
|
|
6
5
|
|
|
7
|
-
baseTracingCollector.options = options
|
|
6
|
+
baseTracingCollector.options = runtime.tracer.options;
|
|
8
7
|
|
|
9
|
-
baseTracingCollector.init = (runtime
|
|
10
|
-
baseTracingCollector.runtime = runtime
|
|
11
|
-
baseTracingCollector.tracer = tracer
|
|
12
|
-
}
|
|
8
|
+
baseTracingCollector.init = (runtime) => {
|
|
9
|
+
baseTracingCollector.runtime = runtime;
|
|
10
|
+
baseTracingCollector.tracer = runtime.tracer;
|
|
11
|
+
};
|
|
13
12
|
|
|
14
13
|
baseTracingCollector.startedSpan = () => {
|
|
15
|
-
throw new WeaveError('not implemented.')
|
|
16
|
-
}
|
|
14
|
+
// throw new WeaveError('not implemented.')
|
|
15
|
+
};
|
|
17
16
|
|
|
18
17
|
baseTracingCollector.finishedSpan = () => {
|
|
19
|
-
throw new WeaveError('not implemented.')
|
|
20
|
-
}
|
|
18
|
+
// throw new WeaveError('not implemented.')
|
|
19
|
+
};
|
|
21
20
|
|
|
22
21
|
baseTracingCollector.stop = () => {
|
|
23
|
-
throw new WeaveError('not implemented.')
|
|
24
|
-
}
|
|
22
|
+
// throw new WeaveError('not implemented.')
|
|
23
|
+
};
|
|
25
24
|
|
|
26
25
|
baseTracingCollector.flattenTags = (obj, convertToString = false, path = '') => {
|
|
27
26
|
if (!obj) {
|
|
28
|
-
return null
|
|
27
|
+
return null;
|
|
29
28
|
}
|
|
30
29
|
|
|
31
30
|
return Object.keys(obj).reduce((res, k) => {
|
|
32
|
-
const o = obj[k]
|
|
33
|
-
const pp = (path ? path + '.' : '') + k
|
|
31
|
+
const o = obj[k];
|
|
32
|
+
const pp = (path ? path + '.' : '') + k;
|
|
34
33
|
|
|
35
34
|
if (isObject(o)) {
|
|
36
|
-
Object.assign(res, baseTracingCollector.flattenTags(o, convertToString, pp))
|
|
35
|
+
Object.assign(res, baseTracingCollector.flattenTags(o, convertToString, pp));
|
|
37
36
|
} else if (o !== undefined) {
|
|
38
|
-
res[pp] = convertToString ? String(o) : o
|
|
37
|
+
res[pp] = convertToString ? String(o) : o;
|
|
39
38
|
}
|
|
40
39
|
|
|
41
|
-
return res
|
|
42
|
-
}, {})
|
|
43
|
-
}
|
|
40
|
+
return res;
|
|
41
|
+
}, {});
|
|
42
|
+
};
|
|
44
43
|
|
|
45
|
-
baseTracingCollector.getErrorFields = (
|
|
46
|
-
if (!
|
|
47
|
-
return null
|
|
44
|
+
baseTracingCollector.getErrorFields = (err, fields) => {
|
|
45
|
+
if (!err) {
|
|
46
|
+
return null;
|
|
48
47
|
}
|
|
48
|
+
return pick(err, fields);
|
|
49
|
+
};
|
|
49
50
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
for (const field of fields) {
|
|
53
|
-
picked[field] = error[field]
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
return picked
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
return baseTracingCollector
|
|
60
|
-
}
|
|
51
|
+
return baseTracingCollector;
|
|
52
|
+
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const { createBaseTracingCollector } = require('./base')
|
|
1
|
+
const { createBaseTracingCollector } = require('./base');
|
|
2
2
|
|
|
3
3
|
const mergeDefaultOptions = (options) => {
|
|
4
4
|
return Object.assign({
|
|
@@ -7,80 +7,80 @@ const mergeDefaultOptions = (options) => {
|
|
|
7
7
|
sendStartSpan: false,
|
|
8
8
|
sendFinishedSpan: true,
|
|
9
9
|
broadcast: false
|
|
10
|
-
}, options)
|
|
11
|
-
}
|
|
10
|
+
}, options);
|
|
11
|
+
};
|
|
12
12
|
|
|
13
13
|
module.exports = (options) => (runtime, tracer) => {
|
|
14
|
-
options = mergeDefaultOptions(options)
|
|
14
|
+
options = mergeDefaultOptions(options);
|
|
15
15
|
|
|
16
|
-
const exporter = createBaseTracingCollector(
|
|
16
|
+
const exporter = createBaseTracingCollector(runtime);
|
|
17
17
|
|
|
18
|
-
exporter.init(runtime, tracer)
|
|
18
|
+
exporter.init(runtime, tracer);
|
|
19
19
|
|
|
20
|
-
const queue = []
|
|
20
|
+
const queue = [];
|
|
21
21
|
|
|
22
|
-
let timer
|
|
22
|
+
let timer;
|
|
23
23
|
|
|
24
24
|
const generateTracingData = () => {
|
|
25
25
|
return Array
|
|
26
26
|
.from(queue)
|
|
27
27
|
.map(span => {
|
|
28
|
-
const newSpan = Object.assign({}, span)
|
|
28
|
+
const newSpan = Object.assign({}, span);
|
|
29
29
|
|
|
30
30
|
if (newSpan.error) {
|
|
31
|
-
newSpan.error = exporter.getErrorFields(newSpan.error)
|
|
31
|
+
newSpan.error = exporter.getErrorFields(newSpan.error, exporter.options.errors.fields);
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
return newSpan
|
|
35
|
-
})
|
|
36
|
-
}
|
|
34
|
+
return newSpan;
|
|
35
|
+
});
|
|
36
|
+
};
|
|
37
37
|
|
|
38
38
|
const flushQueue = () => {
|
|
39
|
-
if (queue.length === 0) return
|
|
39
|
+
if (queue.length === 0) return;
|
|
40
40
|
|
|
41
|
-
const data = generateTracingData()
|
|
42
|
-
queue.length = 0
|
|
41
|
+
const data = generateTracingData();
|
|
42
|
+
queue.length = 0;
|
|
43
43
|
|
|
44
44
|
if (options.broadcast) {
|
|
45
|
-
exporter.runtime.eventBus.broadcast(options.eventName, data)
|
|
45
|
+
exporter.runtime.eventBus.broadcast(options.eventName, data);
|
|
46
46
|
} else {
|
|
47
|
-
exporter.runtime.eventBus.emit(options.eventName, data)
|
|
47
|
+
exporter.runtime.eventBus.emit(options.eventName, data);
|
|
48
48
|
}
|
|
49
|
-
}
|
|
49
|
+
};
|
|
50
50
|
|
|
51
51
|
if (options.interval > 0) {
|
|
52
|
-
timer = setInterval(() => flushQueue(), options.interval)
|
|
53
|
-
timer.unref()
|
|
52
|
+
timer = setInterval(() => flushQueue(), options.interval);
|
|
53
|
+
timer.unref();
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
exporter.init = (runtime) => {
|
|
57
57
|
|
|
58
|
-
}
|
|
58
|
+
};
|
|
59
59
|
|
|
60
60
|
exporter.startedSpan = (span) => {
|
|
61
61
|
if (options.sendStartSpan) {
|
|
62
|
-
queue.push(span)
|
|
62
|
+
queue.push(span);
|
|
63
63
|
if (!timer) {
|
|
64
|
-
flushQueue()
|
|
64
|
+
flushQueue();
|
|
65
65
|
}
|
|
66
66
|
}
|
|
67
|
-
}
|
|
67
|
+
};
|
|
68
68
|
|
|
69
69
|
exporter.finishedSpan = (span) => {
|
|
70
70
|
if (options.sendFinishedSpan) {
|
|
71
|
-
queue.push(span)
|
|
71
|
+
queue.push(span);
|
|
72
72
|
if (!timer) {
|
|
73
|
-
flushQueue()
|
|
73
|
+
flushQueue();
|
|
74
74
|
}
|
|
75
75
|
}
|
|
76
|
-
}
|
|
76
|
+
};
|
|
77
77
|
|
|
78
78
|
exporter.stop = async () => {
|
|
79
79
|
if (timer) {
|
|
80
|
-
clearInterval(timer)
|
|
81
|
-
timer = null
|
|
80
|
+
clearInterval(timer);
|
|
81
|
+
timer = null;
|
|
82
82
|
}
|
|
83
|
-
}
|
|
83
|
+
};
|
|
84
84
|
|
|
85
|
-
return exporter
|
|
86
|
-
}
|
|
85
|
+
return exporter;
|
|
86
|
+
};
|
|
@@ -1,39 +1,39 @@
|
|
|
1
|
-
const { isFunction } = require('@weave-js/utils')
|
|
1
|
+
const { isFunction } = require('@weave-js/utils');
|
|
2
2
|
|
|
3
3
|
const collectors = {
|
|
4
4
|
// Console: require('./console'),
|
|
5
5
|
Event: require('./event'),
|
|
6
6
|
BaseCollector: require('./base')
|
|
7
|
-
}
|
|
7
|
+
};
|
|
8
8
|
|
|
9
9
|
const getByName = name => {
|
|
10
|
-
const n = Object.keys(collectors).find(collectorName => collectorName.toLowerCase() === name.toLowerCase())
|
|
11
|
-
return collectors[n]
|
|
12
|
-
}
|
|
10
|
+
const n = Object.keys(collectors).find(collectorName => collectorName.toLowerCase() === name.toLowerCase());
|
|
11
|
+
return collectors[n];
|
|
12
|
+
};
|
|
13
13
|
|
|
14
|
-
exports.resolveCollector = (runtime, collector
|
|
15
|
-
let CollectorClass
|
|
14
|
+
exports.resolveCollector = (runtime, collector) => {
|
|
15
|
+
let CollectorClass;
|
|
16
16
|
if (typeof collector === 'string') {
|
|
17
|
-
CollectorClass = getByName(collector)
|
|
17
|
+
CollectorClass = getByName(collector);
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
if (isFunction(collector)) {
|
|
21
|
-
return collector(runtime
|
|
21
|
+
return collector(runtime);
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
if (typeof collector === 'object') {
|
|
25
|
-
return collector
|
|
25
|
+
return collector;
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
if (!CollectorClass) {
|
|
29
|
-
runtime.handleError(new Error('Tracer not found'))
|
|
29
|
+
runtime.handleError(new Error('Tracer not found'));
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
return new CollectorClass(collector)
|
|
33
|
-
}
|
|
32
|
+
return new CollectorClass(collector);
|
|
33
|
+
};
|
|
34
34
|
|
|
35
|
-
exports.Base = collectors.BaseCollector
|
|
35
|
+
exports.Base = collectors.BaseCollector;
|
|
36
36
|
|
|
37
|
-
exports.Console = collectors.Console
|
|
37
|
+
exports.Console = collectors.Console;
|
|
38
38
|
|
|
39
|
-
exports.Event = collectors.Event
|
|
39
|
+
exports.Event = collectors.Event;
|
package/lib/tracing/span.js
CHANGED
|
@@ -1,61 +1,63 @@
|
|
|
1
|
-
const hrTime = require('./time')
|
|
1
|
+
const hrTime = require('./time');
|
|
2
2
|
|
|
3
3
|
exports.createSpan = (tracer, name, options) => {
|
|
4
4
|
const span = Object.assign({}, {
|
|
5
5
|
name,
|
|
6
|
-
id: options.id || tracer.
|
|
7
|
-
traceId: options.traceId || tracer.
|
|
6
|
+
id: options.id || tracer.runtime.generateUUID(),
|
|
7
|
+
traceId: options.traceId || tracer.runtime.generateUUID(),
|
|
8
8
|
parentId: options.parentId,
|
|
9
9
|
type: options.type,
|
|
10
10
|
sampled: options.sampled || tracer.shouldSample(),
|
|
11
11
|
service: options.service,
|
|
12
12
|
tags: {}
|
|
13
|
-
})
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
if (options.service) {
|
|
16
|
+
span.service = {
|
|
17
|
+
name: options.service.name,
|
|
18
|
+
version: options.service.version,
|
|
19
|
+
fullyQualifiedName: options.service.fullyQualifiedName
|
|
20
|
+
};
|
|
19
21
|
}
|
|
20
22
|
|
|
21
23
|
span.addTags = (tags) => {
|
|
22
|
-
Object.assign(span.tags, tags)
|
|
23
|
-
return span
|
|
24
|
-
}
|
|
24
|
+
Object.assign(span.tags, tags);
|
|
25
|
+
return span;
|
|
26
|
+
};
|
|
25
27
|
|
|
26
28
|
span.start = (time) => {
|
|
27
|
-
span.startTime = time || hrTime()
|
|
28
|
-
tracer.invokeCollectorMethod('startedSpan', [span])
|
|
29
|
-
return span
|
|
30
|
-
}
|
|
29
|
+
span.startTime = time || hrTime();
|
|
30
|
+
tracer.invokeCollectorMethod('startedSpan', [span]);
|
|
31
|
+
return span;
|
|
32
|
+
};
|
|
31
33
|
|
|
32
34
|
span.startChildSpan = (name, options) => {
|
|
33
35
|
const parentOptions = {
|
|
34
36
|
parentId: options.parentId,
|
|
35
37
|
sampled: options.sampled
|
|
36
|
-
}
|
|
37
|
-
return tracer.startSpan(name, Object.assign(parentOptions, options))
|
|
38
|
-
}
|
|
38
|
+
};
|
|
39
|
+
return tracer.startSpan(name, Object.assign(parentOptions, options));
|
|
40
|
+
};
|
|
39
41
|
|
|
40
42
|
span.finish = (time) => {
|
|
41
|
-
span.finishTime = time || hrTime()
|
|
42
|
-
span.duration = span.finishTime - span.startTime
|
|
43
|
-
tracer.log.debug('Span finished')
|
|
44
|
-
tracer.invokeCollectorMethod('finishedSpan', [span])
|
|
43
|
+
span.finishTime = time || hrTime();
|
|
44
|
+
span.duration = span.finishTime - span.startTime;
|
|
45
|
+
tracer.log.debug('Span finished');
|
|
46
|
+
tracer.invokeCollectorMethod('finishedSpan', [span]);
|
|
45
47
|
|
|
46
|
-
return span
|
|
47
|
-
}
|
|
48
|
+
return span;
|
|
49
|
+
};
|
|
48
50
|
|
|
49
|
-
span.isActive = () => span.finishTime !== null
|
|
51
|
+
span.isActive = () => span.finishTime !== null;
|
|
50
52
|
|
|
51
53
|
span.setError = (error) => {
|
|
52
|
-
span.error = error
|
|
53
|
-
return span
|
|
54
|
-
}
|
|
54
|
+
span.error = error;
|
|
55
|
+
return span;
|
|
56
|
+
};
|
|
55
57
|
|
|
56
58
|
if (options.tags) {
|
|
57
|
-
span.addTags(options.tags)
|
|
59
|
+
span.addTags(options.tags);
|
|
58
60
|
}
|
|
59
61
|
|
|
60
|
-
return span
|
|
61
|
-
}
|
|
62
|
+
return span;
|
|
63
|
+
};
|