@theotherwillembotha/node-red-plugincore 0.1.0 → 0.2.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.
Files changed (134) hide show
  1. package/README.md +616 -220
  2. package/build/GenerateNodes.js +3 -6
  3. package/build/Nodes.html +3 -1504
  4. package/build/Nodes.js +5 -15
  5. package/build/Plugins.html +227 -0
  6. package/build/Plugins.js +18 -8
  7. package/build/core/NodeConstructor.d.ts +9 -16
  8. package/build/core/NodeConstructor.d.ts.map +1 -1
  9. package/build/core/NodeConstructor.js +109 -146
  10. package/build/core/NodeGenerator.d.ts.map +1 -1
  11. package/build/core/NodeGenerator.js +79 -28
  12. package/build/core/NodeManagerRuntime.d.ts +44 -0
  13. package/build/core/NodeManagerRuntime.d.ts.map +1 -0
  14. package/build/core/NodeManagerRuntime.js +140 -0
  15. package/build/core/Utils.d.ts.map +1 -1
  16. package/build/core/logger/service/LoggerService.d.ts +6 -5
  17. package/build/core/logger/service/LoggerService.d.ts.map +1 -1
  18. package/build/core/logger/service/LoggerService.js +51 -20
  19. package/build/core/logger/template/LoggerTemplate.d.ts.map +1 -1
  20. package/build/core/metrics/MetricsDecorator.d.ts +1 -2
  21. package/build/core/metrics/MetricsDecorator.d.ts.map +1 -1
  22. package/build/core/metrics/MetricsDecorator.js +89 -116
  23. package/build/core/metrics/node/CounterMetricConfigNode.d.ts.map +1 -1
  24. package/build/core/metrics/node/CounterMetricConfigNode.js +4 -5
  25. package/build/core/metrics/node/GaugeMetricConfigNode.d.ts.map +1 -1
  26. package/build/core/metrics/node/GaugeMetricConfigNode.js +5 -6
  27. package/build/core/metrics/node/MetricsConfigNode.d.ts +19 -9
  28. package/build/core/metrics/node/MetricsConfigNode.d.ts.map +1 -1
  29. package/build/core/metrics/node/MetricsConfigNode.js +14 -45
  30. package/build/core/metrics/node/TimerMetricConfigNode.d.ts.map +1 -1
  31. package/build/core/metrics/node/TimerMetricConfigNode.js +11 -17
  32. package/build/core/metrics/service/MetricsService.d.ts +110 -114
  33. package/build/core/metrics/service/MetricsService.d.ts.map +1 -1
  34. package/build/core/metrics/service/MetricsService.js +122 -339
  35. package/build/core/metrics/template/CounterMetricTemplate.d.ts.map +1 -1
  36. package/build/core/metrics/template/GaugeMetricTemplate.d.ts.map +1 -1
  37. package/build/core/metrics/template/MetricsTemplate.d.ts.map +1 -1
  38. package/build/core/metrics/template/MetricsTemplate.js +1 -2
  39. package/build/core/metrics/template/TimerMetricTemplate.d.ts.map +1 -1
  40. package/build/core/other/node/DelegatedConfigReferenceNode.d.ts +1 -1
  41. package/build/core/other/node/DelegatedConfigReferenceNode.d.ts.map +1 -1
  42. package/build/core/other/node/DelegatedConfigReferenceNode.js +1 -1
  43. package/build/core/other/service/InputService.d.ts.map +1 -1
  44. package/build/core/other/service/SettingsService.d.ts +1 -2
  45. package/build/core/other/service/SettingsService.d.ts.map +1 -1
  46. package/build/core/other/service/SettingsService.js +19 -5
  47. package/build/core/other/template/BasicTemplate.d.ts.map +1 -1
  48. package/build/core/other/template/SettingsTemplate.d.ts.map +1 -1
  49. package/build/core/state/node/InternalStateConfigNode.d.ts +16 -0
  50. package/build/core/state/node/InternalStateConfigNode.d.ts.map +1 -0
  51. package/build/core/state/node/InternalStateConfigNode.js +89 -0
  52. package/build/core/state/node/StateConfigNode.d.ts +24 -0
  53. package/build/core/state/node/StateConfigNode.d.ts.map +1 -0
  54. package/build/core/state/node/StateConfigNode.js +22 -0
  55. package/build/core/state/service/StateService.d.ts +34 -0
  56. package/build/core/state/service/StateService.d.ts.map +1 -0
  57. package/build/core/state/service/StateService.js +201 -0
  58. package/build/core/state/template/StateTemplate.d.ts +8 -0
  59. package/build/core/state/template/StateTemplate.d.ts.map +1 -0
  60. package/build/core/state/template/StateTemplate.js +11 -0
  61. package/build/core/tagging/ServiceDescriptionDecorator.d.ts +10 -0
  62. package/build/core/tagging/ServiceDescriptionDecorator.d.ts.map +1 -0
  63. package/build/core/tagging/ServiceDescriptionDecorator.js +10 -0
  64. package/build/core/tagging/service/NodeTypeService.d.ts +1 -2
  65. package/build/core/tagging/service/NodeTypeService.d.ts.map +1 -1
  66. package/build/core/tagging/service/NodeTypeService.js +19 -5
  67. package/build/core/ui/template/ScriptEditorTemplate.d.ts.map +1 -1
  68. package/build/core/ui/template/UIHelperTemplate.d.ts.map +1 -1
  69. package/build/core/webhook/node/WebhookServerConfigNode.d.ts.map +1 -1
  70. package/build/core/webhook/service/ReverseProxyTypeService.d.ts.map +1 -1
  71. package/build/core/webhook/service/WebhookServerService.d.ts +3 -4
  72. package/build/core/webhook/service/WebhookServerService.d.ts.map +1 -1
  73. package/build/core/webhook/service/WebhookServerService.js +48 -18
  74. package/build/core/webhook/template/WebhookTemplate.d.ts.map +1 -1
  75. package/build/index.d.ts +5 -2
  76. package/build/index.d.ts.map +1 -1
  77. package/build/index.js +6 -2
  78. package/build/runtime/NodeManagerRuntime.js +140 -0
  79. package/documentation/CounterMetricConfigNode.png +0 -0
  80. package/documentation/GaugeMetricConfigNode.png +0 -0
  81. package/documentation/LoggerTemplate.png +0 -0
  82. package/documentation/MetricsTemplate.png +0 -0
  83. package/documentation/StateTemplate.png +0 -0
  84. package/documentation/TimerMetricConfigNode_histogram.png +0 -0
  85. package/documentation/TimerMetricConfigNode_summary.png +0 -0
  86. package/documentation/WebhookServerConfigNode.png +0 -0
  87. package/documentation/WebhookTemplate.png +0 -0
  88. package/package.json +4 -10
  89. package/src/GenerateNodes.ts +7 -11
  90. package/src/core/NodeConstructor.ts +130 -186
  91. package/src/core/NodeGenerator.ts +88 -33
  92. package/src/core/NodeManagerRuntime.ts +179 -0
  93. package/src/core/logger/service/LoggerService.ts +39 -26
  94. package/src/core/logger/template/LoggerTemplate.html +11 -6
  95. package/src/core/metrics/MetricsDecorator.ts +140 -168
  96. package/src/core/metrics/node/CounterMetricConfigNode.ts +20 -20
  97. package/src/core/metrics/node/GaugeMetricConfigNode.ts +24 -25
  98. package/src/core/metrics/node/MetricsConfigNode.ts +29 -48
  99. package/src/core/metrics/node/TimerMetricConfigNode.ts +50 -59
  100. package/src/core/metrics/service/MetricsService.ts +214 -489
  101. package/src/core/metrics/template/CounterMetricTemplate.html +0 -1
  102. package/src/core/metrics/template/GaugeMetricTemplate.html +1 -1
  103. package/src/core/metrics/template/MetricsTemplate.html +132 -13
  104. package/src/core/metrics/template/MetricsTemplate.ts +3 -4
  105. package/src/core/other/node/DelegatedConfigReferenceNode.ts +1 -1
  106. package/src/core/other/service/SettingsService.ts +6 -10
  107. package/src/core/other/template/BasicTemplate.html +1 -1
  108. package/src/core/state/node/InternalStateConfigNode.html +77 -0
  109. package/src/core/state/node/InternalStateConfigNode.ts +102 -0
  110. package/src/core/state/node/StateConfigNode.ts +29 -0
  111. package/src/core/state/service/StateService.ts +180 -0
  112. package/src/core/state/template/StateTemplate.html +244 -0
  113. package/src/core/state/template/StateTemplate.ts +17 -0
  114. package/src/core/tagging/ServiceDescriptionDecorator.ts +23 -0
  115. package/src/core/tagging/service/NodeTypeService.ts +6 -11
  116. package/src/core/ui/template/UIHelperTemplate.html +41 -26
  117. package/src/core/webhook/service/WebhookServerService.ts +39 -23
  118. package/src/core/webhook/template/WebhookTemplate.html +28 -35
  119. package/src/index.ts +7 -2
  120. package/build/core/logger/node/ConsoleLoggerConfigNode.d.ts +0 -20
  121. package/build/core/logger/node/ConsoleLoggerConfigNode.d.ts.map +0 -1
  122. package/build/core/logger/node/ConsoleLoggerConfigNode.js +0 -62
  123. package/build/core/logger/node/RestLoggerConfigNode.d.ts +0 -40
  124. package/build/core/logger/node/RestLoggerConfigNode.d.ts.map +0 -1
  125. package/build/core/logger/node/RestLoggerConfigNode.js +0 -128
  126. package/documentation/ConsoleLoggerConfigNode.png +0 -0
  127. package/documentation/MetricsConfigNode.png +0 -0
  128. package/documentation/RestLoggerConfigNode.png +0 -0
  129. package/documentation/TimerMetricConfigNode.png +0 -0
  130. package/documentation/WebhookNode.png +0 -0
  131. package/src/core/logger/node/ConsoleLoggerConfigNode.html +0 -90
  132. package/src/core/logger/node/ConsoleLoggerConfigNode.ts +0 -71
  133. package/src/core/logger/node/RestLoggerConfigNode.html +0 -183
  134. package/src/core/logger/node/RestLoggerConfigNode.ts +0 -170
