@5minds/node-red-contrib-processcube-elasticsearch 0.3.3-feature-056883-m66btl04 → 0.4.0-develop-7b8fdf-m692xvm9
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/.processcube/nodered/.config.nodes.json +1 -1
- package/.processcube/nodered/config.js +7 -0
- package/.processcube/nodered/flows.json +162 -4
- package/.processcube/nodered/flows_cred.json +1 -1
- package/elastic-search-logger.js +109 -64
- package/elastic-search.js +6 -4
- package/package.json +6 -2
- package/.processcube/nodered/.config.nodes.json.backup +0 -774
- package/.processcube/nodered/.config.runtime.json.backup +0 -4
- package/.processcube/nodered/.config.users.json.backup +0 -35
- package/.processcube/nodered/.flows.json.backup +0 -566
- package/.processcube/nodered/.flows_cred.json.backup +0 -3
- package/.processcube/nodered/node-red-contrib-processcube-flows.json +0 -0
|
@@ -9,5 +9,12 @@ try {
|
|
|
9
9
|
console.log(">>>", e);
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
+
process.on('uncaughtException', (err) => {
|
|
13
|
+
console.error(`Uncaught Exception: ${err}`, {});
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
process.on('unhandledRejection', (reason, promise) => {
|
|
17
|
+
console.error(`Unhandled Rejection at ${promise} reason: ${reason}`, {});
|
|
18
|
+
});
|
|
12
19
|
|
|
13
20
|
module.exports = config;
|
|
@@ -135,6 +135,54 @@
|
|
|
135
135
|
"w": 532,
|
|
136
136
|
"h": 142
|
|
137
137
|
},
|
|
138
|
+
{
|
|
139
|
+
"id": "38edcaecf5968ff5",
|
|
140
|
+
"type": "group",
|
|
141
|
+
"z": "53b75a173ac5abcc",
|
|
142
|
+
"style": {
|
|
143
|
+
"stroke": "#999999",
|
|
144
|
+
"stroke-opacity": "1",
|
|
145
|
+
"fill": "none",
|
|
146
|
+
"fill-opacity": "1",
|
|
147
|
+
"label": true,
|
|
148
|
+
"label-position": "nw",
|
|
149
|
+
"color": "#a4a4a4"
|
|
150
|
+
},
|
|
151
|
+
"nodes": [
|
|
152
|
+
"0b2f670fec931f5f",
|
|
153
|
+
"443b329ab591c4dd",
|
|
154
|
+
"f4a0d7de5d04c121",
|
|
155
|
+
"946add545fa1db9f",
|
|
156
|
+
"0c15060915aac994"
|
|
157
|
+
],
|
|
158
|
+
"x": 34,
|
|
159
|
+
"y": 19,
|
|
160
|
+
"w": 372,
|
|
161
|
+
"h": 202
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
"id": "4aae454884faa826",
|
|
165
|
+
"type": "group",
|
|
166
|
+
"z": "53b75a173ac5abcc",
|
|
167
|
+
"style": {
|
|
168
|
+
"stroke": "#999999",
|
|
169
|
+
"stroke-opacity": "1",
|
|
170
|
+
"fill": "none",
|
|
171
|
+
"fill-opacity": "1",
|
|
172
|
+
"label": true,
|
|
173
|
+
"label-position": "nw",
|
|
174
|
+
"color": "#a4a4a4"
|
|
175
|
+
},
|
|
176
|
+
"nodes": [
|
|
177
|
+
"f90f2ba54f023834",
|
|
178
|
+
"31dcfc340dae3780",
|
|
179
|
+
"59df2485b6c11412"
|
|
180
|
+
],
|
|
181
|
+
"x": 34,
|
|
182
|
+
"y": 259,
|
|
183
|
+
"w": 372,
|
|
184
|
+
"h": 142
|
|
185
|
+
},
|
|
138
186
|
{
|
|
139
187
|
"id": "e8672d361683672d",
|
|
140
188
|
"type": "elastic-search-logger",
|
|
@@ -148,6 +196,19 @@
|
|
|
148
196
|
"maxsize": 1,
|
|
149
197
|
"maxfiles": 2
|
|
150
198
|
},
|
|
199
|
+
{
|
|
200
|
+
"id": "3667972f5cb77061",
|
|
201
|
+
"type": "elastic-search-logger",
|
|
202
|
+
"name": "Failed docker compose",
|
|
203
|
+
"url": "",
|
|
204
|
+
"urlType": "str",
|
|
205
|
+
"usernameType": "str",
|
|
206
|
+
"passwordType": "str",
|
|
207
|
+
"indexType": "str",
|
|
208
|
+
"filename": "log-elastic.log",
|
|
209
|
+
"maxsize": 1,
|
|
210
|
+
"maxfiles": 2
|
|
211
|
+
},
|
|
151
212
|
{
|
|
152
213
|
"id": "95fa4d376d072354",
|
|
153
214
|
"type": "http request",
|
|
@@ -530,18 +591,20 @@
|
|
|
530
591
|
"id": "0b2f670fec931f5f",
|
|
531
592
|
"type": "elastic-search",
|
|
532
593
|
"z": "53b75a173ac5abcc",
|
|
594
|
+
"g": "38edcaecf5968ff5",
|
|
533
595
|
"name": "",
|
|
534
596
|
"logger": "e8672d361683672d",
|
|
535
597
|
"complete": "payload",
|
|
536
598
|
"loglevel": "Debug",
|
|
537
|
-
"x":
|
|
538
|
-
"y":
|
|
599
|
+
"x": 300,
|
|
600
|
+
"y": 120,
|
|
539
601
|
"wires": []
|
|
540
602
|
},
|
|
541
603
|
{
|
|
542
604
|
"id": "443b329ab591c4dd",
|
|
543
605
|
"type": "inject",
|
|
544
606
|
"z": "53b75a173ac5abcc",
|
|
607
|
+
"g": "38edcaecf5968ff5",
|
|
545
608
|
"name": "",
|
|
546
609
|
"props": [
|
|
547
610
|
{
|
|
@@ -553,14 +616,109 @@
|
|
|
553
616
|
"once": false,
|
|
554
617
|
"onceDelay": 0.1,
|
|
555
618
|
"topic": "",
|
|
556
|
-
"payload": "{\"message\":\"hello world\"}",
|
|
619
|
+
"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\"}}",
|
|
557
620
|
"payloadType": "json",
|
|
558
621
|
"x": 130,
|
|
559
|
-
"y":
|
|
622
|
+
"y": 120,
|
|
560
623
|
"wires": [
|
|
561
624
|
[
|
|
562
625
|
"0b2f670fec931f5f"
|
|
563
626
|
]
|
|
564
627
|
]
|
|
628
|
+
},
|
|
629
|
+
{
|
|
630
|
+
"id": "f4a0d7de5d04c121",
|
|
631
|
+
"type": "comment",
|
|
632
|
+
"z": "53b75a173ac5abcc",
|
|
633
|
+
"g": "38edcaecf5968ff5",
|
|
634
|
+
"name": "Handle log",
|
|
635
|
+
"info": "",
|
|
636
|
+
"x": 120,
|
|
637
|
+
"y": 60,
|
|
638
|
+
"wires": []
|
|
639
|
+
},
|
|
640
|
+
{
|
|
641
|
+
"id": "946add545fa1db9f",
|
|
642
|
+
"type": "catch",
|
|
643
|
+
"z": "53b75a173ac5abcc",
|
|
644
|
+
"g": "38edcaecf5968ff5",
|
|
645
|
+
"name": "",
|
|
646
|
+
"scope": null,
|
|
647
|
+
"uncaught": false,
|
|
648
|
+
"x": 120,
|
|
649
|
+
"y": 180,
|
|
650
|
+
"wires": [
|
|
651
|
+
[
|
|
652
|
+
"0c15060915aac994"
|
|
653
|
+
]
|
|
654
|
+
]
|
|
655
|
+
},
|
|
656
|
+
{
|
|
657
|
+
"id": "0c15060915aac994",
|
|
658
|
+
"type": "debug",
|
|
659
|
+
"z": "53b75a173ac5abcc",
|
|
660
|
+
"g": "38edcaecf5968ff5",
|
|
661
|
+
"name": "error",
|
|
662
|
+
"active": true,
|
|
663
|
+
"tosidebar": true,
|
|
664
|
+
"console": false,
|
|
665
|
+
"tostatus": false,
|
|
666
|
+
"complete": "true",
|
|
667
|
+
"targetType": "full",
|
|
668
|
+
"statusVal": "",
|
|
669
|
+
"statusType": "auto",
|
|
670
|
+
"x": 270,
|
|
671
|
+
"y": 180,
|
|
672
|
+
"wires": []
|
|
673
|
+
},
|
|
674
|
+
{
|
|
675
|
+
"id": "f90f2ba54f023834",
|
|
676
|
+
"type": "elastic-search",
|
|
677
|
+
"z": "53b75a173ac5abcc",
|
|
678
|
+
"g": "4aae454884faa826",
|
|
679
|
+
"name": "",
|
|
680
|
+
"logger": "3667972f5cb77061",
|
|
681
|
+
"complete": "payload",
|
|
682
|
+
"loglevel": "Debug",
|
|
683
|
+
"x": 300,
|
|
684
|
+
"y": 360,
|
|
685
|
+
"wires": []
|
|
686
|
+
},
|
|
687
|
+
{
|
|
688
|
+
"id": "31dcfc340dae3780",
|
|
689
|
+
"type": "inject",
|
|
690
|
+
"z": "53b75a173ac5abcc",
|
|
691
|
+
"g": "4aae454884faa826",
|
|
692
|
+
"name": "",
|
|
693
|
+
"props": [
|
|
694
|
+
{
|
|
695
|
+
"p": "payload"
|
|
696
|
+
}
|
|
697
|
+
],
|
|
698
|
+
"repeat": "",
|
|
699
|
+
"crontab": "",
|
|
700
|
+
"once": false,
|
|
701
|
+
"onceDelay": 0.1,
|
|
702
|
+
"topic": "",
|
|
703
|
+
"payload": "{\"message\":\"hello world\"}",
|
|
704
|
+
"payloadType": "json",
|
|
705
|
+
"x": 130,
|
|
706
|
+
"y": 360,
|
|
707
|
+
"wires": [
|
|
708
|
+
[
|
|
709
|
+
"f90f2ba54f023834"
|
|
710
|
+
]
|
|
711
|
+
]
|
|
712
|
+
},
|
|
713
|
+
{
|
|
714
|
+
"id": "59df2485b6c11412",
|
|
715
|
+
"type": "comment",
|
|
716
|
+
"z": "53b75a173ac5abcc",
|
|
717
|
+
"g": "4aae454884faa826",
|
|
718
|
+
"name": "Handle failed log",
|
|
719
|
+
"info": "",
|
|
720
|
+
"x": 140,
|
|
721
|
+
"y": 300,
|
|
722
|
+
"wires": []
|
|
565
723
|
}
|
|
566
724
|
]
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
{
|
|
2
|
-
"$": "
|
|
2
|
+
"$": "69c2a3b18186363d4e5849655756e7349gcyp66cMJ2/lgr6ulxmCSArRIQWk2T3HrJ7yfqDFqO7OXOON2aVmPkkjsW0asmrmrja7buybbECE8+uj2QSR3m8ncp/9umm9nM//dgBrCOkpiQ62Rg2vlDYw8PcUvEaNuGm0040d1swspl21P6mqXwGp57SOBpTz/U6MPLQTixR4IWCxUl5euN6kJNUnXYXoAbW5nnx/Q=="
|
|
3
3
|
}
|
package/elastic-search-logger.js
CHANGED
|
@@ -1,37 +1,97 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const winston = require('winston');
|
|
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
|
+
|
|
55
|
+
// TODO: MM winston-elasticsearch/index.js#112 wird die log als async function deklariert,
|
|
56
|
+
// aber nicht als async aufgerufen
|
|
57
|
+
process.on('unhandledRejection', (reason, promise) => {
|
|
58
|
+
console.error(`Unhandled Rejection at ${promise} reason: ${reason}`, {});
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
|
|
1
62
|
module.exports = function (RED) {
|
|
2
|
-
'use strict';
|
|
3
63
|
|
|
4
64
|
function LogElasticLoggerNode(config) {
|
|
5
|
-
let winston = require('winston');
|
|
6
|
-
let winstonElasticSearch = require('winston-elasticsearch');
|
|
7
|
-
|
|
8
65
|
RED.nodes.createNode(this, config);
|
|
9
|
-
|
|
10
|
-
|
|
66
|
+
const node = this;
|
|
67
|
+
|
|
68
|
+
node.logger = null;
|
|
11
69
|
|
|
12
70
|
// Elastic settings
|
|
13
|
-
|
|
14
|
-
if (url
|
|
15
|
-
|
|
71
|
+
const url = RED.util.evaluateNodeProperty(config.url, config.urlType, node);
|
|
72
|
+
if (!url || url === 'undefined') {
|
|
73
|
+
raiseErrorAndSetNodeStatus(node, 'Elastic search url is not set');
|
|
16
74
|
}
|
|
17
75
|
|
|
18
|
-
|
|
19
|
-
if (user
|
|
20
|
-
|
|
76
|
+
const user = RED.util.evaluateNodeProperty(this.credentials.username, config.usernameType, node);
|
|
77
|
+
if (!user || user === 'undefined') {
|
|
78
|
+
raiseErrorAndSetNodeStatus(node, 'Elastic search username is not set');
|
|
21
79
|
}
|
|
22
80
|
|
|
23
|
-
|
|
24
|
-
if (password
|
|
25
|
-
|
|
81
|
+
const password = RED.util.evaluateNodeProperty(this.credentials.password, config.passwordType, node);
|
|
82
|
+
if (!password || password === 'undefined') {
|
|
83
|
+
raiseErrorAndSetNodeStatus(node, 'Elastic search password is not set');
|
|
26
84
|
}
|
|
27
85
|
|
|
28
|
-
let index = RED.util.evaluateNodeProperty(this.credentials.index, config.indexType,
|
|
29
|
-
if (index
|
|
30
|
-
|
|
86
|
+
let index = RED.util.evaluateNodeProperty(this.credentials.index, config.indexType, node);
|
|
87
|
+
if (!index || index === 'undefined') {
|
|
88
|
+
raiseErrorAndSetNodeStatus(node, 'Elastic search index is not set');
|
|
89
|
+
} else {
|
|
90
|
+
index = index.toLowerCase();
|
|
31
91
|
}
|
|
32
92
|
|
|
33
|
-
index = index.toLowerCase();
|
|
34
93
|
if (url) {
|
|
94
|
+
const transports = [];
|
|
35
95
|
const elasticSearchTransport = new winstonElasticSearch.ElasticsearchTransport({
|
|
36
96
|
clientOpts: {
|
|
37
97
|
node: url,
|
|
@@ -44,63 +104,52 @@ module.exports = function (RED) {
|
|
|
44
104
|
rejectUnauthorized: false,
|
|
45
105
|
},
|
|
46
106
|
},
|
|
47
|
-
transformer: (logData) =>
|
|
107
|
+
transformer: (logData) => transformElasticFields(logData),
|
|
48
108
|
index: index,
|
|
49
109
|
});
|
|
50
110
|
|
|
51
111
|
transports.push(elasticSearchTransport);
|
|
52
112
|
|
|
53
113
|
elasticSearchTransport.on('error', (error) => {
|
|
54
|
-
|
|
55
|
-
console.error('Error in elasticSearchTransport caught', error);
|
|
114
|
+
raiseErrorAndSetNodeStatus(node, `Error in elasticSearchTransport caught: ${error.message}`);
|
|
56
115
|
});
|
|
57
|
-
}
|
|
58
116
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
});
|
|
117
|
+
node.logger = new winston.createLogger({
|
|
118
|
+
exitOnError: false,
|
|
119
|
+
level: 'Debug',
|
|
120
|
+
levels: logLevels.levels,
|
|
121
|
+
transports: transports,
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
node.logger.on('error', (error) => {
|
|
125
|
+
raiseErrorAndSetNodeStatus(node, `Error in logger caught: ${error.message}`);
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
this.debug('elastic-search logger created');
|
|
129
|
+
}
|
|
73
130
|
|
|
74
|
-
this.debug('elastic-search logger created');
|
|
75
131
|
|
|
76
|
-
this.on('close', function (
|
|
132
|
+
this.on('close', function () {
|
|
77
133
|
// close logger
|
|
78
|
-
if (
|
|
79
|
-
|
|
134
|
+
if (node.logger) {
|
|
135
|
+
node.logger.close();
|
|
80
136
|
}
|
|
81
137
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
if (done) done();
|
|
138
|
+
node.debug('elastic-search logger closed');
|
|
85
139
|
});
|
|
86
140
|
}
|
|
87
141
|
|
|
88
|
-
function
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
if (logData.meta['trace.id']) transformed.trace = { id: logData.meta['trace.id'] };
|
|
100
|
-
if (logData.meta['span.id']) transformed.span = { id: logData.meta['span.id'] };
|
|
101
|
-
|
|
102
|
-
return transformed;
|
|
103
|
-
}
|
|
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
|
+
};
|
|
104
153
|
|
|
105
154
|
RED.nodes.registerType('elastic-search-logger', LogElasticLoggerNode, {
|
|
106
155
|
credentials: {
|
|
@@ -109,8 +158,4 @@ module.exports = function (RED) {
|
|
|
109
158
|
index: { type: 'text' },
|
|
110
159
|
},
|
|
111
160
|
});
|
|
112
|
-
|
|
113
|
-
LogElasticLoggerNode.prototype.addToLog = function addTolog(loglevel, msg) {
|
|
114
|
-
this.logger.log(loglevel, msg.payload.message, msg.payload.meta);
|
|
115
|
-
};
|
|
116
161
|
};
|
package/elastic-search.js
CHANGED
|
@@ -10,7 +10,7 @@ module.exports = function (RED) {
|
|
|
10
10
|
RED.nodes.createNode(this, config);
|
|
11
11
|
const node = this;
|
|
12
12
|
|
|
13
|
-
this.on('input', function (msg
|
|
13
|
+
this.on('input', function (msg) {
|
|
14
14
|
node.logger = RED.nodes.getNode(config.logger);
|
|
15
15
|
|
|
16
16
|
let loglevel = config.loglevel || '';
|
|
@@ -34,10 +34,12 @@ module.exports = function (RED) {
|
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
try {
|
|
38
|
+
node.logger.addToLog(level, msg);
|
|
39
|
+
} catch (err) {
|
|
40
|
+
node.error(err);
|
|
41
|
+
}
|
|
38
42
|
}
|
|
39
|
-
|
|
40
|
-
if (done) done();
|
|
41
43
|
});
|
|
42
44
|
}
|
|
43
45
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@5minds/node-red-contrib-processcube-elasticsearch",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0-develop-7b8fdf-m692xvm9",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Node-RED nodes for Elasticsearch",
|
|
6
6
|
"scripts": {
|
|
@@ -10,6 +10,10 @@
|
|
|
10
10
|
{
|
|
11
11
|
"name": "Robin Lenz",
|
|
12
12
|
"email": "Robin.Lenz@5Minds.de"
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"name": "Martin Möllenbeck",
|
|
16
|
+
"email": "martin.moellenbeck@5Minds.de"
|
|
13
17
|
}
|
|
14
18
|
],
|
|
15
19
|
"repository": {
|
|
@@ -25,7 +29,7 @@
|
|
|
25
29
|
"npm": ">=8.0.0"
|
|
26
30
|
},
|
|
27
31
|
"node-red": {
|
|
28
|
-
"version": ">=
|
|
32
|
+
"version": ">=4.0.0",
|
|
29
33
|
"nodes": {
|
|
30
34
|
"elastic-search": "elastic-search.js",
|
|
31
35
|
"elastic-search-logger": "elastic-search-logger.js"
|