@theotherwillembotha/node-red-plugincore 0.0.50
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/LICENSE +15 -0
- package/README.md +190 -0
- package/build/GenerateNodes.d.ts +2 -0
- package/build/GenerateNodes.d.ts.map +1 -0
- package/build/GenerateNodes.js +36 -0
- package/build/Nodes.html +1729 -0
- package/build/Nodes.js +32 -0
- package/build/Plugins.js +74 -0
- package/build/core/NodeConstructor.d.ts +188 -0
- package/build/core/NodeConstructor.d.ts.map +1 -0
- package/build/core/NodeConstructor.js +679 -0
- package/build/core/NodeGenerator.d.ts +37 -0
- package/build/core/NodeGenerator.d.ts.map +1 -0
- package/build/core/NodeGenerator.js +300 -0
- package/build/core/Utils.d.ts +7 -0
- package/build/core/Utils.d.ts.map +1 -0
- package/build/core/Utils.js +19 -0
- package/build/core/logger/LoggerDecorator.d.ts +2 -0
- package/build/core/logger/LoggerDecorator.d.ts.map +1 -0
- package/build/core/logger/LoggerDecorator.js +93 -0
- package/build/core/logger/node/ConsoleLoggerConfigNode.d.ts +16 -0
- package/build/core/logger/node/ConsoleLoggerConfigNode.d.ts.map +1 -0
- package/build/core/logger/node/ConsoleLoggerConfigNode.html +131 -0
- package/build/core/logger/node/ConsoleLoggerConfigNode.js +47 -0
- package/build/core/logger/node/LoggerConfigNode.d.ts +30 -0
- package/build/core/logger/node/LoggerConfigNode.d.ts.map +1 -0
- package/build/core/logger/node/LoggerConfigNode.html +307 -0
- package/build/core/logger/node/LoggerConfigNode.js +60 -0
- package/build/core/logger/node/LokiLoggerConfigNode.d.ts +20 -0
- package/build/core/logger/node/LokiLoggerConfigNode.d.ts.map +1 -0
- package/build/core/logger/node/LokiLoggerConfigNode.html +153 -0
- package/build/core/logger/node/LokiLoggerConfigNode.js +52 -0
- package/build/core/logger/node/RestLoggerConfigNode.d.ts +24 -0
- package/build/core/logger/node/RestLoggerConfigNode.d.ts.map +1 -0
- package/build/core/logger/node/RestLoggerConfigNode.html +209 -0
- package/build/core/logger/node/RestLoggerConfigNode.js +57 -0
- package/build/core/logger/service/LoggerService.d.ts +88 -0
- package/build/core/logger/service/LoggerService.d.ts.map +1 -0
- package/build/core/logger/service/LoggerService.js +204 -0
- package/build/core/logger/service/LoggerServiceTypes.d.ts +24 -0
- package/build/core/logger/service/LoggerServiceTypes.d.ts.map +1 -0
- package/build/core/logger/service/LoggerServiceTypes.js +30 -0
- package/build/core/logger/template/LoggerTemplate.d.ts +11 -0
- package/build/core/logger/template/LoggerTemplate.d.ts.map +1 -0
- package/build/core/logger/template/LoggerTemplate.html +328 -0
- package/build/core/logger/template/LoggerTemplate.js +12 -0
- package/build/core/metrics/MetricsDecorator.d.ts +40 -0
- package/build/core/metrics/MetricsDecorator.d.ts.map +1 -0
- package/build/core/metrics/MetricsDecorator.js +166 -0
- package/build/core/metrics/node/CounterMetricConfigNode.d.ts +16 -0
- package/build/core/metrics/node/CounterMetricConfigNode.d.ts.map +1 -0
- package/build/core/metrics/node/CounterMetricConfigNode.html +48 -0
- package/build/core/metrics/node/CounterMetricConfigNode.js +61 -0
- package/build/core/metrics/node/GaugeMetricConfigNode.d.ts +17 -0
- package/build/core/metrics/node/GaugeMetricConfigNode.d.ts.map +1 -0
- package/build/core/metrics/node/GaugeMetricConfigNode.html +48 -0
- package/build/core/metrics/node/GaugeMetricConfigNode.js +61 -0
- package/build/core/metrics/node/MetricsConfigNode.d.ts +14 -0
- package/build/core/metrics/node/MetricsConfigNode.d.ts.map +1 -0
- package/build/core/metrics/node/MetricsConfigNode.html +21 -0
- package/build/core/metrics/node/MetricsConfigNode.js +56 -0
- package/build/core/metrics/node/TimerMetricConfigNode.d.ts +28 -0
- package/build/core/metrics/node/TimerMetricConfigNode.d.ts.map +1 -0
- package/build/core/metrics/node/TimerMetricConfigNode.html +190 -0
- package/build/core/metrics/node/TimerMetricConfigNode.js +101 -0
- package/build/core/metrics/service/MetricsService.d.ts +187 -0
- package/build/core/metrics/service/MetricsService.d.ts.map +1 -0
- package/build/core/metrics/service/MetricsService.js +385 -0
- package/build/core/metrics/template/CounterMetricTemplate.d.ts +5 -0
- package/build/core/metrics/template/CounterMetricTemplate.d.ts.map +1 -0
- package/build/core/metrics/template/CounterMetricTemplate.html +40 -0
- package/build/core/metrics/template/CounterMetricTemplate.js +12 -0
- package/build/core/metrics/template/GaugeMetricTemplate.d.ts +5 -0
- package/build/core/metrics/template/GaugeMetricTemplate.d.ts.map +1 -0
- package/build/core/metrics/template/GaugeMetricTemplate.html +39 -0
- package/build/core/metrics/template/GaugeMetricTemplate.js +12 -0
- package/build/core/metrics/template/MetricsTemplate.d.ts +8 -0
- package/build/core/metrics/template/MetricsTemplate.d.ts.map +1 -0
- package/build/core/metrics/template/MetricsTemplate.html +54 -0
- package/build/core/metrics/template/MetricsTemplate.js +12 -0
- package/build/core/metrics/template/TimerMetricTemplate.d.ts +5 -0
- package/build/core/metrics/template/TimerMetricTemplate.d.ts.map +1 -0
- package/build/core/metrics/template/TimerMetricTemplate.html +39 -0
- package/build/core/metrics/template/TimerMetricTemplate.js +12 -0
- package/build/core/other/InputDecorator.d.ts +3 -0
- package/build/core/other/InputDecorator.d.ts.map +1 -0
- package/build/core/other/InputDecorator.js +43 -0
- package/build/core/other/service/InputService.d.ts +16 -0
- package/build/core/other/service/InputService.d.ts.map +1 -0
- package/build/core/other/service/InputService.js +31 -0
- package/build/core/other/service/SettingsService.d.ts +25 -0
- package/build/core/other/service/SettingsService.d.ts.map +1 -0
- package/build/core/other/service/SettingsService.js +74 -0
- package/build/core/other/template/BasicTemplate.d.ts +5 -0
- package/build/core/other/template/BasicTemplate.d.ts.map +1 -0
- package/build/core/other/template/BasicTemplate.html +76 -0
- package/build/core/other/template/BasicTemplate.js +11 -0
- package/build/core/other/template/SettingsTemplate.d.ts +5 -0
- package/build/core/other/template/SettingsTemplate.d.ts.map +1 -0
- package/build/core/other/template/SettingsTemplate.html +128 -0
- package/build/core/other/template/SettingsTemplate.js +11 -0
- package/build/core/tagging/NodeDescriptionDecorator.d.ts +17 -0
- package/build/core/tagging/NodeDescriptionDecorator.d.ts.map +1 -0
- package/build/core/tagging/NodeDescriptionDecorator.js +25 -0
- package/build/core/tagging/service/NodeTypeService.d.ts +15 -0
- package/build/core/tagging/service/NodeTypeService.d.ts.map +1 -0
- package/build/core/tagging/service/NodeTypeService.js +47 -0
- package/build/core/webhook/WebhookDecorator.d.ts +3 -0
- package/build/core/webhook/WebhookDecorator.d.ts.map +1 -0
- package/build/core/webhook/WebhookDecorator.js +45 -0
- package/build/core/webhook/node/WebhookServerConfigNode.d.ts +16 -0
- package/build/core/webhook/node/WebhookServerConfigNode.d.ts.map +1 -0
- package/build/core/webhook/node/WebhookServerConfigNode.html +61 -0
- package/build/core/webhook/node/WebhookServerConfigNode.js +40 -0
- package/build/core/webhook/service/ReverseProxyTypeService.d.ts +29 -0
- package/build/core/webhook/service/ReverseProxyTypeService.d.ts.map +1 -0
- package/build/core/webhook/service/ReverseProxyTypeService.js +24 -0
- package/build/core/webhook/service/WebhookServerService.d.ts +52 -0
- package/build/core/webhook/service/WebhookServerService.d.ts.map +1 -0
- package/build/core/webhook/service/WebhookServerService.js +146 -0
- package/build/core/webhook/template/WebhookTemplate.d.ts +22 -0
- package/build/core/webhook/template/WebhookTemplate.d.ts.map +1 -0
- package/build/core/webhook/template/WebhookTemplate.html +434 -0
- package/build/core/webhook/template/WebhookTemplate.js +12 -0
- package/build/index.d.ts +33 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +55 -0
- package/package.json +67 -0
- package/src/GenerateNodes.ts +42 -0
- package/src/core/NodeConstructor.ts +889 -0
- package/src/core/NodeGenerator.ts +331 -0
- package/src/core/Utils.ts +19 -0
- package/src/core/logger/LoggerDecorator.ts +105 -0
- package/src/core/logger/node/ConsoleLoggerConfigNode.html +131 -0
- package/src/core/logger/node/ConsoleLoggerConfigNode.ts +46 -0
- package/src/core/logger/node/LoggerConfigNode.html +307 -0
- package/src/core/logger/node/LoggerConfigNode.ts +95 -0
- package/src/core/logger/node/LokiLoggerConfigNode.html +153 -0
- package/src/core/logger/node/LokiLoggerConfigNode.ts +58 -0
- package/src/core/logger/node/RestLoggerConfigNode.html +209 -0
- package/src/core/logger/node/RestLoggerConfigNode.ts +67 -0
- package/src/core/logger/service/LoggerService.ts +317 -0
- package/src/core/logger/service/LoggerServiceTypes.ts +26 -0
- package/src/core/logger/template/LoggerTemplate.html +328 -0
- package/src/core/logger/template/LoggerTemplate.ts +23 -0
- package/src/core/metrics/MetricsDecorator.ts +227 -0
- package/src/core/metrics/node/CounterMetricConfigNode.html +48 -0
- package/src/core/metrics/node/CounterMetricConfigNode.ts +62 -0
- package/src/core/metrics/node/GaugeMetricConfigNode.html +48 -0
- package/src/core/metrics/node/GaugeMetricConfigNode.ts +62 -0
- package/src/core/metrics/node/MetricsConfigNode.html +21 -0
- package/src/core/metrics/node/MetricsConfigNode.ts +55 -0
- package/src/core/metrics/node/TimerMetricConfigNode.html +190 -0
- package/src/core/metrics/node/TimerMetricConfigNode.ts +118 -0
- package/src/core/metrics/service/MetricsService.ts +560 -0
- package/src/core/metrics/template/CounterMetricTemplate.html +40 -0
- package/src/core/metrics/template/CounterMetricTemplate.ts +15 -0
- package/src/core/metrics/template/GaugeMetricTemplate.html +39 -0
- package/src/core/metrics/template/GaugeMetricTemplate.ts +15 -0
- package/src/core/metrics/template/MetricsTemplate.html +54 -0
- package/src/core/metrics/template/MetricsTemplate.ts +18 -0
- package/src/core/metrics/template/TimerMetricTemplate.html +39 -0
- package/src/core/metrics/template/TimerMetricTemplate.ts +14 -0
- package/src/core/other/InputDecorator.ts +57 -0
- package/src/core/other/service/InputService.ts +36 -0
- package/src/core/other/service/SettingsService.ts +103 -0
- package/src/core/other/template/BasicTemplate.html +76 -0
- package/src/core/other/template/BasicTemplate.ts +15 -0
- package/src/core/other/template/SettingsTemplate.html +128 -0
- package/src/core/other/template/SettingsTemplate.ts +17 -0
- package/src/core/tagging/NodeDescriptionDecorator.ts +39 -0
- package/src/core/tagging/service/NodeTypeService.ts +67 -0
- package/src/core/webhook/WebhookDecorator.ts +70 -0
- package/src/core/webhook/node/WebhookServerConfigNode.html +61 -0
- package/src/core/webhook/node/WebhookServerConfigNode.ts +38 -0
- package/src/core/webhook/service/ReverseProxyTypeService.ts +46 -0
- package/src/core/webhook/service/WebhookServerService.ts +211 -0
- package/src/core/webhook/template/WebhookTemplate.html +434 -0
- package/src/core/webhook/template/WebhookTemplate.ts +36 -0
- package/src/index.ts +47 -0
|
@@ -0,0 +1,328 @@
|
|
|
1
|
+
<div template-section="onIncludeOnce">
|
|
2
|
+
<style>
|
|
3
|
+
.editorgroupborder {
|
|
4
|
+
border-width:1px;
|
|
5
|
+
border-style:solid;
|
|
6
|
+
border-color:lightgray;
|
|
7
|
+
padding: 3px;
|
|
8
|
+
margin-top: 2px;
|
|
9
|
+
margin-bottom: 2px;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.editorsectionheading {
|
|
13
|
+
font-weight: 600;
|
|
14
|
+
margin-bottom:1px !important;
|
|
15
|
+
margin-top:6px !important;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.nomargin {
|
|
19
|
+
margin-bottom:1px !important;
|
|
20
|
+
margin-top:1px !important;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.slidecontainer {
|
|
24
|
+
width: 100%;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.slider {
|
|
28
|
+
-webkit-appearance: none;
|
|
29
|
+
appearance: none;
|
|
30
|
+
width: 100%;
|
|
31
|
+
height: 25px;
|
|
32
|
+
background: #d3d3d3;
|
|
33
|
+
outline: none;
|
|
34
|
+
opacity: 0.7;
|
|
35
|
+
-webkit-transition: .2s;
|
|
36
|
+
transition: opacity .2s;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.slider:hover {
|
|
40
|
+
opacity: 1;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.slider::-webkit-slider-thumb {
|
|
44
|
+
-webkit-appearance: none;
|
|
45
|
+
appearance: none;
|
|
46
|
+
width: 25px;
|
|
47
|
+
height: 25px;
|
|
48
|
+
background: #04AA6D;
|
|
49
|
+
cursor: pointer;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.slider::-moz-range-thumb {
|
|
53
|
+
width: 25px;
|
|
54
|
+
height: 25px;
|
|
55
|
+
background: #04AA6D;
|
|
56
|
+
cursor: pointer;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.towb_editorlabel {
|
|
60
|
+
width: 120px !important;
|
|
61
|
+
}
|
|
62
|
+
.towb_editorfield {
|
|
63
|
+
width: 70% !important;
|
|
64
|
+
}
|
|
65
|
+
.towb_editorfield_short {
|
|
66
|
+
width: 30% !important;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
</style>
|
|
70
|
+
|
|
71
|
+
<script type="text/javascript">
|
|
72
|
+
|
|
73
|
+
// CSS
|
|
74
|
+
dropdownStyles = `
|
|
75
|
+
.loggertype-dropdown {
|
|
76
|
+
position: absolute;
|
|
77
|
+
background: white;
|
|
78
|
+
border: 1px solid #ccc;
|
|
79
|
+
border-radius: 4px;
|
|
80
|
+
box-shadow: 0 2px 8px rgba(0,0,0,0.15);
|
|
81
|
+
max-height: 150px;
|
|
82
|
+
overflow-y: auto;
|
|
83
|
+
z-index: 1000;
|
|
84
|
+
min-width: 150px;
|
|
85
|
+
}
|
|
86
|
+
.loggertype-dropdown .dropdown-item {
|
|
87
|
+
padding: 6px 12px;
|
|
88
|
+
cursor: pointer;
|
|
89
|
+
}
|
|
90
|
+
.loggertype-dropdown .dropdown-item:hover {
|
|
91
|
+
background: #f0f0f0;
|
|
92
|
+
}
|
|
93
|
+
`;
|
|
94
|
+
$('<style>').text(dropdownStyles).appendTo('head');
|
|
95
|
+
|
|
96
|
+
</script>
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
</div>
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
<script type="text/javascript" template-section="onCompose">
|
|
103
|
+
node
|
|
104
|
+
.addDefault("logEnabled", { value:false, required:true})
|
|
105
|
+
.addDefault("logger", { required:false})
|
|
106
|
+
.addDefault("logTemplateOverrideEnabled", {value:false})
|
|
107
|
+
.addDefault("logTemplateOverride", {value:"message:{{msg}}"})
|
|
108
|
+
</script>
|
|
109
|
+
|
|
110
|
+
<script type="text/javascript" template-section="onIncludeEditPrepare">
|
|
111
|
+
let node = this;
|
|
112
|
+
|
|
113
|
+
// controls.
|
|
114
|
+
let logEnabled = $("#{{defaults.logEnabled}}");
|
|
115
|
+
let logTemplateEnabled = $("#{{defaults.logTemplateOverrideEnabled}}");
|
|
116
|
+
let logTemplateEnabledSection = $("#section_logTemplateOverrideEnabled");
|
|
117
|
+
let logEnabledSection = $("#section_logEnabled");
|
|
118
|
+
|
|
119
|
+
// functions.
|
|
120
|
+
let getLoggerTypes = async function(){
|
|
121
|
+
let types = [];
|
|
122
|
+
await $.ajax({
|
|
123
|
+
url: "nodetypeservice/find?tag=LoggerType",
|
|
124
|
+
type: "GET",
|
|
125
|
+
contentType: "application/json; charset=utf-8",
|
|
126
|
+
data:JSON.stringify({id:node.id}),
|
|
127
|
+
success: (response) => {
|
|
128
|
+
types = response;
|
|
129
|
+
},
|
|
130
|
+
error: (jqXHR, textStatus, errorThrown) => {
|
|
131
|
+
console.log(jqXHR, textStatus, errorThrown);
|
|
132
|
+
},
|
|
133
|
+
});
|
|
134
|
+
return types;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
let getLoggers = async () => {
|
|
138
|
+
let loggers = [];
|
|
139
|
+
|
|
140
|
+
// get the list of types again.
|
|
141
|
+
let loggerTypes = (await getLoggerTypes()).map(type => type.id);
|
|
142
|
+
|
|
143
|
+
// add all of the known loggers.
|
|
144
|
+
RED.nodes.eachConfig(cfg => {
|
|
145
|
+
if(loggerTypes.includes(cfg.type)){
|
|
146
|
+
loggers.push({id:cfg.id, name:cfg.label(), type:cfg.type});
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
return loggers;
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
let updateLoggerSelectorList = async () => {
|
|
154
|
+
loggerSelector.empty();
|
|
155
|
+
(await getLoggers()).forEach(logger => {
|
|
156
|
+
$('<option value="' + logger.id + '">' + logger.name + '</option>').appendTo(loggerSelector);
|
|
157
|
+
});
|
|
158
|
+
$('<option value="_ADD_">none</option>').appendTo(loggerSelector);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
logEnabled.on('change', function() {
|
|
162
|
+
if(logEnabled.prop("checked")){
|
|
163
|
+
logEnabledSection.show();
|
|
164
|
+
node._def.defaults.logger.required = true;
|
|
165
|
+
}
|
|
166
|
+
else{
|
|
167
|
+
logEnabledSection.hide()
|
|
168
|
+
node._def.defaults.logger.required = false;
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
logTemplateEnabled.on('change', function() {
|
|
173
|
+
if(logTemplateEnabled.prop("checked")){
|
|
174
|
+
logTemplateEnabledSection.show();
|
|
175
|
+
node._def.defaults.logTemplateOverride.required = true;
|
|
176
|
+
}
|
|
177
|
+
else{
|
|
178
|
+
logTemplateEnabledSection.hide()
|
|
179
|
+
node._def.defaults.logTemplateOverride.required = false;
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
node.logTemplateOverrideEditor = RED.editor.createEditor({
|
|
184
|
+
id: 'node-input-logTemplateOverrideEditor',
|
|
185
|
+
mode: 'ace/mode/handlebars',
|
|
186
|
+
value: node.logTemplateOverride
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
let loggerSelector = $("#{{defaults.logger}}");
|
|
190
|
+
let loggerEditButton = $("#logger-edit-btn");
|
|
191
|
+
let loggerAddButton = $("#logger-add-btn");
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
loggerEditButton.on('click', async function(event){
|
|
195
|
+
event.stopPropagation();
|
|
196
|
+
if(loggerEditButton.hasClass("disabled")){
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// figure out what type of logger this is.
|
|
201
|
+
let selectedLogger = (await getLoggers()).find(logger => logger.id === loggerSelector.val());
|
|
202
|
+
RED.editor.editConfig("#{{defaults.logger}}", selectedLogger.type, selectedLogger.id);
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
loggerAddButton.on('click', function(event) {
|
|
206
|
+
event.stopPropagation();
|
|
207
|
+
let $btn = $(event.target);
|
|
208
|
+
|
|
209
|
+
// Remove any existing dropdown
|
|
210
|
+
$('.loggertype-dropdown').remove();
|
|
211
|
+
|
|
212
|
+
getLoggerTypes().then(loggerTypes => {
|
|
213
|
+
let $dropdown = $('<div class="loggertype-dropdown red-ui-editor"></div>');
|
|
214
|
+
|
|
215
|
+
loggerTypes.forEach(loggerType => {
|
|
216
|
+
$('<div class="dropdown-item"></div>')
|
|
217
|
+
.text(loggerType.name)
|
|
218
|
+
.data('value', loggerType.id)
|
|
219
|
+
.css({
|
|
220
|
+
padding: '4px 8px',
|
|
221
|
+
cursor: 'pointer'
|
|
222
|
+
})
|
|
223
|
+
.appendTo($dropdown);
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
// Position it near the button
|
|
227
|
+
$dropdown.css({
|
|
228
|
+
top: $btn.offset().top + $btn.height(),
|
|
229
|
+
left: $btn.offset().left
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
$('body').append($dropdown);
|
|
233
|
+
|
|
234
|
+
$(document).on('mousedown.dropdown', function(e) {
|
|
235
|
+
if (!$(e.target).closest('.loggertype-dropdown').length) {
|
|
236
|
+
$dropdown.remove();
|
|
237
|
+
$(document).off('mousedown.dropdown'); // Clean up the listener
|
|
238
|
+
}
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
// Handle item selection
|
|
242
|
+
$dropdown.on('click', '.dropdown-item', function(e) {
|
|
243
|
+
e.stopPropagation();
|
|
244
|
+
const selectedValue = $(this).data('value');
|
|
245
|
+
const selectedText = $(this).text();
|
|
246
|
+
|
|
247
|
+
// Do whatever you need with the selection
|
|
248
|
+
console.log('Selected:', selectedValue, selectedText);
|
|
249
|
+
$dropdown.remove();
|
|
250
|
+
RED.editor.editConfig("#{{defaults.logger}}", selectedValue, "_ADD_");
|
|
251
|
+
});
|
|
252
|
+
})
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
loggerSelector.on("focus", updateLoggerSelectorList);
|
|
256
|
+
loggerSelector.on('change', function(event) {
|
|
257
|
+
if("_ADD_" === loggerSelector.val()){
|
|
258
|
+
loggerEditButton.addClass("disabled")
|
|
259
|
+
}
|
|
260
|
+
else{
|
|
261
|
+
loggerEditButton.removeClass("disabled")
|
|
262
|
+
}
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
// lastly, make sure that we set the correct value on the logger selector.
|
|
266
|
+
updateLoggerSelectorList().then(() => {
|
|
267
|
+
loggerSelector.val(node.logger);
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
</script>
|
|
271
|
+
|
|
272
|
+
<script type="text/javascript" template-section="onIncludeEditSave">
|
|
273
|
+
node = this;
|
|
274
|
+
node.logTemplateOverride = node.logTemplateOverrideEditor.getValue();
|
|
275
|
+
node.logTemplateOverrideEditor.destroy();
|
|
276
|
+
delete node.logTemplateOverrideEditor;
|
|
277
|
+
</script>
|
|
278
|
+
|
|
279
|
+
<script type="text/html" template-section="onIncludeEditForm">
|
|
280
|
+
<div id="section_loggerconfig" >
|
|
281
|
+
<div class="form-row editorsectionheading">
|
|
282
|
+
<i class="w-16 fa fa-eye"></i> <span>Logging</span>
|
|
283
|
+
</div>
|
|
284
|
+
<div class="editorgroupborder">
|
|
285
|
+
<div class="form-row nomargin logEnableCheck">
|
|
286
|
+
<input type="checkbox" id="{{defaults.logEnabled}}" placeholder="logEnabled" value="false" style="margin:8px 0 10px 102px; width:20px;">
|
|
287
|
+
<label style="width:auto" for="{{defaults.logEnabled}}"><span>Enable Logging</span></label>
|
|
288
|
+
</div>
|
|
289
|
+
|
|
290
|
+
<div id="section_logEnabled">
|
|
291
|
+
<div class="form-row nomargin">
|
|
292
|
+
<label for="{{defaults.logger}}">Logger</label>
|
|
293
|
+
<div style="width: 70%; display: inline-flex;">
|
|
294
|
+
<select id="{{defaults.logger}}" style="flex-grow: 1;" class="">
|
|
295
|
+
<option value="_ADD_">none</option>
|
|
296
|
+
</select>
|
|
297
|
+
<a id="logger-edit-btn" class="red-ui-button disabled" style="margin-left: 10px;">
|
|
298
|
+
<i class="fa fa-pencil"></i>
|
|
299
|
+
</a>
|
|
300
|
+
<a id="logger-add-btn" class="red-ui-button" style="margin-left: 10px;">
|
|
301
|
+
<i class="fa fa-plus"></i>
|
|
302
|
+
</a>
|
|
303
|
+
</div>
|
|
304
|
+
</div>
|
|
305
|
+
|
|
306
|
+
<div class="form-row nomargin">
|
|
307
|
+
<input type="checkbox" id="{{defaults.logTemplateOverrideEnabled}}" placeholder="" value="false" style="margin:8px 0 10px 102px; width:20px;">
|
|
308
|
+
<label style="width:auto" for="{{defaults.logTemplateOverrideEnabled}}"><span>Override Template</span></label>
|
|
309
|
+
</div>
|
|
310
|
+
|
|
311
|
+
<div id="section_logTemplateOverrideEnabled">
|
|
312
|
+
<div class="form-row">
|
|
313
|
+
<label for="node-input-logTemplateOverrideEditor"><i class="fa fa-tag"></i> Template</label>
|
|
314
|
+
<div style="height: 250px; min-height:150px;" class="node-text-editor" id="node-input-logTemplateOverrideEditor"></div>
|
|
315
|
+
</div>
|
|
316
|
+
</div>
|
|
317
|
+
</div>
|
|
318
|
+
</div>
|
|
319
|
+
</div>
|
|
320
|
+
</script>
|
|
321
|
+
|
|
322
|
+
<script type="text/markdown" template-section="onIncludeDocumentation">
|
|
323
|
+
### Logging
|
|
324
|
+
: *enable logging* (boolean) : if checked, then the node will produce logging output to the specified logger.
|
|
325
|
+
: *logger* (logconfig) : the endppoint that the node will log events to.
|
|
326
|
+
: *override template* (logconfig) : if checked, a custom logging template can be provided for the log message.
|
|
327
|
+
: *logger template* (mustache) : a template in mustache format to generate a message for logging purposes (see LoggerConfig node for more information)
|
|
328
|
+
</script>
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { SourceUtility } from "../../NodeGenerator";
|
|
2
|
+
import { BaseNodeConfig, Template, TemplateDescriptor } from "../../NodeConstructor"
|
|
3
|
+
import { LoggerConfigNode } from "../node/LoggerConfigNode";
|
|
4
|
+
|
|
5
|
+
export interface LoggerTemplateConfig extends BaseNodeConfig{
|
|
6
|
+
logEnabled:boolean,
|
|
7
|
+
logger:string,
|
|
8
|
+
logTemplateOverrideEnabled:boolean,
|
|
9
|
+
logTemplateOverride:string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export class LoggerTemplate extends Template {
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
static getTemplateDescriptor(): TemplateDescriptor {
|
|
16
|
+
return new TemplateDescriptor(
|
|
17
|
+
"logger",
|
|
18
|
+
LoggerTemplate,
|
|
19
|
+
SourceUtility.getSourcePath("/build/", "/src/") + "LoggerTemplate.html",
|
|
20
|
+
[LoggerConfigNode],
|
|
21
|
+
)
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
|
|
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";
|
|
4
|
+
import { MetricsTemplateConfig } from "./template/MetricsTemplate";
|
|
5
|
+
|
|
6
|
+
export enum MetricType {
|
|
7
|
+
Counter = "Counter",
|
|
8
|
+
Timer = "Timer",
|
|
9
|
+
Gauge = "Gauge",
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export enum MetricCollectorType {
|
|
13
|
+
histogram = "histogram",
|
|
14
|
+
summary = "summary",
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
type BaseMetricDecoratorConfig = {
|
|
19
|
+
name:string;
|
|
20
|
+
type:MetricType;
|
|
21
|
+
description:string;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
type CounterMetricDecoratorConfig = BaseMetricDecoratorConfig & {
|
|
25
|
+
type:MetricType.Counter
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
type GaugeMetricDecoratorConfig = BaseMetricDecoratorConfig & {
|
|
29
|
+
type:MetricType.Gauge
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
type TimerMetricDecoratorConfig = BaseMetricDecoratorConfig & {
|
|
33
|
+
type:MetricType.Timer,
|
|
34
|
+
collector:MetricCollectorType,
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
type SummaryTimerMetricDecoratorConfig = TimerMetricDecoratorConfig & {
|
|
38
|
+
collector:MetricCollectorType.summary,
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
type HistogramTimerMetricDecoratorConfig = TimerMetricDecoratorConfig & {
|
|
42
|
+
collector:MetricCollectorType.histogram,
|
|
43
|
+
buckettype:BucketType,
|
|
44
|
+
//bucketconfig:DefaultBucketConfig|ManualBucketConfig|LinearBucketConfig|ExponentialBucketConfig,
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
type DefaultHistogramTimerMetricDecoratorConfig = HistogramTimerMetricDecoratorConfig & {
|
|
48
|
+
buckettype:BucketType.default,
|
|
49
|
+
bucketconfig?:DefaultBucketConfig
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
type MetricsConfig =
|
|
53
|
+
CounterMetricDecoratorConfig |
|
|
54
|
+
GaugeMetricDecoratorConfig |
|
|
55
|
+
SummaryTimerMetricDecoratorConfig |
|
|
56
|
+
DefaultHistogramTimerMetricDecoratorConfig
|
|
57
|
+
|
|
58
|
+
export function Metrics(metricsConfig: MetricsConfig):Function {
|
|
59
|
+
return function (target: any, propertyKey: string | symbol) {
|
|
60
|
+
|
|
61
|
+
// if the type is a string, then its probably defined in the local (core) module.
|
|
62
|
+
if(typeof propertyKey === "string"){
|
|
63
|
+
const valueSymbol = Symbol(`_${String(propertyKey)}_value`);
|
|
64
|
+
|
|
65
|
+
Object.defineProperty(target, propertyKey, {
|
|
66
|
+
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
|
+
}
|
|
84
|
+
|
|
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
|
+
}
|
|
95
|
+
|
|
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.guage(gaugeConfig);
|
|
104
|
+
return this[valueSymbol];
|
|
105
|
+
}
|
|
106
|
+
|
|
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
|
+
return this[valueSymbol];
|
|
137
|
+
},
|
|
138
|
+
enumerable: true,
|
|
139
|
+
configurable: false
|
|
140
|
+
});
|
|
141
|
+
return
|
|
142
|
+
}
|
|
143
|
+
else{
|
|
144
|
+
let property = propertyKey as any;
|
|
145
|
+
property.addInitializer(function(this:BaseNode<MetricsTemplateConfig>){
|
|
146
|
+
let node = this as BaseNode<MetricsTemplateConfig>
|
|
147
|
+
const valueSymbol = Symbol(`_${String(property.name)}_value`);
|
|
148
|
+
|
|
149
|
+
Object.defineProperty(node, property.name, {
|
|
150
|
+
get: function() {
|
|
151
|
+
if(this[valueSymbol]){
|
|
152
|
+
return this[valueSymbol];
|
|
153
|
+
}
|
|
154
|
+
|
|
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.guage(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
|
+
return this[valueSymbol];
|
|
220
|
+
},
|
|
221
|
+
enumerable: true,
|
|
222
|
+
configurable: false
|
|
223
|
+
});
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
};
|
|
227
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
<script type="text/javascript" template-section="onCompose">
|
|
2
|
+
node
|
|
3
|
+
.addDefault("name", { value:"Counter Example", required:true})
|
|
4
|
+
.addDefault("description", {value:"an example couter", required:false})
|
|
5
|
+
.addDefault("reset", {value:false, required:false})
|
|
6
|
+
.setPaletteLabel("Counter Metric Config")
|
|
7
|
+
.setLabel(function() {return this.name })
|
|
8
|
+
</script>
|
|
9
|
+
|
|
10
|
+
<script type="text/javascript" template-section="onIncludeEditPrepare">
|
|
11
|
+
// enable the metrics by default and hide the Enable metrics button.
|
|
12
|
+
let metricsEnabled = $("#node-config-input-metricsEnabled");
|
|
13
|
+
metricsEnabled.prop('checked', true);
|
|
14
|
+
metricsEnabled.trigger("change");
|
|
15
|
+
$("#section_metricsconfig").find(".metricsEnableCheck").hide();
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
</script>
|
|
19
|
+
|
|
20
|
+
<script type="text/html" template-section="onIncludeEditForm">
|
|
21
|
+
<div id="MetricsConfig">
|
|
22
|
+
<div class="form-row">
|
|
23
|
+
<label for="node-config-input-name"><i class="fa fa-tag"></i> Name</label>
|
|
24
|
+
<input type="text" id="node-config-input-name" />
|
|
25
|
+
</div>
|
|
26
|
+
|
|
27
|
+
<div class="form-row">
|
|
28
|
+
<label for="node-config-input-description"><i class="fa fa-tag"></i> Description</label>
|
|
29
|
+
<input type="text" id="node-config-input-description" />
|
|
30
|
+
</div>
|
|
31
|
+
|
|
32
|
+
<div class="form-row">
|
|
33
|
+
<label></label>
|
|
34
|
+
<input type="checkbox" id="node-config-input-reset" style="width:20px; margin-right:5px;" />
|
|
35
|
+
<label style="width:auto" for="node-config-input-reset"><span>Reset on Deploy</span></label>
|
|
36
|
+
</div>
|
|
37
|
+
</div>
|
|
38
|
+
</script>
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
<script type="text/markdown" template-section="onIncludeDocumentation">
|
|
42
|
+
Configuration node for the Counter Metrics
|
|
43
|
+
|
|
44
|
+
### Inputs
|
|
45
|
+
: *name* (string) : The common name for the counter.
|
|
46
|
+
: *description* (string) : A description for the given counter
|
|
47
|
+
|
|
48
|
+
</script>
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
|
|
2
|
+
import { Node } from "node-red";
|
|
3
|
+
import { ConfigNode, ConfigNodeConfig, NodeDescriptor, NodeManager } from "../../NodeConstructor"
|
|
4
|
+
import { MetricsContainer, MetricsService, MetricsReference, CounterMetric, CounterMetricConfig} from "../service/MetricsService"
|
|
5
|
+
import { SourceUtility } from "../../NodeGenerator";
|
|
6
|
+
import { MetricsConfigNode } from "./MetricsConfigNode";
|
|
7
|
+
import { MetricsTemplate } from "../template/MetricsTemplate";
|
|
8
|
+
import { NodeDescription } from "../../tagging/NodeDescriptionDecorator";
|
|
9
|
+
|
|
10
|
+
interface CounterMetricConfigNodeConfig extends ConfigNodeConfig, CounterMetricConfig, MetricsReference {
|
|
11
|
+
description:string,
|
|
12
|
+
reset:boolean
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
@NodeDescription({
|
|
16
|
+
id:"CounterMetricConfigNode",
|
|
17
|
+
name:"Counter Metric Config Node",
|
|
18
|
+
group:"config",
|
|
19
|
+
sourceFile:SourceUtility.getSourcePath("/build/", "/src/") + "CounterMetricConfigNode.html",
|
|
20
|
+
package: "@theotherwillembotha/node-red-plugincore",
|
|
21
|
+
templates:[
|
|
22
|
+
{ template:MetricsTemplate, config: {} }
|
|
23
|
+
],
|
|
24
|
+
dependencies:[ MetricsConfigNode, MetricsService ],
|
|
25
|
+
tags: [ "MetricType" ]
|
|
26
|
+
})
|
|
27
|
+
export class CounterMetricConfigNode extends ConfigNode<CounterMetricConfigNodeConfig> {
|
|
28
|
+
private _metrics: MetricsContainer;
|
|
29
|
+
private _counter: CounterMetric;
|
|
30
|
+
|
|
31
|
+
constructor(node: Node, config: CounterMetricConfigNodeConfig){
|
|
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()
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
this._counter = this._metrics.counter(counterConfig);
|
|
49
|
+
|
|
50
|
+
if(config.reset){
|
|
51
|
+
this._counter.reset();
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
public metrics():MetricsContainer {
|
|
56
|
+
return this._metrics;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
public counter():CounterMetric {
|
|
60
|
+
return this._counter;
|
|
61
|
+
}
|
|
62
|
+
}
|