@5minds/node-red-contrib-processcube-elasticsearch 0.4.0-feature-d4edf3-m6cmuwqg → 1.0.0-develop-31b02f-m6dsjh20

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.
@@ -429,7 +429,7 @@
429
429
  },
430
430
  "@5minds/node-red-contrib-processcube-elasticsearch": {
431
431
  "name": "@5minds/node-red-contrib-processcube-elasticsearch",
432
- "version": "0.4.0",
432
+ "version": "1.0.0",
433
433
  "local": false,
434
434
  "user": false,
435
435
  "nodes": {
@@ -32,11 +32,18 @@
32
32
  },
33
33
  "tours": {
34
34
  "welcome": "4.0.8"
35
+ },
36
+ "dialog": {
37
+ "export": {
38
+ "pretty": true,
39
+ "json-view": false
40
+ }
35
41
  }
36
42
  },
37
43
  "do": {
38
44
  "markNodes": true
39
45
  },
40
- "menu-menu-item-sidebar": false
46
+ "menu-menu-item-sidebar": true,
47
+ "menu-menu-item-palette": false
41
48
  }
42
49
  }
@@ -15,14 +15,6 @@
15
15
  "info": "",
16
16
  "env": []
17
17
  },
18
- {
19
- "id": "4d4b126d45321059",
20
- "type": "tab",
21
- "label": "Flow 1",
22
- "disabled": false,
23
- "info": "",
24
- "env": []
25
- },
26
18
  {
27
19
  "id": "d35cb40208b209e1",
28
20
  "type": "group",
@@ -552,7 +544,7 @@
552
544
  "method": "GET",
553
545
  "ret": "obj",
554
546
  "paytoqs": "ignore",
555
- "url": "http://elasticsearch:9200/_search",
547
+ "url": "http://elasticsearch:9200/my-index/_search",
556
548
  "tls": "",
557
549
  "persist": false,
558
550
  "proxy": "",
@@ -628,7 +620,9 @@
628
620
  "loglevel": "Debug",
629
621
  "x": 300,
630
622
  "y": 120,
631
- "wires": []
623
+ "wires": [
624
+ []
625
+ ]
632
626
  },
633
627
  {
634
628
  "id": "443b329ab591c4dd",
@@ -646,7 +640,7 @@
646
640
  "once": false,
647
641
  "onceDelay": 0.1,
648
642
  "topic": "",
649
- "payload": "{\"message\":\"hello world\",\"messageTemplate\":\"a messageTemplate\",\"meta\":{\"message\":\"a message\",\"messageTemplate\":\"a messageTemplate\",\"severity\":\"a severity\",\"level\":\"a level\",\"fields\":{\"firstField\":\"a FirstField\",\"secondField\":\"a SecondField\"},\"transaction.id\":\"a transaction.id\",\"trace.id\":\"a trace.id\",\"span.id\":\"a span.id\"}}",
643
+ "payload": "{\"message\":\"hello world\",\"messageTemplate\":\"a messageTemplate\",\"severity\":\"a severity\",\"level\":\"a level\",\"meta\":{\"firstField\":\"a FirstField\",\"secondField\":\"a SecondField\",\"transaction.id\":\"a transaction.id\",\"trace.id\":\"a trace.id\",\"span.id\":\"a span.id\"}}",
650
644
  "payloadType": "json",
651
645
  "x": 130,
652
646
  "y": 120,
@@ -712,7 +706,9 @@
712
706
  "loglevel": "Debug",
713
707
  "x": 300,
714
708
  "y": 360,
715
- "wires": []
709
+ "wires": [
710
+ []
711
+ ]
716
712
  },
717
713
  {
718
714
  "id": "31dcfc340dae3780",
@@ -750,23 +746,5 @@
750
746
  "x": 140,
751
747
  "y": 300,
752
748
  "wires": []
753
- },
754
- {
755
- "id": "cb17b4b12c08ea24",
756
- "type": "OpenTelemetry",
757
- "z": "53b75a173ac5abcc",
758
- "name": "",
759
- "url": "http://apm-server:8200/v1/traces ",
760
- "serviceName": "Node-RED",
761
- "protocol": "proto",
762
- "rootPrefix": "apm",
763
- "timeout": 10,
764
- "ignoredTypes": "debug,catch",
765
- "propagateHeadersTypes": "",
766
- "isLogging": true,
767
- "attributeMappings": [],
768
- "x": 140,
769
- "y": 620,
770
- "wires": []
771
749
  }
