@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.
- package/README.md +616 -220
- package/build/GenerateNodes.js +3 -6
- package/build/Nodes.html +3 -1504
- package/build/Nodes.js +5 -15
- package/build/Plugins.html +227 -0
- package/build/Plugins.js +18 -8
- package/build/core/NodeConstructor.d.ts +9 -16
- package/build/core/NodeConstructor.d.ts.map +1 -1
- package/build/core/NodeConstructor.js +109 -146
- package/build/core/NodeGenerator.d.ts.map +1 -1
- package/build/core/NodeGenerator.js +79 -28
- package/build/core/NodeManagerRuntime.d.ts +44 -0
- package/build/core/NodeManagerRuntime.d.ts.map +1 -0
- package/build/core/NodeManagerRuntime.js +140 -0
- package/build/core/Utils.d.ts.map +1 -1
- package/build/core/logger/service/LoggerService.d.ts +6 -5
- package/build/core/logger/service/LoggerService.d.ts.map +1 -1
- package/build/core/logger/service/LoggerService.js +51 -20
- package/build/core/logger/template/LoggerTemplate.d.ts.map +1 -1
- package/build/core/metrics/MetricsDecorator.d.ts +1 -2
- package/build/core/metrics/MetricsDecorator.d.ts.map +1 -1
- package/build/core/metrics/MetricsDecorator.js +89 -116
- package/build/core/metrics/node/CounterMetricConfigNode.d.ts.map +1 -1
- package/build/core/metrics/node/CounterMetricConfigNode.js +4 -5
- package/build/core/metrics/node/GaugeMetricConfigNode.d.ts.map +1 -1
- package/build/core/metrics/node/GaugeMetricConfigNode.js +5 -6
- package/build/core/metrics/node/MetricsConfigNode.d.ts +19 -9
- package/build/core/metrics/node/MetricsConfigNode.d.ts.map +1 -1
- package/build/core/metrics/node/MetricsConfigNode.js +14 -45
- package/build/core/metrics/node/TimerMetricConfigNode.d.ts.map +1 -1
- package/build/core/metrics/node/TimerMetricConfigNode.js +11 -17
- package/build/core/metrics/service/MetricsService.d.ts +110 -114
- package/build/core/metrics/service/MetricsService.d.ts.map +1 -1
- package/build/core/metrics/service/MetricsService.js +122 -339
- package/build/core/metrics/template/CounterMetricTemplate.d.ts.map +1 -1
- package/build/core/metrics/template/GaugeMetricTemplate.d.ts.map +1 -1
- package/build/core/metrics/template/MetricsTemplate.d.ts.map +1 -1
- package/build/core/metrics/template/MetricsTemplate.js +1 -2
- package/build/core/metrics/template/TimerMetricTemplate.d.ts.map +1 -1
- package/build/core/other/node/DelegatedConfigReferenceNode.d.ts +1 -1
- package/build/core/other/node/DelegatedConfigReferenceNode.d.ts.map +1 -1
- package/build/core/other/node/DelegatedConfigReferenceNode.js +1 -1
- package/build/core/other/service/InputService.d.ts.map +1 -1
- package/build/core/other/service/SettingsService.d.ts +1 -2
- package/build/core/other/service/SettingsService.d.ts.map +1 -1
- package/build/core/other/service/SettingsService.js +19 -5
- package/build/core/other/template/BasicTemplate.d.ts.map +1 -1
- package/build/core/other/template/SettingsTemplate.d.ts.map +1 -1
- package/build/core/state/node/InternalStateConfigNode.d.ts +16 -0
- package/build/core/state/node/InternalStateConfigNode.d.ts.map +1 -0
- package/build/core/state/node/InternalStateConfigNode.js +89 -0
- package/build/core/state/node/StateConfigNode.d.ts +24 -0
- package/build/core/state/node/StateConfigNode.d.ts.map +1 -0
- package/build/core/state/node/StateConfigNode.js +22 -0
- package/build/core/state/service/StateService.d.ts +34 -0
- package/build/core/state/service/StateService.d.ts.map +1 -0
- package/build/core/state/service/StateService.js +201 -0
- package/build/core/state/template/StateTemplate.d.ts +8 -0
- package/build/core/state/template/StateTemplate.d.ts.map +1 -0
- package/build/core/state/template/StateTemplate.js +11 -0
- package/build/core/tagging/ServiceDescriptionDecorator.d.ts +10 -0
- package/build/core/tagging/ServiceDescriptionDecorator.d.ts.map +1 -0
- package/build/core/tagging/ServiceDescriptionDecorator.js +10 -0
- package/build/core/tagging/service/NodeTypeService.d.ts +1 -2
- package/build/core/tagging/service/NodeTypeService.d.ts.map +1 -1
- package/build/core/tagging/service/NodeTypeService.js +19 -5
- package/build/core/ui/template/ScriptEditorTemplate.d.ts.map +1 -1
- package/build/core/ui/template/UIHelperTemplate.d.ts.map +1 -1
- package/build/core/webhook/node/WebhookServerConfigNode.d.ts.map +1 -1
- package/build/core/webhook/service/ReverseProxyTypeService.d.ts.map +1 -1
- package/build/core/webhook/service/WebhookServerService.d.ts +3 -4
- package/build/core/webhook/service/WebhookServerService.d.ts.map +1 -1
- package/build/core/webhook/service/WebhookServerService.js +48 -18
- package/build/core/webhook/template/WebhookTemplate.d.ts.map +1 -1
- package/build/index.d.ts +5 -2
- package/build/index.d.ts.map +1 -1
- package/build/index.js +6 -2
- package/build/runtime/NodeManagerRuntime.js +140 -0
- package/documentation/CounterMetricConfigNode.png +0 -0
- package/documentation/GaugeMetricConfigNode.png +0 -0
- package/documentation/LoggerTemplate.png +0 -0
- package/documentation/MetricsTemplate.png +0 -0
- package/documentation/StateTemplate.png +0 -0
- package/documentation/TimerMetricConfigNode_histogram.png +0 -0
- package/documentation/TimerMetricConfigNode_summary.png +0 -0
- package/documentation/WebhookServerConfigNode.png +0 -0
- package/documentation/WebhookTemplate.png +0 -0
- package/package.json +4 -10
- package/src/GenerateNodes.ts +7 -11
- package/src/core/NodeConstructor.ts +130 -186
- package/src/core/NodeGenerator.ts +88 -33
- package/src/core/NodeManagerRuntime.ts +179 -0
- package/src/core/logger/service/LoggerService.ts +39 -26
- package/src/core/logger/template/LoggerTemplate.html +11 -6
- package/src/core/metrics/MetricsDecorator.ts +140 -168
- package/src/core/metrics/node/CounterMetricConfigNode.ts +20 -20
- package/src/core/metrics/node/GaugeMetricConfigNode.ts +24 -25
- package/src/core/metrics/node/MetricsConfigNode.ts +29 -48
- package/src/core/metrics/node/TimerMetricConfigNode.ts +50 -59
- package/src/core/metrics/service/MetricsService.ts +214 -489
- package/src/core/metrics/template/CounterMetricTemplate.html +0 -1
- package/src/core/metrics/template/GaugeMetricTemplate.html +1 -1
- package/src/core/metrics/template/MetricsTemplate.html +132 -13
- package/src/core/metrics/template/MetricsTemplate.ts +3 -4
- package/src/core/other/node/DelegatedConfigReferenceNode.ts +1 -1
- package/src/core/other/service/SettingsService.ts +6 -10
- package/src/core/other/template/BasicTemplate.html +1 -1
- package/src/core/state/node/InternalStateConfigNode.html +77 -0
- package/src/core/state/node/InternalStateConfigNode.ts +102 -0
- package/src/core/state/node/StateConfigNode.ts +29 -0
- package/src/core/state/service/StateService.ts +180 -0
- package/src/core/state/template/StateTemplate.html +244 -0
- package/src/core/state/template/StateTemplate.ts +17 -0
- package/src/core/tagging/ServiceDescriptionDecorator.ts +23 -0
- package/src/core/tagging/service/NodeTypeService.ts +6 -11
- package/src/core/ui/template/UIHelperTemplate.html +41 -26
- package/src/core/webhook/service/WebhookServerService.ts +39 -23
- package/src/core/webhook/template/WebhookTemplate.html +28 -35
- package/src/index.ts +7 -2
- package/build/core/logger/node/ConsoleLoggerConfigNode.d.ts +0 -20
- package/build/core/logger/node/ConsoleLoggerConfigNode.d.ts.map +0 -1
- package/build/core/logger/node/ConsoleLoggerConfigNode.js +0 -62
- package/build/core/logger/node/RestLoggerConfigNode.d.ts +0 -40
- package/build/core/logger/node/RestLoggerConfigNode.d.ts.map +0 -1
- package/build/core/logger/node/RestLoggerConfigNode.js +0 -128
- package/documentation/ConsoleLoggerConfigNode.png +0 -0
- package/documentation/MetricsConfigNode.png +0 -0
- package/documentation/RestLoggerConfigNode.png +0 -0
- package/documentation/TimerMetricConfigNode.png +0 -0
- package/documentation/WebhookNode.png +0 -0
- package/src/core/logger/node/ConsoleLoggerConfigNode.html +0 -90
- package/src/core/logger/node/ConsoleLoggerConfigNode.ts +0 -71
- package/src/core/logger/node/RestLoggerConfigNode.html +0 -183
- package/src/core/logger/node/RestLoggerConfigNode.ts +0 -170
|
@@ -1,221 +1,193 @@
|
|
|
1
1
|
|
|
2
2
|
import { BaseNode, NodeManager } from "../NodeConstructor";
|
|
3
|
-
import {
|
|
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
|
|
9
|
-
Gauge
|
|
24
|
+
Timer = "Timer",
|
|
25
|
+
Gauge = "Gauge",
|
|
10
26
|
}
|
|
11
27
|
|
|
12
28
|
export enum MetricCollectorType {
|
|
13
29
|
histogram = "histogram",
|
|
14
|
-
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
|
|
29
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
86
|
-
|
|
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
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
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
|
-
|
|
142
|
-
}
|
|
143
|
-
else{
|
|
171
|
+
|
|
172
|
+
} else {
|
|
144
173
|
let property = propertyKey as any;
|
|
145
|
-
property.addInitializer(function(this:BaseNode<MetricsTemplateConfig>){
|
|
146
|
-
|
|
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
|
-
|
|
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,
|
|
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:[
|
|
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
|
-
|
|
34
|
-
|
|
35
|
-
this._metrics = (
|
|
36
|
-
|
|
37
|
-
|
|
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,
|
|
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:[
|
|
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
|
-
|
|
34
|
-
|
|
35
|
-
this._metrics = (
|
|
36
|
-
|
|
37
|
-
|
|
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
|
-
|
|
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
|
|
4
|
-
import { MetricsContainer, MetricsService} from "../service/MetricsService"
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
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
|
-
|
|
42
|
-
|
|
43
|
-
|
|
19
|
+
MetricsService.register(
|
|
20
|
+
config.id,
|
|
21
|
+
{ id: config.id },
|
|
22
|
+
() => this.createContainer({ id: config.id })
|
|
23
|
+
);
|
|
44
24
|
}
|
|
45
25
|
|
|
46
|
-
|
|
47
|
-
|
|
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
|
-
|
|
51
|
-
|
|
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
|
}
|