@@ -1,221 +1,193 @@
1
1
 
2
2
  import { BaseNode, NodeManager } from "../NodeConstructor";
3
- import { BucketType, CounterMetricConfig, DefaultBucketConfig, ExponentialBucketConfig, HistogramMetricConfig, LinearBucketConfig, ManualBucketConfig, MetricsContainer, Metric, MetricConfig, CounterMetric, HistogramMetric, SummaryMetric, GaugeMetric, GaugeMetricConfig } from "./service/MetricsService";
3
+ import {
4
+ MetricCapability,
5
+ MetricsContainer,
6
+ CounterMetricConfig,
7
+ GaugeMetricConfig,
8
+ HistogramMetricConfig,
9
+ BucketType,
10
+ CounterMetric,
11
+ HistogramMetric,
12
+ SummaryMetric,
13
+ GaugeMetric,
14
+ DoNothingCounterMetric,
15
+ DoNothingGaugeMetric,
16
+ DoNothingHistogramMetric,
17
+ DoNothingSummaryMetric,
18
+ DoNothingMetricsContainer,
19
+ } from "./service/MetricsService";
4
20
  import { MetricsTemplateConfig } from "./template/MetricsTemplate";
5
21
 
6
22
  export enum MetricType {
7
23
  Counter = "Counter",
8
- Timer = "Timer",
9
- Gauge = "Gauge",
24
+ Timer = "Timer",
25
+ Gauge = "Gauge",
10
26
  }