772
750
  ]
@@ -2,55 +2,6 @@
2
2
 
3
3
  const winston = require('winston');
4
4
  const winstonElasticSearch = require('winston-elasticsearch');
5
- const { ElasticsearchTransformer } = require('winston-elasticsearch');
6
-
7
- const logLevels = {
8
- levels: {
9
- Error: 0,
10
- Warning: 1,
11
- Information: 2,
12
- Debug: 3
13
- }
14
- };
15
-
16
- function transformElasticFields(logData) {
17
- const transformed = ElasticsearchTransformer(logData);
18
-
19
- transformed['@timestamp'] = logData.timestamp ? logData.timestamp : new Date().toISOString();
20
- transformed.message = logData.message;
21
- transformed.messageTemplate = logData.messageTemplate;
22
- transformed.severity = logData.level;
23
- transformed.level = logData.level;
24
- transformed.fields = logData.meta;
25
-
26
- if (logData.meta['transaction.id']) {
27
- transformed.transaction = { id: logData.meta['transaction.id'] };
28
- }
29
-
30
- if (logData.meta['trace.id']) {
31
- transformed.trace = {
32
- id: logData.meta['trace.id']
33
- };
34
- }
35
-
36
- if (logData.meta['span.id']) {
37
- transformed.span = {
38
- id: logData.meta['span.id']
39
- };
40
- }
41
-
42
- return transformed;
43
- }
44
-
45
- function raiseErrorAndSetNodeStatus(node, message) {
46
- node.error(message, {});
47
- node.status({
48
- fill: 'red',
49
- shape: 'ring',
50
- text: message,
51
- });
52
- }
53
-
54
5
 
55
6
  // TODO: MM winston-elasticsearch/index.js#112 wird die log als async function deklariert,
56
7
  // aber nicht als async aufgerufen
@@ -58,9 +9,26 @@ process.on('unhandledRejection', (reason, promise) => {
58
9
  console.error(`Unhandled Rejection at ${promise} reason: ${reason}`, {});
59
10
  });
60
11
 
