@theotherwillembotha/node-red-plugincore 0.0.54 → 0.1.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 +9 -9
- package/build/GenerateNodes.js +0 -1
- package/build/Nodes.html +23 -162
- package/build/Nodes.js +0 -2
- package/build/Plugins.js +2 -3
- package/build/core/NodeConstructor.d.ts +1 -0
- package/build/core/NodeConstructor.d.ts.map +1 -1
- package/build/core/NodeConstructor.js +20 -62
- package/build/core/NodeGenerator.d.ts.map +1 -1
- package/build/core/NodeGenerator.js +8 -11
- package/build/core/logger/LoggerDecorator.d.ts.map +1 -1
- package/build/core/logger/LoggerDecorator.js +34 -38
- package/build/core/logger/node/ConsoleLoggerConfigNode.d.ts +11 -7
- package/build/core/logger/node/ConsoleLoggerConfigNode.d.ts.map +1 -1
- package/build/core/logger/node/ConsoleLoggerConfigNode.js +24 -10
- package/build/core/logger/node/RestLoggerConfigNode.d.ts +22 -6
- package/build/core/logger/node/RestLoggerConfigNode.d.ts.map +1 -1
- package/build/core/logger/node/RestLoggerConfigNode.js +93 -23
- package/build/core/logger/service/LoggerService.d.ts +59 -68
- package/build/core/logger/service/LoggerService.d.ts.map +1 -1
- package/build/core/logger/service/LoggerService.js +76 -165
- package/build/core/logger/template/LoggerTemplate.d.ts +9 -1
- package/build/core/logger/template/LoggerTemplate.d.ts.map +1 -1
- package/build/core/metrics/node/CounterMetricConfigNode.js +0 -2
- package/build/core/metrics/node/GaugeMetricConfigNode.js +0 -2
- package/build/core/metrics/node/MetricsConfigNode.js +0 -1
- package/build/core/metrics/node/TimerMetricConfigNode.js +0 -2
- package/build/core/metrics/service/MetricsService.js +10 -24
- package/build/core/other/service/SettingsService.js +0 -2
- package/build/core/tagging/service/NodeTypeService.js +1 -2
- package/build/core/webhook/WebhookDecorator.d.ts.map +1 -1
- package/build/core/webhook/WebhookDecorator.js +47 -10
- package/build/core/webhook/node/WebhookServerConfigNode.js +0 -1
- package/build/core/webhook/service/ReverseProxyTypeService.d.ts +1 -2
- package/build/core/webhook/service/ReverseProxyTypeService.d.ts.map +1 -1
- package/build/core/webhook/service/ReverseProxyTypeService.js +1 -6
- package/build/core/webhook/service/WebhookServerService.d.ts +1 -1
- package/build/core/webhook/service/WebhookServerService.d.ts.map +1 -1
- package/build/core/webhook/service/WebhookServerService.js +6 -14
- package/build/core/webhook/template/WebhookTemplate.d.ts +1 -1
- package/build/core/webhook/template/WebhookTemplate.d.ts.map +1 -1
- package/build/index.d.ts +1 -2
- package/build/index.d.ts.map +1 -1
- package/build/index.js +1 -2
- package/build/resources/editorLanguageExtension.js +1 -2
- package/package.json +6 -5
- package/resources/editorLanguageExtension.js +1 -2
- package/src/GenerateNodes.ts +2 -2
- package/src/core/NodeConstructor.ts +7 -14
- package/src/core/NodeGenerator.ts +2 -3
- package/src/core/logger/LoggerDecorator.ts +56 -53
- package/src/core/logger/node/ConsoleLoggerConfigNode.ts +39 -14
- package/src/core/logger/node/RestLoggerConfigNode.ts +128 -25
- package/src/core/logger/service/LoggerService.ts +103 -239
- package/src/core/logger/template/LoggerTemplate.html +2 -2
- package/src/core/logger/template/LoggerTemplate.ts +11 -1
- package/src/core/metrics/node/TimerMetricConfigNode.html +2 -2
- package/src/core/other/template/BasicTemplate.html +5 -2
- package/src/core/webhook/WebhookDecorator.ts +54 -13
- package/src/core/webhook/service/ReverseProxyTypeService.ts +1 -4
- package/src/core/webhook/service/WebhookServerService.ts +1 -6
- package/src/core/webhook/template/WebhookTemplate.html +1 -1
- package/src/core/webhook/template/WebhookTemplate.ts +1 -1
- package/src/index.ts +2 -2
- package/build/core/logger/node/ConsoleLoggerConfigNode.html +0 -90
- package/build/core/logger/node/LokiLoggerConfigNode.d.ts +0 -20
- package/build/core/logger/node/LokiLoggerConfigNode.d.ts.map +0 -1
- package/build/core/logger/node/LokiLoggerConfigNode.html +0 -117
- package/build/core/logger/node/LokiLoggerConfigNode.js +0 -53
- package/build/core/logger/node/RestLoggerConfigNode.html +0 -183
- package/build/core/logger/service/LoggerServiceTypes.d.ts +0 -24
- package/build/core/logger/service/LoggerServiceTypes.d.ts.map +0 -1
- package/build/core/logger/service/LoggerServiceTypes.js +0 -30
- package/build/core/logger/template/LoggerTemplate.html +0 -331
- package/build/core/metrics/node/CounterMetricConfigNode.html +0 -48
- package/build/core/metrics/node/GaugeMetricConfigNode.html +0 -48
- package/build/core/metrics/node/MetricsConfigNode.html +0 -21
- package/build/core/metrics/node/TimerMetricConfigNode.html +0 -190
- package/build/core/metrics/template/CounterMetricTemplate.html +0 -40
- package/build/core/metrics/template/GaugeMetricTemplate.html +0 -39
- package/build/core/metrics/template/MetricsTemplate.html +0 -54
- package/build/core/metrics/template/TimerMetricTemplate.html +0 -39
- package/build/core/other/node/DelegatedConfigReferenceNode.html +0 -1
- package/build/core/other/template/BasicTemplate.html +0 -76
- package/build/core/other/template/SettingsTemplate.html +0 -128
- package/build/core/ui/template/ScriptEditorTemplate.html +0 -50
- package/build/core/ui/template/UIHelperTemplate.html +0 -229
- package/build/core/webhook/node/WebhookServerConfigNode.html +0 -61
- package/build/core/webhook/template/WebhookTemplate.html +0 -442
- package/documentation/LokiLoggerConfigNode.png +0 -0
- package/src/core/logger/node/LokiLoggerConfigNode.html +0 -117
- package/src/core/logger/node/LokiLoggerConfigNode.ts +0 -58
- package/src/core/logger/service/LoggerServiceTypes.ts +0 -26
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import
|
|
1
|
+
import os from "os";
|
|
2
|
+
import { RestAuthType } from "../logger/service/LoggerService";
|
|
2
3
|
import { BaseNode, createPostConstructDecorator, NodeManager } from "../NodeConstructor";
|
|
3
|
-
import { ProxyManagerClient } from "./service/ReverseProxyTypeService";
|
|
4
|
+
import { HTTPScheme, ProxyManagerClient } from "./service/ReverseProxyTypeService";
|
|
4
5
|
import { ApiKeyAuthenticationConfig, BasicAuthenticationConfig, EndpointConfig, EndpointMethodType, NoAuthenticationConfig, WebhookServer } from "./service/WebhookServerService";
|
|
5
6
|
import { WebhookTemplateConfig } from "./template/WebhookTemplate";
|
|
6
7
|
|
|
@@ -10,6 +11,14 @@ type WebhookConfig = {
|
|
|
10
11
|
methods:EndpointMethodType[],
|
|
11
12
|
}
|
|
12
13
|
|
|
14
|
+
type ManagedProxyHost = {
|
|
15
|
+
proxyNodeId: string;
|
|
16
|
+
hostId: number;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// In-memory registry: nodeId → managed proxy host entries from the last deploy.
|
|
20
|
+
const managedProxyHosts = new Map<string, ManagedProxyHost[]>();
|
|
21
|
+
|
|
13
22
|
const Webhook = createPostConstructDecorator<WebhookConfig>('Webhook')
|
|
14
23
|
.withInitLogic(async (instance, propertyKey, webhookconfig:WebhookConfig) => {
|
|
15
24
|
//console.log(`Registering webhook callback`, "PROPERTYKEY", propertyKey, "WEBHOOK CONFIG", webhookconfig, "THIS", this);
|
|
@@ -35,26 +44,58 @@ const Webhook = createPostConstructDecorator<WebhookConfig>('Webhook')
|
|
|
35
44
|
|
|
36
45
|
if(nodeConfig.reverseProxies_enabled){
|
|
37
46
|
|
|
38
|
-
|
|
47
|
+
let targetPort = webhookServer.config().port;
|
|
48
|
+
let targetHost = os.hostname();
|
|
49
|
+
let nodeId = nodeConfig.id;
|
|
50
|
+
let newlyManaged: ManagedProxyHost[] = [];
|
|
39
51
|
|
|
52
|
+
await Promise.all(nodeConfig.reverseProxies_connections.map(async proxy => {
|
|
40
53
|
try{
|
|
41
|
-
// get a n instance of reverseProxNode.
|
|
42
|
-
let reverseProxyNode = (NodeManager.RED.nodes.getNode(proxy.proxy) as any).node();
|
|
43
|
-
|
|
44
54
|
// TODO: ReverseProxyConfigNodes need to become their own subtype of config nodes so we can enforce the ".client()" method.
|
|
55
|
+
let reverseProxyNode = (NodeManager.RED.nodes.getNode(proxy.proxy) as any).node();
|
|
45
56
|
let proxyClient = reverseProxyNode.client() as ProxyManagerClient;
|
|
46
57
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
58
|
+
let hosts = await proxyClient.getHosts();
|
|
59
|
+
let matchingHost = hosts.find(h => h.domainNames?.includes(proxy.domainname));
|
|
60
|
+
|
|
61
|
+
if (!matchingHost) {
|
|
62
|
+
await proxyClient.updateHost({ domainNames: [proxy.domainname], forwardHost: targetHost, forwardPort: targetPort, scheme: HTTPScheme.HTTP });
|
|
63
|
+
// Fetch again to get the assigned ID of the newly created entry.
|
|
64
|
+
let updatedHosts = await proxyClient.getHosts();
|
|
65
|
+
matchingHost = updatedHosts.find(h => h.domainNames?.includes(proxy.domainname));
|
|
66
|
+
}
|
|
67
|
+
else if (matchingHost.forwardHost !== targetHost || matchingHost.forwardPort !== targetPort) {
|
|
68
|
+
await proxyClient.updateHost({ id: matchingHost.id, forwardHost: targetHost, forwardPort: targetPort, scheme: HTTPScheme.HTTP });
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (matchingHost?.id !== undefined) {
|
|
72
|
+
newlyManaged.push({ proxyNodeId: proxy.proxy, hostId: matchingHost.id });
|
|
73
|
+
}
|
|
51
74
|
}
|
|
52
75
|
catch(e){
|
|
53
|
-
console.
|
|
76
|
+
console.error(e);
|
|
54
77
|
}
|
|
55
|
-
|
|
56
|
-
return Promise.resolve();
|
|
57
78
|
}));
|
|
79
|
+
|
|
80
|
+
// Remove any stale proxy host entries that were managed last deploy but are no longer in the current config.
|
|
81
|
+
let previouslyManaged = managedProxyHosts.get(nodeId) ?? [];
|
|
82
|
+
let newHostIds = new Set(newlyManaged.map(m => m.hostId));
|
|
83
|
+
|
|
84
|
+
await Promise.all(previouslyManaged
|
|
85
|
+
.filter(m => !newHostIds.has(m.hostId))
|
|
86
|
+
.map(async stale => {
|
|
87
|
+
try{
|
|
88
|
+
let reverseProxyNode = (NodeManager.RED.nodes.getNode(stale.proxyNodeId) as any).node();
|
|
89
|
+
let proxyClient = reverseProxyNode.client() as ProxyManagerClient;
|
|
90
|
+
await proxyClient.deleteHost(stale.hostId);
|
|
91
|
+
}
|
|
92
|
+
catch(e){
|
|
93
|
+
console.error(e);
|
|
94
|
+
}
|
|
95
|
+
})
|
|
96
|
+
);
|
|
97
|
+
|
|
98
|
+
managedProxyHosts.set(nodeId, newlyManaged);
|
|
58
99
|
}
|
|
59
100
|
|
|
60
101
|
// register a close listener to the node.
|
|
@@ -22,10 +22,7 @@ export abstract class ReverseProxyType {
|
|
|
22
22
|
export interface ProxyManagerClient {
|
|
23
23
|
updateHost(data: Partial<HostEntry>):Promise<void>;
|
|
24
24
|
getHosts():Promise<Partial<HostEntry>[]>;
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
export abstract class ReverseProxyClient {
|
|
28
|
-
|
|
25
|
+
deleteHost(id: number):Promise<void>;
|
|
29
26
|
}
|
|
30
27
|
|
|
31
28
|
export type HostEntry = {
|
|
@@ -5,7 +5,7 @@ import { WebhookServerConfigNode } from "../node/WebhookServerConfigNode";
|
|
|
5
5
|
import { WebhookTemplate } from "../template/WebhookTemplate";
|
|
6
6
|
import express, {Express, Request, Response} from "express";
|
|
7
7
|
import { Server } from "http";
|
|
8
|
-
import { ApiKeyMechanismType, RestAuthType } from "../../logger/service/
|
|
8
|
+
import { ApiKeyMechanismType, RestAuthType } from "../../logger/service/LoggerService";
|
|
9
9
|
|
|
10
10
|
var bodyParser = require('body-parser');
|
|
11
11
|
|
|
@@ -95,7 +95,6 @@ export class WebhookServer {
|
|
|
95
95
|
this._app.post(endpoint.path, handlerChain);
|
|
96
96
|
}
|
|
97
97
|
|
|
98
|
-
console.log("added endpoint to " + endpoint.path);
|
|
99
98
|
}
|
|
100
99
|
|
|
101
100
|
public detach(configuration:EndpointConfig){
|
|
@@ -116,8 +115,6 @@ export class WebhookServer {
|
|
|
116
115
|
})
|
|
117
116
|
});
|
|
118
117
|
|
|
119
|
-
console.log("ROUTES REMOVED!");
|
|
120
|
-
this._app.router.stack.forEach(route => console.log("KNOWN ROUTE", route, route.route?.path, (route.route as any).methods.post));
|
|
121
118
|
}
|
|
122
119
|
|
|
123
120
|
public config():WebhookServerConfig {
|
|
@@ -161,7 +158,6 @@ export class WebhookServerService extends BaseService {
|
|
|
161
158
|
// compare the properties.
|
|
162
159
|
if(!webhookServerNode){
|
|
163
160
|
// the node has been removed: TODO: alert the listeners that it has been removed.
|
|
164
|
-
console.log("Webhook Service Removed", serverServiceConfig)
|
|
165
161
|
removedServers.push(serverServiceConfig);
|
|
166
162
|
}
|
|
167
163
|
else{
|
|
@@ -173,7 +169,6 @@ export class WebhookServerService extends BaseService {
|
|
|
173
169
|
|
|
174
170
|
if(serviceChanged){
|
|
175
171
|
// TODO: notify the subscribers that the server has chaned.
|
|
176
|
-
console.log("Notify the subscribers WebhookServer has changed.", serverServiceConfig, webhookServerNode);
|
|
177
172
|
removedServers.push(serverServiceConfig);
|
|
178
173
|
addedServers.push(webhookServerNode);
|
|
179
174
|
}
|
|
@@ -11,7 +11,7 @@ node
|
|
|
11
11
|
.addDefault('webhookAuth_apikey_key', {value:"x-api-key", required:false})
|
|
12
12
|
.addDefault('webhookAuth_apikey_value', {value:"testkey", required:false})
|
|
13
13
|
.addDefault('reverseProxies_enabled', {required:false})
|
|
14
|
-
.addDefault('reverseProxies_connections', { type:"
|
|
14
|
+
.addDefault('reverseProxies_connections', { type:"DelegatedConfigReferenceNode", list:true, maxInstances:10})
|
|
15
15
|
</script>
|
|
16
16
|
|
|
17
17
|
<div template-section="onIncludeOnce">
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { BaseNodeConfig, Template, TemplateDescriptor } from "../../NodeConstructor"
|
|
2
2
|
import { WebhookServerConfigNode } from "../node/WebhookServerConfigNode";
|
|
3
3
|
import { SourceUtility } from "../../NodeGenerator";
|
|
4
|
-
import {
|
|
4
|
+
import { RestAuthType, ApiKeyMechanismType } from "../../logger/service/LoggerService";
|
|
5
5
|
|
|
6
6
|
export interface WebhookTemplateConfig extends BaseNodeConfig{
|
|
7
7
|
webhook:string,
|
package/src/index.ts
CHANGED
|
@@ -4,10 +4,10 @@ export * from "./core/NodeConstructor";
|
|
|
4
4
|
|
|
5
5
|
// LOGGER
|
|
6
6
|
export * from "./core/logger/service/LoggerService";
|
|
7
|
-
export * from "./core/logger/template/LoggerTemplate";
|
|
8
7
|
export * from "./core/logger/node/ConsoleLoggerConfigNode";
|
|
9
8
|
export * from "./core/logger/node/RestLoggerConfigNode";
|
|
10
|
-
export * from "./core/logger/
|
|
9
|
+
export * from "./core/logger/template/LoggerTemplate";
|
|
10
|
+
|
|
11
11
|
|
|
12
12
|
// METRICS
|
|
13
13
|
export * from "./core/metrics/service/MetricsService";
|
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
<script type="text/javascript" template-section="onCompose">
|
|
3
|
-
node
|
|
4
|
-
.addDefault("name", {value:"Logger Example", required:true})
|
|
5
|
-
.addDefault("platform", {value:"rest", required:true})
|
|
6
|
-
.addDefault("template", {value:`message:{{msg}}`, required:true})
|
|
7
|
-
.addDefault("level", {value:"info", required:true})
|
|
8
|
-
.setPaletteLabel("Console Logger Config Node")
|
|
9
|
-
.setLabel(function() {return this.name })
|
|
10
|
-
</script>
|
|
11
|
-
|
|
12
|
-
<script type="text/javascript" template-section="onIncludeEditPrepare">
|
|
13
|
-
{
|
|
14
|
-
let node = this;
|
|
15
|
-
|
|
16
|
-
let levelSelection = $("#node-config-input-level");
|
|
17
|
-
levelSelection.typedInput({type:"level", types:[{
|
|
18
|
-
value: "level",
|
|
19
|
-
options: [
|
|
20
|
-
{ value: "DEBUG", label: "debug"},
|
|
21
|
-
{ value: "INFO", label: "info"},
|
|
22
|
-
{ value: "WARNING", label: "warning"},
|
|
23
|
-
{ value: "ERROR", label: "error"},
|
|
24
|
-
]
|
|
25
|
-
}]});
|
|
26
|
-
|
|
27
|
-
this.editor = RED.editor.createEditor({
|
|
28
|
-
id: 'node-config-input-templateEditor',
|
|
29
|
-
mode: 'ace/mode/handlebars',
|
|
30
|
-
value: this.template
|
|
31
|
-
});
|
|
32
|
-
}
|
|
33
|
-
</script>
|
|
34
|
-
|
|
35
|
-
<script type="text/javascript" template-section="onIncludeEditSave">
|
|
36
|
-
{
|
|
37
|
-
let node = this;
|
|
38
|
-
|
|
39
|
-
this.template = this.editor.getValue();
|
|
40
|
-
this.editor.destroy();
|
|
41
|
-
delete this.editor;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
</script>
|
|
45
|
-
|
|
46
|
-
<script type="text/html" template-section="onIncludeEditForm">
|
|
47
|
-
<div id="LoggerConfig">
|
|
48
|
-
<div class="form-row">
|
|
49
|
-
<label class="towb_editorlabel" for="node-config-input-name"><i class="fa fa-font"></i> Name</label>
|
|
50
|
-
<input type="text" id="node-config-input-name" />
|
|
51
|
-
</div>
|
|
52
|
-
|
|
53
|
-
<div class="form-row">
|
|
54
|
-
<label class="towb_editorlabel" for="node-config-input-level"><i class="fa fa-signal"></i> Level</label>
|
|
55
|
-
<input type="text" id="node-config-input-level" />
|
|
56
|
-
</div>
|
|
57
|
-
|
|
58
|
-
<div class="form-row">
|
|
59
|
-
<label class="towb_editorlabel" for="node-config-input-templateEditor"><i class="fa fa-code"></i> Template</label>
|
|
60
|
-
<div style="height: 250px; min-height:150px;" class="node-text-editor" id="node-config-input-templateEditor"></div>
|
|
61
|
-
</div>
|
|
62
|
-
</div>
|
|
63
|
-
</script>
|
|
64
|
-
|
|
65
|
-
<script type="text/markdown" template-section="onIncludeDocumentation">
|
|
66
|
-
Writes log output to the Node-RED runtime console (stdout). Suitable for local development and containerised environments where stdout is captured.
|
|
67
|
-
|
|
68
|
-
### Properties
|
|
69
|
-
: *name* (string) : A descriptive name for this logger configuration.
|
|
70
|
-
: *level* (level) : The minimum log level. Messages below this threshold are suppressed. Options: DEBUG, INFO, WARNING, ERROR.
|
|
71
|
-
: *template* (mustache) : A Mustache/Handlebars template that formats the log message body.
|
|
72
|
-
|
|
73
|
-
### Mustache Templating
|
|
74
|
-
Mustache/Handlebars templates build the message string written to the console.
|
|
75
|
-
|
|
76
|
-
#### Provided Properties
|
|
77
|
-
: *msg* (object) : The Node-RED message object passed through the node.
|
|
78
|
-
: *currentTime* (string) : The current time in ISO 8601 format.
|
|
79
|
-
|
|
80
|
-
#### Helpers
|
|
81
|
-
: *json* (helper) : Serialises an object to a JSON string using `JSON.stringify`.
|
|
82
|
-
|
|
83
|
-
#### Examples
|
|
84
|
-
- `{{{json msg}}}` — serialises the full message object as JSON.
|
|
85
|
-
|
|
86
|
-
#### References
|
|
87
|
-
- [Mustache — Wikipedia](https://en.wikipedia.org/wiki/Mustache_(template_system))
|
|
88
|
-
- [Mustache — Playground](https://jgonggrijp.gitlab.io/wontache/playground.html)
|
|
89
|
-
</script>
|
|
90
|
-
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { Node } from "node-red";
|
|
2
|
-
import { ConfigNode, ConfigNodeConfig } from "../../NodeConstructor";
|
|
3
|
-
import { Log, LoggerRegistration } from "../service/LoggerService";
|
|
4
|
-
import { Level } from "../service/LoggerServiceTypes";
|
|
5
|
-
interface LokiLoggerConfigNodeConfig extends ConfigNodeConfig {
|
|
6
|
-
id: string;
|
|
7
|
-
level: Level;
|
|
8
|
-
template: string;
|
|
9
|
-
loki_host: string;
|
|
10
|
-
loki_userid?: string;
|
|
11
|
-
loki_authtoken?: string;
|
|
12
|
-
loki_tenantid?: string;
|
|
13
|
-
}
|
|
14
|
-
export declare class LokiLoggerConfigNode extends ConfigNode<LokiLoggerConfigNodeConfig> {
|
|
15
|
-
private _logger;
|
|
16
|
-
constructor(node: Node, config: LokiLoggerConfigNodeConfig);
|
|
17
|
-
registerLogger(registration: LoggerRegistration): Log;
|
|
18
|
-
}
|
|
19
|
-
export {};
|
|
20
|
-
//# sourceMappingURL=LokiLoggerConfigNode.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"LokiLoggerConfigNode.d.ts","sourceRoot":"","sources":["../../../../src/core/logger/node/LokiLoggerConfigNode.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAChC,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AACpE,OAAO,EAAa,GAAG,EAAE,kBAAkB,EAAiB,MAAM,0BAA0B,CAAA;AAE5F,OAAO,EAAE,KAAK,EAAgB,MAAM,+BAA+B,CAAC;AAGpE,UAAU,0BAA2B,SAAQ,gBAAgB;IAEzD,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAC,KAAK,CAAC;IACZ,QAAQ,EAAC,MAAM,CAAC;IAEhB,SAAS,EAAC,MAAM,CAAC;IACjB,WAAW,CAAC,EAAC,MAAM,CAAC;IACpB,cAAc,CAAC,EAAC,MAAM,CAAC;IACvB,aAAa,CAAC,EAAC,MAAM,CAAA;CACxB;AAED,qBASa,oBAAqB,SAAQ,UAAU,CAAC,0BAA0B,CAAC;IAE5E,OAAO,CAAC,OAAO,CAAkB;gBAErB,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,0BAA0B;IAqBnD,cAAc,CAAC,YAAY,EAAC,kBAAkB,GAAE,GAAG;CAG7D"}
|
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
<script type="text/javascript" template-section="onCompose">
|
|
3
|
-
node
|
|
4
|
-
.addDefault("name", {value:"Logger Example", required:true})
|
|
5
|
-
.addDefault("template", {value:`message:{{msg}}`, required:true})
|
|
6
|
-
.addDefault("level", {value:"info", required:true})
|
|
7
|
-
|
|
8
|
-
.addDefault("loki_host", {})
|
|
9
|
-
.addDefault("loki_tenantid", {})
|
|
10
|
-
.addDefault("loki_userid", {})
|
|
11
|
-
.addDefault("loki_authtoken", {})
|
|
12
|
-
|
|
13
|
-
.setPaletteLabel("Loki Logger Config Node")
|
|
14
|
-
.setLabel(function() {return this.name })
|
|
15
|
-
</script>
|
|
16
|
-
|
|
17
|
-
<script type="text/javascript" template-section="onIncludeEditPrepare">
|
|
18
|
-
{
|
|
19
|
-
let node = this;
|
|
20
|
-
|
|
21
|
-
let levelSelection = $("#node-config-input-level");
|
|
22
|
-
levelSelection.typedInput({type:"level", types:[{
|
|
23
|
-
value: "level",
|
|
24
|
-
options: [
|
|
25
|
-
{ value: "DEBUG", label: "debug"},
|
|
26
|
-
{ value: "INFO", label: "info"},
|
|
27
|
-
{ value: "WARNING", label: "warning"},
|
|
28
|
-
{ value: "ERROR", label: "error"},
|
|
29
|
-
]
|
|
30
|
-
}]});
|
|
31
|
-
|
|
32
|
-
this.editor = RED.editor.createEditor({
|
|
33
|
-
id: 'node-config-input-templateEditor',
|
|
34
|
-
mode: 'ace/mode/handlebars',
|
|
35
|
-
value: this.template
|
|
36
|
-
});
|
|
37
|
-
}
|
|
38
|
-
</script>
|
|
39
|
-
|
|
40
|
-
<script type="text/javascript" template-section="onIncludeEditSave">
|
|
41
|
-
{
|
|
42
|
-
let node = this;
|
|
43
|
-
|
|
44
|
-
this.template = this.editor.getValue();
|
|
45
|
-
this.editor.destroy();
|
|
46
|
-
delete this.editor;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
</script>
|
|
50
|
-
|
|
51
|
-
<script type="text/html" template-section="onIncludeEditForm">
|
|
52
|
-
<div id="LoggerConfig">
|
|
53
|
-
<div class="form-row">
|
|
54
|
-
<label class="towb_editorlabel" for="node-config-input-name"><i class="fa fa-font"></i> Name</label>
|
|
55
|
-
<input type="text" id="node-config-input-name" />
|
|
56
|
-
</div>
|
|
57
|
-
|
|
58
|
-
<div class="form-row">
|
|
59
|
-
<label class="towb_editorlabel" for="node-config-input-level"><i class="fa fa-signal"></i> Level</label>
|
|
60
|
-
<input type="text" id="node-config-input-level" />
|
|
61
|
-
</div>
|
|
62
|
-
|
|
63
|
-
<div class="form-row">
|
|
64
|
-
<label class="towb_editorlabel" for="node-config-input-loki_host"><i class="fa fa-server"></i> Host</label>
|
|
65
|
-
<input class="required" type="text" id="node-config-input-loki_host" />
|
|
66
|
-
</div>
|
|
67
|
-
<div class="form-row">
|
|
68
|
-
<label class="towb_editorlabel" for="node-config-input-loki_tenantid"><i class="fa fa-building-o"></i> Tenant ID</label>
|
|
69
|
-
<input class="" type="text" id="node-config-input-loki_tenantid" />
|
|
70
|
-
</div>
|
|
71
|
-
<div class="form-row">
|
|
72
|
-
<label class="towb_editorlabel" for="node-config-input-loki_userid"><i class="fa fa-user"></i> Username</label>
|
|
73
|
-
<input class="" type="text" id="node-config-input-loki_userid" />
|
|
74
|
-
</div>
|
|
75
|
-
<div class="form-row">
|
|
76
|
-
<label class="towb_editorlabel" for="node-config-input-loki_authtoken"><i class="fa fa-key"></i> Auth Token</label>
|
|
77
|
-
<input class="" type="password" id="node-config-input-loki_authtoken" />
|
|
78
|
-
</div>
|
|
79
|
-
|
|
80
|
-
<div class="form-row">
|
|
81
|
-
<label class="towb_editorlabel" for="node-config-input-templateEditor"><i class="fa fa-code"></i> Template</label>
|
|
82
|
-
<div style="height: 250px; min-height:150px;" class="node-text-editor" id="node-config-input-templateEditor"></div>
|
|
83
|
-
</div>
|
|
84
|
-
</div>
|
|
85
|
-
</script>
|
|
86
|
-
|
|
87
|
-
<script type="text/markdown" template-section="onIncludeDocumentation">
|
|
88
|
-
Pushes log messages to a Grafana Loki instance using the Loki HTTP API.
|
|
89
|
-
|
|
90
|
-
### Properties
|
|
91
|
-
: *name* (string) : A descriptive name for this logger configuration.
|
|
92
|
-
: *level* (level) : The minimum log level. Messages below this threshold are suppressed. Options: DEBUG, INFO, WARNING, ERROR.
|
|
93
|
-
: *host* (string) : The base URL of the Loki instance, including port (e.g. `http://localhost:3100`).
|
|
94
|
-
: *tenant ID* (string) : The tenant identifier for multi-tenant Loki deployments (`X-Scope-OrgID` header). Leave blank for single-tenant deployments.
|
|
95
|
-
: *username* (string) : Username for Loki authentication.
|
|
96
|
-
: *auth token* (string) : Authentication token or password for Loki.
|
|
97
|
-
: *template* (mustache) : A Mustache/Handlebars template that formats the log message body.
|
|
98
|
-
|
|
99
|
-
### Mustache Templating
|
|
100
|
-
Mustache/Handlebars templates build the message string pushed to Loki.
|
|
101
|
-
|
|
102
|
-
#### Provided Properties
|
|
103
|
-
: *msg* (object) : The Node-RED message object passed through the node.
|
|
104
|
-
: *currentTime* (string) : The current time in ISO 8601 format.
|
|
105
|
-
|
|
106
|
-
#### Helpers
|
|
107
|
-
: *json* (helper) : Serialises an object to a JSON string using `JSON.stringify`.
|
|
108
|
-
|
|
109
|
-
#### Examples
|
|
110
|
-
- `{{{json msg}}}` — serialises the full message object as JSON.
|
|
111
|
-
|
|
112
|
-
#### References
|
|
113
|
-
- [Grafana Loki — HTTP API](https://grafana.com/docs/loki/latest/reference/loki-http-api/)
|
|
114
|
-
- [Mustache — Wikipedia](https://en.wikipedia.org/wiki/Mustache_(template_system))
|
|
115
|
-
- [Mustache — Playground](https://jgonggrijp.gitlab.io/wontache/playground.html)
|
|
116
|
-
</script>
|
|
117
|
-
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
-
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
-
};
|
|
8
|
-
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
-
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
-
};
|
|
11
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.LokiLoggerConfigNode = void 0;
|
|
13
|
-
const NodeConstructor_1 = require("../../NodeConstructor");
|
|
14
|
-
const LoggerService_1 = require("../service/LoggerService");
|
|
15
|
-
const NodeGenerator_1 = require("../../NodeGenerator");
|
|
16
|
-
const LoggerServiceTypes_1 = require("../service/LoggerServiceTypes");
|
|
17
|
-
const NodeDescriptionDecorator_1 = require("../../tagging/NodeDescriptionDecorator");
|
|
18
|
-
let LokiLoggerConfigNode = class LokiLoggerConfigNode extends NodeConstructor_1.ConfigNode {
|
|
19
|
-
_logger;
|
|
20
|
-
constructor(node, config) {
|
|
21
|
-
super(node, config);
|
|
22
|
-
let _this = this;
|
|
23
|
-
// instantiate the logger.
|
|
24
|
-
let loggerConfig;
|
|
25
|
-
loggerConfig = {
|
|
26
|
-
id: this.id(),
|
|
27
|
-
type: LoggerServiceTypes_1.PlatformType.loki,
|
|
28
|
-
template: config.template,
|
|
29
|
-
level: config.level,
|
|
30
|
-
host: config.loki_host,
|
|
31
|
-
userid: config.loki_userid,
|
|
32
|
-
authtoken: config.loki_authtoken,
|
|
33
|
-
tenantID: config.loki_tenantid,
|
|
34
|
-
};
|
|
35
|
-
this._logger = LoggerService_1.LoggerService.get(loggerConfig);
|
|
36
|
-
}
|
|
37
|
-
registerLogger(registration) {
|
|
38
|
-
return this._logger.register(registration);
|
|
39
|
-
}
|
|
40
|
-
};
|
|
41
|
-
exports.LokiLoggerConfigNode = LokiLoggerConfigNode;
|
|
42
|
-
exports.LokiLoggerConfigNode = LokiLoggerConfigNode = __decorate([
|
|
43
|
-
(0, NodeDescriptionDecorator_1.NodeDescription)({
|
|
44
|
-
id: "LokiLoggerConfigNode",
|
|
45
|
-
name: "Loki Logger",
|
|
46
|
-
group: "config",
|
|
47
|
-
sourceFile: NodeGenerator_1.SourceUtility.getSourcePath("/build/", "/src/") + "LokiLoggerConfigNode.html",
|
|
48
|
-
package: "@theotherwillembotha/node-red-plugincore",
|
|
49
|
-
dependencies: [LoggerService_1.LoggerService],
|
|
50
|
-
tags: ["LoggerType"]
|
|
51
|
-
}),
|
|
52
|
-
__metadata("design:paramtypes", [Object, Object])
|
|
53
|
-
], LokiLoggerConfigNode);
|
|
@@ -1,183 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
<script type="text/javascript" template-section="onCompose">
|
|
3
|
-
node
|
|
4
|
-
.addDefault("name", {value:"Logger Example", required:true})
|
|
5
|
-
.addDefault("template", {value:`message:{{msg}}`, required:true})
|
|
6
|
-
.addDefault("level", {value:"info", required:true})
|
|
7
|
-
|
|
8
|
-
// platform rest:
|
|
9
|
-
.addDefault("rest_url", {})
|
|
10
|
-
.addDefault("rest_ignoresslerror", {})
|
|
11
|
-
.addDefault("rest_auth_type", {})
|
|
12
|
-
.addDefault("rest_auth_basic_username", {})
|
|
13
|
-
.addDefault("rest_auth_basic_password", {})
|
|
14
|
-
.addDefault("rest_auth_apikey_mechanism", {})
|
|
15
|
-
.addDefault("rest_auth_apikey_name", {})
|
|
16
|
-
.addDefault("rest_auth_apikey_value", {})
|
|
17
|
-
|
|
18
|
-
.setPaletteLabel("Rest Logger Config Node")
|
|
19
|
-
.setLabel(function() {return this.name })
|
|
20
|
-
|
|
21
|
-
</script>
|
|
22
|
-
|
|
23
|
-
<script type="text/javascript" template-section="onIncludeEditPrepare">
|
|
24
|
-
{
|
|
25
|
-
let node = this;
|
|
26
|
-
|
|
27
|
-
let showSelectedRestAuthMethod = (value) => {
|
|
28
|
-
$("#LoggerConfig")
|
|
29
|
-
.find(".platform.platform-rest").first()
|
|
30
|
-
.find(".platform-rest-auth")
|
|
31
|
-
.each((i, t) => {
|
|
32
|
-
t = $(t);
|
|
33
|
-
if(t.hasClass(`auth-${value}`)){ t.show(); }
|
|
34
|
-
else { t.hide(); }
|
|
35
|
-
});
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
let levelSelection = $("#node-config-input-level");
|
|
39
|
-
levelSelection.typedInput({type:"level", types:[{
|
|
40
|
-
value: "level",
|
|
41
|
-
options: [
|
|
42
|
-
{ value: "DEBUG", label: "debug"},
|
|
43
|
-
{ value: "INFO", label: "info"},
|
|
44
|
-
{ value: "WARNING", label: "warning"},
|
|
45
|
-
{ value: "ERROR", label: "error"},
|
|
46
|
-
]
|
|
47
|
-
}]});
|
|
48
|
-
|
|
49
|
-
let platformRestAuthType = $("#node-config-input-rest_auth_type");
|
|
50
|
-
platformRestAuthType.typedInput({type:"authtype", types:[{
|
|
51
|
-
value: "authtype",
|
|
52
|
-
options: [
|
|
53
|
-
{ value: "none", label: "None"},
|
|
54
|
-
{ value: "basic", label: "Basic"},
|
|
55
|
-
{ value: "apikey", label: "ApiKey"}
|
|
56
|
-
]
|
|
57
|
-
}]});
|
|
58
|
-
platformRestAuthType.on("change", () => showSelectedRestAuthMethod(platformRestAuthType.val()));
|
|
59
|
-
|
|
60
|
-
let apiKeyMechanism = $("#node-config-input-rest_auth_apikey_mechanism");
|
|
61
|
-
apiKeyMechanism.typedInput({type:"apikeymechansim", types:[{
|
|
62
|
-
value: "apikeymechansim",
|
|
63
|
-
options: [
|
|
64
|
-
{ value: "header", label: "Header"},
|
|
65
|
-
{ value: "queryparam", label: "Query Param"},
|
|
66
|
-
{ value: "matrixparam", label: "Matrix Param"}
|
|
67
|
-
]
|
|
68
|
-
}]});
|
|
69
|
-
|
|
70
|
-
this.editor = RED.editor.createEditor({
|
|
71
|
-
id: 'node-config-input-templateEditor',
|
|
72
|
-
mode: 'ace/mode/handlebars',
|
|
73
|
-
value: this.template
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
</script>
|
|
77
|
-
|
|
78
|
-
<script type="text/javascript" template-section="onIncludeEditSave">
|
|
79
|
-
{
|
|
80
|
-
let node = this;
|
|
81
|
-
this.template = this.editor.getValue();
|
|
82
|
-
this.editor.destroy();
|
|
83
|
-
delete this.editor;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
</script>
|
|
87
|
-
|
|
88
|
-
<script type="text/html" template-section="onIncludeEditForm">
|
|
89
|
-
<div id="LoggerConfig">
|
|
90
|
-
<div class="form-row">
|
|
91
|
-
<label class="towb_editorlabel" for="node-config-input-name"><i class="fa fa-font"></i> Name</label>
|
|
92
|
-
<input type="text" id="node-config-input-name" />
|
|
93
|
-
</div>
|
|
94
|
-
|
|
95
|
-
<div class="form-row">
|
|
96
|
-
<label class="towb_editorlabel" for="node-config-input-level"><i class="fa fa-signal"></i> Level</label>
|
|
97
|
-
<input type="text" id="node-config-input-level" />
|
|
98
|
-
</div>
|
|
99
|
-
|
|
100
|
-
<div class="platform platform-rest">
|
|
101
|
-
<div class="form-row">
|
|
102
|
-
<label class="towb_editorlabel" for="node-config-input-rest_url"><i class="fa fa-link"></i> URL</label>
|
|
103
|
-
<input class="platform-rest-input required" type="text" id="node-config-input-rest_url" />
|
|
104
|
-
</div>
|
|
105
|
-
<div class="form-row">
|
|
106
|
-
<label class="towb_editorlabel"></label>
|
|
107
|
-
<input type="checkbox" id="node-config-input-rest_ignoresslerror" style="width:20px; margin-right:5px;" />
|
|
108
|
-
<label style="width:auto" for="node-config-input-rest_ignoresslerror"><span>Ignore Invalid SSL certificates</span></label>
|
|
109
|
-
</div>
|
|
110
|
-
<div class="form-row">
|
|
111
|
-
<label class="towb_editorlabel" for="node-config-input-rest_auth_type"><i class="fa fa-lock"></i> Authentication</label>
|
|
112
|
-
<input class="platform-rest-input required" type="text" id="node-config-input-rest_auth_type" />
|
|
113
|
-
</div>
|
|
114
|
-
<div class="form-row platform-rest-auth auth-basic">
|
|
115
|
-
<label class="towb_editorlabel" for="node-config-input-rest_auth_basic_username"><i class="fa fa-user"></i> Username</label>
|
|
116
|
-
<input class="platform-rest-input" type="text" id="node-config-input-rest_auth_basic_username" />
|
|
117
|
-
</div>
|
|
118
|
-
<div class="form-row platform-rest-auth auth-basic">
|
|
119
|
-
<label class="towb_editorlabel" for="node-config-input-rest_auth_basic_password"><i class="fa fa-key"></i> Password</label>
|
|
120
|
-
<input class="platform-rest-input" type="password" id="node-config-input-rest_auth_basic_password" />
|
|
121
|
-
</div>
|
|
122
|
-
<div class="form-row platform-rest-auth auth-apikey">
|
|
123
|
-
<label class="towb_editorlabel" for="node-config-input-rest_auth_apikey_mechanism"><i class="fa fa-exchange"></i> Mechanism</label>
|
|
124
|
-
<input class="platform-rest-input" type="text" id="node-config-input-rest_auth_apikey_mechanism" />
|
|
125
|
-
</div>
|
|
126
|
-
<div class="form-row platform-rest-auth auth-apikey">
|
|
127
|
-
<label class="towb_editorlabel" for="node-config-input-rest_auth_apikey_name"><i class="fa fa-id-badge"></i> APIKey name</label>
|
|
128
|
-
<input class="platform-rest-input" type="text" id="node-config-input-rest_auth_apikey_name" />
|
|
129
|
-
</div>
|
|
130
|
-
<div class="form-row platform-rest-auth auth-apikey">
|
|
131
|
-
<label class="towb_editorlabel" for="node-config-input-rest_auth_apikey_value"><i class="fa fa-lock"></i> APIKey value</label>
|
|
132
|
-
<input class="platform-rest-input" type="text" id="node-config-input-rest_auth_apikey_value" />
|
|
133
|
-
</div>
|
|
134
|
-
</div>
|
|
135
|
-
|
|
136
|
-
<div class="form-row">
|
|
137
|
-
<label class="towb_editorlabel" for="node-config-input-templateEditor"><i class="fa fa-code"></i> Template</label>
|
|
138
|
-
<div style="height: 250px; min-height:150px;" class="node-text-editor" id="node-config-input-templateEditor"></div>
|
|
139
|
-
</div>
|
|
140
|
-
</div>
|
|
141
|
-
</script>
|
|
142
|
-
|
|
143
|
-
<script type="text/markdown" template-section="onIncludeDocumentation">
|
|
144
|
-
Posts log messages to an HTTP or HTTPS endpoint as a JSON payload.
|
|
145
|
-
|
|
146
|
-
### Properties
|
|
147
|
-
: *name* (string) : A descriptive name for this logger configuration.
|
|
148
|
-
: *level* (level) : The minimum log level. Messages below this threshold are suppressed. Options: DEBUG, INFO, WARNING, ERROR.
|
|
149
|
-
: *url* (url) : The endpoint that log messages will be POSTed to.
|
|
150
|
-
: *ignore SSL errors* (boolean) : When enabled, invalid SSL certificates are accepted.
|
|
151
|
-
: *authentication* (select) : The authentication strategy applied to each request. Options: None, Basic, ApiKey.
|
|
152
|
-
: *template* (mustache) : A Mustache/Handlebars template that formats the log message body.
|
|
153
|
-
|
|
154
|
-
### Authentication
|
|
155
|
-
#### Basic
|
|
156
|
-
Authenticates using the HTTP `Authorization` header (RFC 7617).
|
|
157
|
-
: *username* (string) : The username credential.
|
|
158
|
-
: *password* (string) : The password credential.
|
|
159
|
-
|
|
160
|
-
#### ApiKey
|
|
161
|
-
Authenticates by injecting a key/value pair into the request.
|
|
162
|
-
: *mechanism* (select) : Where the key is injected — Header, Query Param, or Matrix Param.
|
|
163
|
-
: *APIKey name* (string) : The name of the key (e.g. `x-api-key`).
|
|
164
|
-
: *APIKey value* (string) : The value of the key.
|
|
165
|
-
|
|
166
|
-
### Mustache Templating
|
|
167
|
-
Mustache/Handlebars templates build the message string POSTed to the endpoint.
|
|
168
|
-
|
|
169
|
-
#### Provided Properties
|
|
170
|
-
: *msg* (object) : The Node-RED message object passed through the node.
|
|
171
|
-
: *currentTime* (string) : The current time in ISO 8601 format.
|
|
172
|
-
|
|
173
|
-
#### Helpers
|
|
174
|
-
: *json* (helper) : Serialises an object to a JSON string using `JSON.stringify`.
|
|
175
|
-
|
|
176
|
-
#### Examples
|
|
177
|
-
- `{{{json msg}}}` — serialises the full message object as JSON.
|
|
178
|
-
|
|
179
|
-
#### References
|
|
180
|
-
- [Mustache — Wikipedia](https://en.wikipedia.org/wiki/Mustache_(template_system))
|
|
181
|
-
- [Mustache — Playground](https://jgonggrijp.gitlab.io/wontache/playground.html)
|
|
182
|
-
</script>
|
|
183
|
-
|