11
27
 
12
28
  export enum MetricCollectorType {
13
29
  histogram = "histogram",
14
- summary = "summary",
30
+ summary = "summary",
15
31
  }
16
32
 
17
-
18
33
  type BaseMetricDecoratorConfig = {
19
- name:string;
20
- type:MetricType;
21
- description:string;
22
- }
23
-
24
- type CounterMetricDecoratorConfig = BaseMetricDecoratorConfig & {
25
- type:MetricType.Counter
34
+ name: string;
35
+ type: MetricType;
36
+ description: string;
26
37
  }
27
38
 
28
- type GaugeMetricDecoratorConfig = BaseMetricDecoratorConfig & {
29
- type:MetricType.Gauge
30
- }
39
+ type CounterMetricDecoratorConfig = BaseMetricDecoratorConfig & { type: MetricType.Counter }
40
+ type GaugeMetricDecoratorConfig = BaseMetricDecoratorConfig & { type: MetricType.Gauge }
31
41
 
32
42
  type TimerMetricDecoratorConfig = BaseMetricDecoratorConfig & {
33
- type:MetricType.Timer,
34
- collector:MetricCollectorType,
43
+ type: MetricType.Timer,
44
+ collector: MetricCollectorType,
35
45
  }
36
46
 
37
47
  type SummaryTimerMetricDecoratorConfig = TimerMetricDecoratorConfig & {
38
- collector:MetricCollectorType.summary,
48
+ collector: MetricCollectorType.summary,
39
49
  }
40
50
 
41
51
  type HistogramTimerMetricDecoratorConfig = TimerMetricDecoratorConfig & {
42
- collector:MetricCollectorType.histogram,
43
- buckettype:BucketType,
44
- //bucketconfig:DefaultBucketConfig|ManualBucketConfig|LinearBucketConfig|ExponentialBucketConfig,
52
+ collector: MetricCollectorType.histogram,
53
+ buckettype: BucketType,
45
54
  }
46
55
 
47
56
  type DefaultHistogramTimerMetricDecoratorConfig = HistogramTimerMetricDecoratorConfig & {
48
- buckettype:BucketType.default,
49
- bucketconfig?:DefaultBucketConfig
57
+ buckettype: BucketType.default,
50
58
  }
51
59
 
52
- type MetricsConfig =
53
- CounterMetricDecoratorConfig |
54
- GaugeMetricDecoratorConfig |
55
- SummaryTimerMetricDecoratorConfig |
60
+ type MetricsConfig =
61
+ CounterMetricDecoratorConfig |
62
+ GaugeMetricDecoratorConfig |
63
+ SummaryTimerMetricDecoratorConfig |
56
64
  DefaultHistogramTimerMetricDecoratorConfig