61
-
62
12
  module.exports = function (RED) {
63
-
13
+
14
+ const logLevels = {
15
+ levels: {
16
+ Error: 0,
17
+ Warning: 1,
18
+ Information: 2,
19
+ Debug: 3
20
+ }
21
+ };
22
+
23
+ function raiseErrorAndSetNodeStatus(node, message) {
24
+ node.error(message, {});
25
+ node.status({
26
+ fill: 'red',
27
+ shape: 'ring',
28
+ text: message,
29
+ });
30
+ }
31
+
64
32
  function LogElasticLoggerNode(config) {
65
33
  RED.nodes.createNode(this, config);
66
34
  const node = this;
@@ -91,66 +59,39 @@ module.exports = function (RED) {
91
59
  }
92
60
 
93
61
  if (url) {
94
- const transports = [];
95
- const elasticSearchTransport = new winstonElasticSearch.ElasticsearchTransport({
96
- clientOpts: {
97
- node: url,
98
- auth: {
99
- username: user,
100
- password: password,
101
- },
102
- ssl: {
103
- // accept any
104
- rejectUnauthorized: false,
105
- },
106
- },
107
- transformer: (logData) => transformElasticFields(logData),
108
- index: index,
109
- });
62
+ node._url = `${url}/${index}/_doc`;
110
63
 
111
- transports.push(elasticSearchTransport);
64
+ if (user && password) {
65
+ node._credentials = Buffer.from(`${user}:${password}`).toString('base64');
66
+ }
112
67
 
113
- elasticSearchTransport.on('error', (error) => {
114
- raiseErrorAndSetNodeStatus(node, `Error in elasticSearchTransport caught: ${error.message}`);
115
- });
68
+ }
116
69
 
117
- node.logger = new winston.createLogger({
118
- exitOnError: false,
119
- level: 'Debug',
120
- levels: logLevels.levels,
121
- transports: transports,
122
- });
70
+ node.addToLog = async (record) => {
71
+ const headers = {
72
+ 'Content-Type': 'application/json',
73
+ };
74
+
75
+ if (node._credentials) {
76
+ headers.Authorization = `Basic ${node._credentials}`;
77
+ }
123
78
 
124
- node.logger.on('error', (error) => {
125
- raiseErrorAndSetNodeStatus(node, `Error in logger caught: ${error.message}`);
79
+ const response = await fetch(node._url, {
80
+ method: 'POST',
81
+ headers,
82
+ body: JSON.stringify(record),
126
83
  });
127
84
 
128
- this.debug('elastic-search logger created');
129
- }
130
-
85
+ const result = await response.json();
86
+
87
+ return result;
88
+ };
131
89
 
132
90
  this.on('close', function () {
133
- // close logger
134
- if (node.logger) {
135
- node.logger.close();
136
- }
137
-
138
91
  node.debug('elastic-search logger closed');
139
92
  });
140
93
  }
141
94
 
142
- LogElasticLoggerNode.prototype.addToLog = function addTolog(loglevel, msg) {
143
- try {
144
- if (this.logger == null) {
145
- raiseErrorAndSetNodeStatus(this, `Elastic search logger is not initialized: ${JSON.stringify(msg)}`);
146
- } else {
147
- this.logger.log(loglevel, msg.payload.message, msg.payload.meta);
148
- }
149
- } catch (error) {
150
- this.error(error, msg);
151
- }
152
- };
153
-
154
95
  RED.nodes.registerType('elastic-search-logger', LogElasticLoggerNode, {
155
96
  credentials: {
156
97
  username: { type: 'text' },
@@ -17,7 +17,7 @@
17
17
  }
18
18
  },
19
19
  inputs: 1,
20
- outputs: 0,
20
+ outputs: 1,
21
21
  icon: "file.svg",
22
22
  align: "right",
23
23
  label: function () {
@@ -100,15 +100,20 @@
100
100
  </div>
101
101
  </script>
102
102
 
103
- <script type="text/x-red" data-help-name="elastic-search">
104
- <p>A logging node for Elastic Search using the winston and winston-elastic logging libraries</p>
105
- <h3>Details</h3>
106
- <p>Output <code>msg.payload</code> (or <code>msg.&lt;custom path&gt;</code>) or complete <code>msg</code> is used as input of the logged message.</p>
107
- <p>The Log Level (Error, Warning, Information, Debug) used can be configured in the node or can be set
108
- by <code>msg.loglevel</code> (or <code>msg.&lt;custom path&gt;</code>).
109
- If the content is not one of ('Error', 'Warning', 'Information', 'Debug'), 'Debug' will be used as fallback</p>
110
- <p>If <code>msg.meta</code> is set, the meta info Object will be added to the file and ElasticSearch output as a JSON string.</p>
103
+ <script type="text/markdown" data-help-name="elastic-search">
104
+ Sending Data to the Elastic Search.
111
105
 
112
- <h3>References</h3>
113
- <p>This node is based on parts of node-red-contrib-advance-logger</p>
114
- </script>
106
+ ## Inputs
107
+
108
+ : payload (object) : Will mapped to the record for elastic and meta-data are mapped to the key `fields`
109
+
110
+ ## Outputs
111
+
112
+ : payload (string) : The result of the elastic call.
113
+
114
+
115
+ ### References
116
+
117
+ - [The ProcessCube&copy; Developer Network](https://processcube.io) - All documentation for the ProcessCube&copy; platform
118
+ - [ProcessCube&copy; LowCode Integration](https://processcube.io/docs/node-red) - LowCode integration in ProcessCube&copy;
119
+ </script>
package/elastic-search.js CHANGED
@@ -6,11 +6,45 @@ module.exports = function (RED) {
6
6
  const Information = 'Information';
7
7
  const Debug = 'Debug';
8
8
 
9
+ function mapMessage(msg) {
10
+ const transformed = {};
11
+
12
+ transformed['@timestamp'] = msg.payload.timestamp ? msg.timestamp : new Date().toISOString();
13
+ transformed.message = msg.payload.message;
14
+ transformed.messageTemplate = msg.payload.messageTemplate;
15
+ transformed.severity = msg.payload.level;
16
+ transformed.level = msg.payload.level;
17
+ let meta = msg.payload.meta;
18
+
19
+ if (meta['transaction.id']) {
20
+ transformed.transaction = { id: meta['transaction.id'] };
21
+
22
+ delete meta['transaction.id'];
23
+ }
24
+
25
+ if (msg.payload.meta['trace.id']) {
26
+ transformed.trace = { id: meta['trace.id'] };
27
+
28
+ delete meta['trace.id'];
29
+ }
30
+
31
+ if (msg.payload.meta['span.id']) {
32
+ transformed.span = { id: meta['span.id'] };
33
+
34
+ delete meta['span.id'];
35
+ }
36
+
37
+ transformed.fields = meta;
38
+
39
+ return transformed;
40
+ }
41
+
42
+
9
43
  function LogElasticNode(config) {
10
44
  RED.nodes.createNode(this, config);
11
45
  const node = this;
12
46
 
13
- this.on('input', function (msg) {
47
+ this.on('input', async function (msg) {
14
48
  node.logger = RED.nodes.getNode(config.logger);
15
49
 
16
50
  let loglevel = config.loglevel || '';
@@ -35,7 +69,14 @@ module.exports = function (RED) {
35
69
  }
36
70
 
37
71
  try {
38
- node.logger.addToLog(level, msg);
72
+
73
+ const mappedMessage = mapMessage(msg);
74
+
75
+ const result = await node.logger.addToLog(mappedMessage);
76
+
77
+ msg.payload = result;
78
+
79
+ node.send(msg);
39
80
  } catch (err) {
40
81
  node.error(err);
41
82
  }
@@ -0,0 +1,222 @@
1
+ [
2
+ {
3
+ "id": "53b75a173ac5abcc",
4
+ "type": "tab",
5
+ "label": "Elasticsearch loggen",
6
+ "disabled": false,
7
+ "info": "",
8
+ "env": []
9
+ },
10
+ {
11
+ "id": "38edcaecf5968ff5",
12
+ "type": "group",
13
+ "z": "53b75a173ac5abcc",
14
+ "style": {
15
+ "stroke": "#999999",
16
+ "stroke-opacity": "1",
17
+ "fill": "none",
18
+ "fill-opacity": "1",
19
+ "label": true,
20
+ "label-position": "nw",
21
+ "color": "#a4a4a4"
22
+ },
23
+ "nodes": [
24
+ "0b2f670fec931f5f",
25
+ "443b329ab591c4dd",
26
+ "f4a0d7de5d04c121",
27
+ "946add545fa1db9f",
28
+ "0c15060915aac994"
29
+ ],
30
+ "x": 34,
31
+ "y": 19,
32
+ "w": 372,
33
+ "h": 202
34
+ },
35
+ {
36
+ "id": "4aae454884faa826",
37
+ "type": "group",
38
+ "z": "53b75a173ac5abcc",
39
+ "style": {
40
+ "stroke": "#999999",
41
+ "stroke-opacity": "1",
42
+ "fill": "none",
43
+ "fill-opacity": "1",
44
+ "label": true,
45
+ "label-position": "nw",
46
+ "color": "#a4a4a4"
47
+ },
48
+ "nodes": [
49
+ "f90f2ba54f023834",
50
+ "31dcfc340dae3780",
51
+ "59df2485b6c11412"
52
+ ],
53
+ "x": 34,
54
+ "y": 259,
55
+ "w": 372,
56
+ "h": 142
57
+ },
58
+ {
59
+ "id": "0b2f670fec931f5f",
60
+ "type": "elastic-search",
61
+ "z": "53b75a173ac5abcc",
62
+ "g": "38edcaecf5968ff5",
63
+ "name": "",
64
+ "logger": "e8672d361683672d",
65
+ "complete": "payload",
66
+ "loglevel": "Debug",
67
+ "x": 300,
68
+ "y": 120,
69
+ "wires": [
70
+ []
71
+ ]
72
+ },
73
+ {
74
+ "id": "443b329ab591c4dd",
75
+ "type": "inject",
76
+ "z": "53b75a173ac5abcc",
77
+ "g": "38edcaecf5968ff5",
78
+ "name": "",
79
+ "props": [
80
+ {
81
+ "p": "payload"
82
+ }
83
+ ],
84
+ "repeat": "",
85
+ "crontab": "",
86
+ "once": false,
87
+ "onceDelay": 0.1,
88
+ "topic": "",
89
+ "payload": "{\"message\":\"hello world\",\"messageTemplate\":\"a messageTemplate\",\"severity\":\"a severity\",\"level\":\"a level\",\"meta\":{\"firstField\":\"a FirstField\",\"secondField\":\"a SecondField\",\"transaction.id\":\"a transaction.id\",\"trace.id\":\"a trace.id\",\"span.id\":\"a span.id\"}}",
90
+ "payloadType": "json",
91
+ "x": 130,
92
+ "y": 120,
93
+ "wires": [
94
+ [
95
+ "0b2f670fec931f5f"
96
+ ]
97
+ ]
98
+ },
99
+ {
100
+ "id": "f4a0d7de5d04c121",
101
+ "type": "comment",
102
+ "z": "53b75a173ac5abcc",
103
+ "g": "38edcaecf5968ff5",
104
+ "name": "Handle log",
105
+ "info": "",
106
+ "x": 120,
107
+ "y": 60,
108
+ "wires": []
109
+ },
110
+ {
111
+ "id": "946add545fa1db9f",
112
+ "type": "catch",
113
+ "z": "53b75a173ac5abcc",
114
+ "g": "38edcaecf5968ff5",
115
+ "name": "",
116
+ "scope": null,
117
+ "uncaught": false,
118
+ "x": 120,
119
+ "y": 180,
120
+ "wires": [
121
+ [
122
+ "0c15060915aac994"
123
+ ]
124
+ ]
125
+ },
126
+ {
127
+ "id": "0c15060915aac994",
128
+ "type": "debug",
129
+ "z": "53b75a173ac5abcc",
130
+ "g": "38edcaecf5968ff5",
131
+ "name": "error",
132
+ "active": true,
133
+ "tosidebar": true,
134
+ "console": false,
135
+ "tostatus": false,
136
+ "complete": "true",
137
+ "targetType": "full",
138
+ "statusVal": "",
139
+ "statusType": "auto",
140
+ "x": 270,
141
+ "y": 180,
142
+ "wires": []
143
+ },
144
+ {
145
+ "id": "f90f2ba54f023834",
146
+ "type": "elastic-search",
147
+ "z": "53b75a173ac5abcc",
148
+ "g": "4aae454884faa826",
149
+ "name": "",
150
+ "logger": "3667972f5cb77061",
151
+ "complete": "payload",
152
+ "loglevel": "Debug",
153
+ "x": 300,
154
+ "y": 360,
155
+ "wires": [
156
+ []
157
+ ]
158
+ },
159
+ {
160
+ "id": "31dcfc340dae3780",
161
+ "type": "inject",
162
+ "z": "53b75a173ac5abcc",
163
+ "g": "4aae454884faa826",
164
+ "name": "",
165
+ "props": [
166
+ {
167
+ "p": "payload"
168
+ }
169
+ ],
170
+ "repeat": "",
171
+ "crontab": "",
172
+ "once": false,
173
+ "onceDelay": 0.1,
174
+ "topic": "",
175
+ "payload": "{\"message\":\"hello world\"}",
176
+ "payloadType": "json",
177
+ "x": 130,
178
+ "y": 360,
179
+ "wires": [
180
+ [
181
+ "f90f2ba54f023834"
182
+ ]
183
+ ]
184
+ },
185
+ {
186
+ "id": "59df2485b6c11412",
187
+ "type": "comment",
188
+ "z": "53b75a173ac5abcc",
189
+ "g": "4aae454884faa826",
190
+ "name": "Handle failed log",
191
+ "info": "",
192
+ "x": 140,
193
+ "y": 300,
194
+ "wires": []
195
+ },
196
+ {
197
+ "id": "e8672d361683672d",
198
+ "type": "elastic-search-logger",
199
+ "name": "Docker compose",
200
+ "url": "http://elasticsearch:9200",
201
+ "urlType": "str",
202
+ "usernameType": "str",
203
+ "passwordType": "str",
204
+ "indexType": "str",
205
+ "filename": "log-elastic.log",
206
+ "maxsize": 1,
207
+ "maxfiles": 2
208
+ },
209
+ {
210
+ "id": "3667972f5cb77061",
211
+ "type": "elastic-search-logger",
212
+ "name": "Failed docker compose",
213
+ "url": "",
214
+ "urlType": "str",
215
+ "usernameType": "str",
216
+ "passwordType": "str",
217
+ "indexType": "str",
218
+ "filename": "log-elastic.log",
219
+ "maxsize": 1,
220
+ "maxfiles": 2
221
+ }
222
+ ]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@5minds/node-red-contrib-processcube-elasticsearch",
3
- "version": "0.4.0-feature-d4edf3-m6cmuwqg",
3
+ "version": "1.0.0-develop-31b02f-m6dsjh20",
4
4
  "license": "MIT",
5
5
  "description": "Node-RED nodes for Elasticsearch",
6
6
  "scripts": {
@@ -36,10 +36,6 @@
36
36
  },
37
37
  "examples": "examples"
38
38
  },
39
- "dependencies": {
40
- "winston": "^3.17.0",
41
- "winston-elasticsearch": "^0.19.0"
42
- },
43
39
  "keywords": [
44
40
  "node-red",
45
41
  "processcube",