@weave-js/core 0.13.0 → 0.14.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.
@@ -21,6 +21,8 @@ const { WeaveMaxCallLevelError, WeaveError } = require('../errors');
21
21
  * @returns {Context} Context
22
22
  */
23
23
  exports.createContext = (runtime) => {
24
+ const spanStack = [];
25
+
24
26
  /** @type {Context} */
25
27
  const context = {
26
28
  id: null,
@@ -95,17 +97,33 @@ exports.createContext = (runtime) => {
95
97
  sampled: this.tracing
96
98
  }, options);
97
99
 
100
+ let span;
101
+
98
102
  if (this.span) {
99
- this.span = this.span.startChildSpan(name, options);
103
+ span = this.span.startChildSpan(name, options);
100
104
  } else {
101
- this.span = runtime.tracer.startSpan(name, options);
105
+ span = runtime.tracer.startSpan(name, options);
102
106
  }
107
+ spanStack.push(span);
108
+ this.span = span;
109
+
103
110
  return this.span;
104
111
  },
105
- finishSpan () {
106
- if (this.span) {
107
- this.span.finish();
108
- return this.span;
112
+ finishSpan (span, time) {
113
+ if (span && !span.isActive()) {
114
+ return;
115
+ }
116
+
117
+ span.finish(time);
118
+
119
+ const idx = spanStack.findIndex((s) => s === span);
120
+
121
+ if (idx !== -1) {
122
+ spanStack.splice(idx, 1);
123
+ this.span = spanStack[spanStack.length - 1];
124
+ } else {
125
+ /* istanbul ignore next */
126
+ this.service.log.warn('This span is not assigned to this context', span);
109
127
  }
110
128
  },
111
129
  /**
@@ -132,6 +150,8 @@ exports.createContext = (runtime) => {
132
150
  }
133
151
  };
134
152
 
153
+
154
+
135
155
  // Generate context Id
136
156
  if (!context.id) {
137
157
  // Use UUID factory from broker options
@@ -82,6 +82,7 @@ exports.getDefaultOptions = () => {
82
82
  collectors: [],
83
83
  actions: {
84
84
  data: false,
85
+ response: false,
85
86
  tags: {}
86
87
  },
87
88
  events: {
package/lib/errors.js CHANGED
@@ -8,7 +8,7 @@ const { defaultsDeep } = require('@weave-js/utils');
8
8
  const { ExtendableError } = require('./ExtendableError');
9
9
 
10
10
  class WeaveError extends ExtendableError {
11
- constructor (message, options) { // code, type, data
11
+ constructor (message, options) {
12
12
  options = defaultsDeep(
13
13
  options,
14
14
  {
@@ -22,10 +22,6 @@ class WeaveError extends ExtendableError {
22
22
  this.code = options.code || 'WEAVE_ERROR';
23
23
  this.data = options.data;
24
24
  this.retryable = false;
25
-
26
- if (options.statusCode) {
27
- this.statusCode = options.statusCode;
28
- }
29
25
  }
30
26
  }
31
27
 
@@ -4,22 +4,56 @@
4
4
  * Copyright 2021 Fachwerk
5
5
  */
6
6
 
7
- const { isPlainObject } = require('@weave-js/utils');
7
+ const { isPlainObject, isFunction, isObject, dotGet } = require('@weave-js/utils');
8
8
  const { buildActionTags, buildEventTags } = require('./tags');
9
9
 
10
- const wrapTracingLocalActionMiddleware = function (handler) {
10
+ const wrapTracingLocalActionMiddleware = function (handler, action) {
11
11
  const broker = this;
12
12
  const tracingOptions = broker.options.tracing || {};
13
+ const actionTracingOptions = action.tracing || {};
13
14
 
14
15
  if (tracingOptions.enabled) {
15
16
  return function metricsLocalMiddleware (context, serviceInjections) {
16
17
  const tags = buildActionTags(context, tracingOptions);
17
18
 
18
- if (tracingOptions) {
19
+ if (tracingOptions.actions.data) {
19
20
  tags.data = context.data !== null && isPlainObject(context.data) ? Object.assign({}, context.data) : context.data;
20
21
  }
21
22
 
22
- const spanName = `action "${context.action.name}"`;
23
+ const globalActionTags = tracingOptions.actions.tags;
24
+ let actionTags;
25
+ // local action tags take precedence
26
+ if (isFunction(actionTracingOptions.tags)) {
27
+ actionTags = actionTracingOptions.tags;
28
+ } else if (!actionTracingOptions.tags && isFunction(globalActionTags)) {
29
+ actionTags = globalActionTags;
30
+ } else {
31
+ // By default all params are captured. This can be overridden globally and locally
32
+ actionTags = { ...{ data: true }, ...globalActionTags, ...actionTracingOptions.tags };
33
+ }
34
+
35
+ if (isObject(actionTracingOptions.tags)) {
36
+ if (Array.isArray(actionTags.data)) {
37
+ tags.data = actionTags.data.reduce((acc, current) => {
38
+ acc[current] = dotGet(context.data, current);
39
+ return acc;
40
+ }, {});
41
+ }
42
+ }
43
+
44
+ // Span name
45
+ let spanName = `action "${context.action.name}"`;
46
+
47
+ if (actionTracingOptions.spanName) {
48
+ switch (typeof actionTracingOptions.spanName) {
49
+ case 'string':
50
+ spanName = actionTracingOptions.spanName;
51
+ break;
52
+ case 'function':
53
+ spanName = actionTracingOptions.spanName.call(context.service, context);
54
+ break;
55
+ }
56
+ }
23
57
 
24
58
  const span = context.startSpan(spanName, {
25
59
  id: context.id,
@@ -39,18 +73,17 @@ const wrapTracingLocalActionMiddleware = function (handler) {
39
73
  isCachedResult: context.isCachedResult
40
74
  };
41
75
 
42
- if (tracingOptions) {
76
+ if (tracingOptions.actions.response) {
43
77
  tags.response = result !== null && isPlainObject(result) ? Object.assign({}, result) : result;
44
78
  }
45
79
 
46
80
  span.addTags(tags);
47
- span.finish();
81
+ context.finishSpan(span);
48
82
  return result;
49
83
  })
50
84
  .catch(error => {
51
- span
52
- .setError(error)
53
- .finish();
85
+ span.setError(error);
86
+ context.finishSpan(span);
54
87
  return Promise.reject(error);
55
88
  });
56
89
  };
@@ -81,13 +114,12 @@ const wrapTracingLocalEventMiddleware = function (handler, event) {
81
114
 
82
115
  return handler(context)
83
116
  .then(result => {
84
- span.finish();
117
+ context.finishSpan(span);
85
118
  return result;
86
119
  })
87
120
  .catch(error => {
88
- span
89
- .setError(error)
90
- .finish();
121
+ span.setError(error);
122
+ context.finishSpan(span);
91
123
  return Promise.reject(error);
92
124
  });
93
125
  };
@@ -42,7 +42,7 @@ exports.createSpan = (tracer, name, options) => {
42
42
  span.finish = (time) => {
43
43
  span.finishTime = time || hrTime();
44
44
  span.duration = span.finishTime - span.startTime;
45
- tracer.log.debug('Span finished');
45
+ tracer.log.debug(`Span "${span.id}" finished`);
46
46
  tracer.invokeCollectorMethod('finishedSpan', [span]);
47
47
 
48
48
  return span;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@weave-js/core",
3
- "version": "0.13.0",
3
+ "version": "0.14.0",
4
4
  "description": "The core package of weave",
5
5
  "keywords": [
6
6
  "Weave",
@@ -40,14 +40,14 @@
40
40
  "license": "MIT",
41
41
  "dependencies": {
42
42
  "@weave-js/errors": "^0.9.1",
43
- "@weave-js/utils": "^0.12.0",
44
- "@weave-js/validator": "^0.13.0",
45
- "eventemitter2": "^6.4.5",
46
- "glob": "^7.2.0"
43
+ "@weave-js/utils": "^0.13.0",
44
+ "@weave-js/validator": "^0.14.0",
45
+ "eventemitter2": "^6.4.9",
46
+ "glob": "^10.2.2"
47
47
  },
48
48
  "directories": {
49
49
  "lib": "lib",
50
50
  "test": "test"
51
51
  },
52
- "gitHead": "6772c8bfb00be1da32c17cff621a8abcd98a08fc"
52
+ "gitHead": "c2f63481b2a72ae03a35682c9a6d12800f22dbf2"
53
53
  }