57
65
 
58
- export function Metrics(metricsConfig: MetricsConfig):Function {
66
+ function resolveMetric(
67
+ node: BaseNode<MetricsTemplateConfig>,
68
+ metricsConfig: MetricsConfig,
69
+ _metrics: MetricsContainer
70
+ ): CounterMetric | GaugeMetric | HistogramMetric | SummaryMetric | undefined {
71
+
72
+ const nde = {
73
+ id: node.id(),
74
+ name: node.name(),
75
+ flow: node.flow(),
76
+ type: node.type()
77
+ };
78
+
79
+ if (metricsConfig.type === MetricType.Counter) {
80
+ if (!_metrics.supports(MetricCapability.Counter)) {
81
+ console.warn(`[PluginCore] @Metrics Counter requested by node "${node.name()}" (${node.type()}) but the selected provider does not support Counter. Using DoNothing.`);
82
+ }
83
+ const counterConfig: CounterMetricConfig = {
84
+ metricname: metricsConfig.name,
85
+ metricdescription: metricsConfig.description,
86
+ node: nde
87
+ };
88
+ return _metrics.counter(counterConfig);
89
+ }
90
+
91
+ if (metricsConfig.type === MetricType.Gauge) {
92
+ if (!_metrics.supports(MetricCapability.Gauge)) {
93
+ console.warn(`[PluginCore] @Metrics Gauge requested by node "${node.name()}" (${node.type()}) but the selected provider does not support Gauge. Using DoNothing.`);
94
+ }
95
+ const gaugeConfig: GaugeMetricConfig = {
96
+ metricname: metricsConfig.name,
97
+ metricdescription: metricsConfig.description,
98
+ node: nde
99
+ };
100
+ return _metrics.gauge(gaugeConfig);
101
+ }
102
+
103
+ if (metricsConfig.type === MetricType.Timer) {
104
+ if (metricsConfig.collector === MetricCollectorType.histogram) {
105
+ if (!_metrics.supports(MetricCapability.Histogram)) {
106
+ console.warn(`[PluginCore] @Metrics Histogram requested by node "${node.name()}" (${node.type()}) but the selected provider does not support Histogram. Using DoNothing.`);
107
+ }
108
+ if (metricsConfig.buckettype === BucketType.default) {
109
+ const histogramConfig: HistogramMetricConfig = {
110
+ metricname: metricsConfig.name,
111
+ metricdescription: metricsConfig.description,
112
+ buckettype: metricsConfig.buckettype,
113
+ bucketconfig: {},
114
+ node: nde
115
+ };
116
+ return _metrics.histogram(histogramConfig);
117
+ }
118
+ }
119
+ if (metricsConfig.collector === MetricCollectorType.summary) {
120
+ if (!_metrics.supports(MetricCapability.Summary)) {
121
+ console.warn(`[PluginCore] @Metrics Summary requested by node "${node.name()}" (${node.type()}) but the selected provider does not support Summary. Using DoNothing.`);
122
+ }
123
+ }
124
+ }
125
+
126
+ console.error("[PluginCore] @Metrics: no factory matched for config", metricsConfig);
127
+ return undefined;
128
+ }
129
+
130
+ function resolveContainer(metricsReference: string): MetricsContainer {
131
+ if (!metricsReference) return new DoNothingMetricsContainer();
132
+ const refNode = NodeManager.RED.nodes.getNode(metricsReference);
133
+ return refNode ? (refNode as any).node().metrics() as MetricsContainer : new DoNothingMetricsContainer();
134
+ }
135
+
136
+ function dudForType(metricsConfig: MetricsConfig): CounterMetric | GaugeMetric | HistogramMetric | SummaryMetric | undefined {
137
+ if (metricsConfig.type === MetricType.Counter) return new DoNothingCounterMetric();
138
+ if (metricsConfig.type === MetricType.Gauge) return new DoNothingGaugeMetric();
139
+ if (metricsConfig.type === MetricType.Timer) {
140
+ if (metricsConfig.collector === MetricCollectorType.histogram) return new DoNothingHistogramMetric();
141
+ if (metricsConfig.collector === MetricCollectorType.summary) return new DoNothingSummaryMetric();
142
+ }
143
+ return undefined;
144
+ }
145
+
146
+ export function Metrics(metricsConfig: MetricsConfig): Function {
59
147
  return function (target: any, propertyKey: string | symbol) {
60
148
 
61
- // if the type is a string, then its probably defined in the local (core) module.
62
- if(typeof propertyKey === "string"){
149
+ if (typeof propertyKey === "string") {
63
150
  const valueSymbol = Symbol(`_${String(propertyKey)}_value`);
64
151
 
65
152
  Object.defineProperty(target, propertyKey, {
66
153
  get: function() {
67
- if(this[valueSymbol]){
68
- return this[valueSymbol];
69
- }
70
-
71
- //console.log("injecting metric", valueSymbol);
72
- let node = this as BaseNode<MetricsTemplateConfig>;
73
- let config = node.config();
74
-
75
- if(config.metricsEnabled){
76
- let _metrics = (NodeManager.RED.nodes.getNode(config.metricsReference) as any).node().metrics() as MetricsContainer;
77
-
78
- let nde = {
79
- id:node.id(),
80
- name:node.name(),
81
- flow:node.flow(),
82
- type:node.type()
83
- }
154
+ if (this[valueSymbol]) return this[valueSymbol];
84
155
 
85
- // counter metric
86
- if(metricsConfig.type === MetricType.Counter){
87
- let counterConfig:CounterMetricConfig = {
88
- metricname:metricsConfig.name,
89
- metricdescription:metricsConfig.description,
90
- node:nde
91
- };
92
- this[valueSymbol] = _metrics.counter(counterConfig);
93
- return this[valueSymbol];
94
- }
156
+ const node = this as BaseNode<MetricsTemplateConfig>;
157
+ const config = node.config();
95
158
 
96
- // gauge metric
97
- if(metricsConfig.type === MetricType.Gauge){
98
- let gaugeConfig:GaugeMetricConfig = {
99
- metricname:metricsConfig.name,
100
- metricdescription:metricsConfig.description,
101
- node:nde
102
- };
103
- this[valueSymbol] = _metrics.gauge(gaugeConfig);
104
- return this[valueSymbol];
105
- }
159
+ if (config.metricsEnabled) {
160
+ const _metrics = resolveContainer(config.metricsReference);
161
+ this[valueSymbol] = resolveMetric(node, metricsConfig, _metrics);
162
+ } else {
163
+ this[valueSymbol] = dudForType(metricsConfig);
164
+ }
106
165
 
107
- // timer metric.
108
- if(metricsConfig.type === MetricType.Timer){
109
-
110
- // handle it as a histogram collector.
111
- if(metricsConfig.collector === MetricCollectorType.histogram){
112
-
113
- // handle it as the default bucket.
114
- if(metricsConfig.buckettype === BucketType.default){
115
- let histogramConfig:HistogramMetricConfig = {
116
- metricname:metricsConfig.name,
117
- metricdescription:metricsConfig.description,
118
- buckettype:metricsConfig.buckettype,
119
- bucketconfig:{},
120
- node:nde
121
- };
122
- this[valueSymbol] = _metrics.histogram(histogramConfig);
123
- return this[valueSymbol];
124
- }
125
- }
126
- }
127
- console.error("No Metric Factory type defined for ", metricsConfig);
128
- return this[valueSymbol];
129
- }
130
-
131
- this[valueSymbol] =
132
- (metricsConfig.type === MetricType.Counter) ? { inc(){}, reset(){} } as CounterMetric :
133
- (metricsConfig.type === MetricType.Gauge) ? { inc(){}, dec(){}, reset(){} } as GaugeMetric :
134
- (metricsConfig.type === MetricType.Timer) ? { observe(val:number){} } as HistogramMetric | SummaryMetric
135
- : undefined;
136
166
  return this[valueSymbol];
137
167
  },
138
168
  enumerable: true,
139
169
  configurable: false
140
170
  });
141
- return
142
- }
143
- else{
171
+
172
+ } else {
144
173
  let property = propertyKey as any;
145
- property.addInitializer(function(this:BaseNode<MetricsTemplateConfig>){
146
- let node = this as BaseNode<MetricsTemplateConfig>
174
+ property.addInitializer(function(this: BaseNode<MetricsTemplateConfig>) {
175
+ const node = this;
147
176
  const valueSymbol = Symbol(`_${String(property.name)}_value`);
148
177
 
149
178
  Object.defineProperty(node, property.name, {
150
179
  get: function() {
151
- if(this[valueSymbol]){
152
- return this[valueSymbol];
180
+ if (this[valueSymbol]) return this[valueSymbol];
181
+
182
+ const config = node.config();
183
+
184
+ if (config.metricsEnabled) {
185
+ const _metrics = resolveContainer(config.metricsReference);
186
+ this[valueSymbol] = resolveMetric(node, metricsConfig, _metrics);
187
+ } else {
188
+ this[valueSymbol] = dudForType(metricsConfig);
153
189
  }
154
190
 
155
- //console.log("injecting metric", valueSymbol);
156
- let config = node.config();
157
-
158
- if(config.metricsEnabled){
159
- let _metrics = (NodeManager.RED.nodes.getNode(config.metricsReference) as any).node().metrics() as MetricsContainer;
160
-
161
- let nde = {
162
- id:node.id(),
163
- name:node.name(),
164
- flow:node.flow(),
165
- type:node.type()
166
- }
167
-
168
- // counter metric
169
- if(metricsConfig.type === MetricType.Counter){
170
- let counterConfig:CounterMetricConfig = {
171
- metricname:metricsConfig.name,
172
- metricdescription:metricsConfig.description,
173
- node:nde
174
- };
175
- this[valueSymbol] = _metrics.counter(counterConfig);
176
- return this[valueSymbol];
177
- }
178
-
179
- // gauge metric
180
- if(metricsConfig.type === MetricType.Gauge){
181
- let gaugeConfig:GaugeMetricConfig = {
182
- metricname:metricsConfig.name,
183
- metricdescription:metricsConfig.description,
184
- node:nde
185
- };
186
- this[valueSymbol] = _metrics.gauge(gaugeConfig);
187
- return this[valueSymbol];
188
- }
189
-
190
- // timer metric.
191
- if(metricsConfig.type === MetricType.Timer){
192
-
193
- // handle it as a histogram collector.
194
- if(metricsConfig.collector === MetricCollectorType.histogram){
195
-
196
- // handle it as the default bucket.
197
- if(metricsConfig.buckettype === BucketType.default){
198
- let histogramConfig:HistogramMetricConfig = {
199
- metricname:metricsConfig.name,
200
- metricdescription:metricsConfig.description,
201
- buckettype:metricsConfig.buckettype,
202
- bucketconfig:{},
203
- node:nde
204
- };
205
- this[valueSymbol] = _metrics.histogram(histogramConfig);
206
- return this[valueSymbol];
207
- }
208
- }
209
- }
210
- console.error("No Metric Factory type defined for ", metricsConfig);
211
- return this[valueSymbol];
212
- }
213
-
214
- this[valueSymbol] =
215
- (metricsConfig.type === MetricType.Counter) ? { inc(){}, reset(){} } as CounterMetric :
216
- (metricsConfig.type === MetricType.Gauge) ? { inc(){}, dec(){}, reset(){} } as GaugeMetric :
217
- (metricsConfig.type === MetricType.Timer) ? { observe(val:number){} } as HistogramMetric | SummaryMetric
218
- : undefined;
219
191
  return this[valueSymbol];
220
192
  },
221
193
  enumerable: true,
@@ -224,4 +196,4 @@ export function Metrics(metricsConfig: MetricsConfig):Function {
224
196
  });
225
197
  }
226
198
  };
227
- }
199
+ }
@@ -1,15 +1,15 @@
1
1
 
2
2
  import { Node } from "node-red";
3
- import { ConfigNode, ConfigNodeConfig, NodeDescriptor, NodeManager } from "../../NodeConstructor"
4
- import { MetricsContainer, MetricsService, MetricsReference, CounterMetric, CounterMetricConfig} from "../service/MetricsService"
3
+ import { ConfigNode, ConfigNodeConfig, NodeManager } from "../../NodeConstructor"
4
+ import { MetricsContainer, MetricsService, MetricsReference, CounterMetric, CounterMetricConfig, DoNothingMetricsContainer} from "../service/MetricsService"
5
5
  import { SourceUtility } from "../../NodeGenerator";
6
6
  import { MetricsConfigNode } from "./MetricsConfigNode";
7
7
  import { MetricsTemplate } from "../template/MetricsTemplate";
8
8
  import { NodeDescription } from "../../tagging/NodeDescriptionDecorator";
9
9
 
10
10
  interface CounterMetricConfigNodeConfig extends ConfigNodeConfig, CounterMetricConfig, MetricsReference {
11
- description:string,
12
- reset:boolean
11
+ description: string,
12
+ reset: boolean
13
13
  }
14
14
 
15
15
  @NodeDescription({
@@ -21,7 +21,7 @@ interface CounterMetricConfigNodeConfig extends ConfigNodeConfig, CounterMetricC
21
21
  templates:[
22
22
  { template:MetricsTemplate, config: {} }
23
23
  ],
24
- dependencies:[ MetricsConfigNode, MetricsService ],
24
+ dependencies:[ MetricsService ],
25
25
  tags: [ "MetricType" ]
26
26
  })
27
27
  export class CounterMetricConfigNode extends ConfigNode<CounterMetricConfigNodeConfig> {
@@ -30,33 +30,33 @@ export class CounterMetricConfigNode extends ConfigNode<CounterMetricConfigNodeC
30
30
 
31
31
  constructor(node: Node, config: CounterMetricConfigNodeConfig){
32
32
  super(node, config);
33
- let _this = this;
34
-
35
- this._metrics = (NodeManager.RED.nodes.getNode(config.metricsReference) as any).node().metrics();
36
-
37
- let counterConfig:CounterMetricConfig = {
38
- metricname:config.name,
39
- metricdescription:config.description,
40
- node:{
41
- id:this.id(),
42
- name:this.name(),
43
- flow:this.flow(),
44
- type:this.type()
33
+
34
+ const refNode = config.metricsEnabled && config.metricsReference ? NodeManager.RED.nodes.getNode(config.metricsReference) : null;
35
+ this._metrics = refNode ? (refNode as any).node().metrics() : new DoNothingMetricsContainer();
36
+
37
+ const counterConfig: CounterMetricConfig = {
38
+ metricname: config.name,
39
+ metricdescription: config.description,
40
+ node: {
41
+ id: this.id(),
42
+ name: this.name(),
43
+ flow: this.flow(),
44
+ type: this.type()
45
45
  }
46
46
  };
47
47
 
48
48
  this._counter = this._metrics.counter(counterConfig);
49
49
 
50
- if(config.reset){
50
+ if (config.reset) {
51
51
  this._counter.reset();
52
52
  }
53
53
  }
54
54
 
55
- public metrics():MetricsContainer {
55
+ public metrics(): MetricsContainer {
56
56
  return this._metrics;
57
57
  }
58
58
 
59
- public counter():CounterMetric {
59
+ public counter(): CounterMetric {
60
60
  return this._counter;
61
61
  }
62
62
  }
@@ -1,15 +1,14 @@
1
1
 
2
2
  import { Node } from "node-red";
3
- import { ConfigNode, ConfigNodeConfig, NodeDescriptor, NodeManager } from "../../NodeConstructor"
4
- import { MetricsContainer, MetricsService, GaugeMetricConfig, GaugeMetric, MetricsReference} from "../service/MetricsService"
3
+ import { ConfigNode, ConfigNodeConfig, NodeManager } from "../../NodeConstructor"
4
+ import { MetricsContainer, MetricsService, GaugeMetricConfig, GaugeMetric, MetricsReference, DoNothingMetricsContainer} from "../service/MetricsService"
5
5
  import { SourceUtility } from "../../NodeGenerator";
6
- import { MetricsConfigNode } from "./MetricsConfigNode";
7
6
  import { MetricsTemplate, MetricsTemplateConfig } from "../template/MetricsTemplate";
8
7
  import { NodeDescription } from "../../tagging/NodeDescriptionDecorator";
9
8
 
10
9
  interface GaugeMetricConfigNodeConfig extends ConfigNodeConfig, GaugeMetricConfig, MetricsTemplateConfig {
11
- description:string,
12
- reset:boolean
10
+ description: string,
11
+ reset: boolean
13
12
  }
14
13
 
15
14
  @NodeDescription({
@@ -19,9 +18,9 @@ interface GaugeMetricConfigNodeConfig extends ConfigNodeConfig, GaugeMetricConfi
19
18
  sourceFile:SourceUtility.getSourcePath("/build/", "/src/") + "GaugeMetricConfigNode.html",
20
19
  package: "@theotherwillembotha/node-red-plugincore",
21
20
  templates: [
22
- { template: MetricsTemplate, config: {}}
21
+ { template: MetricsTemplate, config: {} }
23
22
  ],
24
- dependencies:[ MetricsConfigNode, MetricsService ],
23
+ dependencies:[ MetricsService ],
25
24
  tags: [ "Core", "Metric" ]
26
25
  })
27
26
  export class GaugeMetricConfigNode extends ConfigNode<GaugeMetricConfigNodeConfig> {
@@ -30,33 +29,33 @@ export class GaugeMetricConfigNode extends ConfigNode<GaugeMetricConfigNodeConfi
30
29
 
31
30
  constructor(node: Node, config: GaugeMetricConfigNodeConfig){
32
31
  super(node, config);
33
- let _this = this;
34
-
35
- this._metrics = (NodeManager.RED.nodes.getNode(config.metricsReference) as any).node().metrics();
36
-
37
- let gaugeConfig:GaugeMetricConfig = {
38
- metricname:config.name,
39
- metricdescription:config.description,
40
- node:{
41
- id:this.id(),
42
- flow:this.flow(),
43
- type:this.type(),
44
- name:this.name()
32
+
33
+ const refNode = config.metricsEnabled && config.metricsReference ? NodeManager.RED.nodes.getNode(config.metricsReference) : null;
34
+ this._metrics = refNode ? (refNode as any).node().metrics() : new DoNothingMetricsContainer();
35
+
36
+ const gaugeConfig: GaugeMetricConfig = {
37
+ metricname: config.name,
38
+ metricdescription: config.description,
39
+ node: {
40
+ id: this.id(),
41
+ flow: this.flow(),
42
+ type: this.type(),
43
+ name: this.name()
45
44
  }
46
45
  };
47
-
46
+
48
47
  this._gauge = this._metrics.gauge(gaugeConfig);
49
-
50
- if(config.reset){
51
- _this._gauge.reset();
48
+
49
+ if (config.reset) {
50
+ this._gauge.reset();
52
51
  }
53
52
  }
54
53
 
55
- public metrics():MetricsContainer {
54
+ public metrics(): MetricsContainer {
56
55
  return this._metrics;
57
56
  }
58
57
 
59
- public gauge():GaugeMetric {
58
+ public gauge(): GaugeMetric {
60
59
  return this._gauge;
61
60
  }
62
61
  }
@@ -1,55 +1,36 @@
1
-
2
1
  import { Node } from "node-red";
3
- import { ConfigNode, ConfigNodeConfig, NodeDescriptor } from "../../NodeConstructor"
4
- import { MetricsContainer, MetricsService} from "../service/MetricsService"
5
- import { SourceUtility } from "../../NodeGenerator";
6
- import { WebhookTemplate, WebhookTemplateConfig } from "../../webhook/template/WebhookTemplate";
7
- import { Webhook } from "../../webhook/WebhookDecorator";
8
- import { EndpointMethodType } from "../../webhook/service/WebhookServerService";
9
- import {register as PrometheusRegistry, } from "prom-client";
10
- import express, { Request, Response, Express } from 'express';
11
- import { NodeDescription } from "../../tagging/NodeDescriptionDecorator";
12
-
13
- /*
14
- Note: the MetricsConfigNode does not actually do the deployment of the metrics / repositories.
15
- The metrics / repositories are menanaged by the plugin and triggered when the flows are deployed.
16
-
17
- The reasoning for this is that the Metrics exist outside of the flow, but is configured using the flow.
18
- Basically, if the metrics arent changed, we dont have to redeploy the metrics, which means that
19
- stuff like coutners, gauges and timers are not reset.
20
- */
21
- interface MetricsConfigNodeConfig extends ConfigNodeConfig, WebhookTemplateConfig {
22
- }
23
-
24
- @NodeDescription({
25
- id:"MetricsConfigNode",
26
- name:"Metrics Config Node",
27
- group:"config",
28
- sourceFile:SourceUtility.getSourcePath("/build/", "/src/") + "MetricsConfigNode.html",
29
- package: "@theotherwillembotha/node-red-plugincore",
30
- templates:[
31
- { template:WebhookTemplate, config: {} }
32
- ],
33
- dependencies:[ MetricsService ],
34
- tags: [ ]
35
- })
36
- export class MetricsConfigNode extends ConfigNode<MetricsConfigNodeConfig> {
37
- private _metrics!: MetricsContainer;
38
-
39
- constructor(node: Node, config: MetricsConfigNodeConfig){
2
+ import { ConfigNode, ConfigNodeConfig } from "../../NodeConstructor"
3
+ import { MetricsContainer, MetricsService, MetricsConfig } from "../service/MetricsService"
4
+
5
+ /**
6
+ * Abstract base for all metrics provider config nodes.
7
+ *
8
+ * Concrete implementations (e.g. PrometheusMetricsConfigNode) extend this class,
9
+ * decorate with @NodeDescription + tags: ["MetricsProvider"], and implement
10
+ * createContainer() to return their backend-specific MetricsContainer.
11
+ *
12
+ * This class is intentionally NOT decorated with @NodeDescription - it is never
13
+ * registered as a Node-RED node type directly. Only concrete subclasses are registered.
14
+ */
15
+ export abstract class MetricsConfigNode extends ConfigNode<ConfigNodeConfig> {
16
+
17
+ constructor(node: Node, config: ConfigNodeConfig) {
40
18
  super(node, config);
41
- let _this = this;
42
-
43
- this._metrics = MetricsService.get({metricsEnabled:false, metricsReference:this.id()});
19
+ MetricsService.register(
20
+ config.id,
21
+ { id: config.id },
22
+ () => this.createContainer({ id: config.id })
23
+ );
44
24
  }
45
25
 
46
- public metrics():MetricsContainer {
47
- return this._metrics;
48
- }
26
+ /**
27
+ * Called once on construction to create the backend MetricsContainer.
28
+ * MetricsService preserves the container across redeploys if the config
29
+ * has not changed, so metric state (counters, gauges) is not reset.
30
+ */
31
+ protected abstract createContainer(config: MetricsConfig): MetricsContainer;
49
32
 
50
- @Webhook({name:"MetricsConfigNode", methods:[EndpointMethodType.GET]})
51
- private onWebhookRequest(request:Request, response:Response):void {
52
- response.set('Content-Type', PrometheusRegistry.contentType);
53
- this._metrics.registry().metrics().then((data:any) => response.status(200).send(data))
33
+ public metrics(): MetricsContainer {
34
+ return MetricsService.get({ metricsEnabled: true, metricsReference: this.id() });
54
35
  }
55
36
  }