@alertlogic/al-collector-js 2.0.3 → 3.0.1
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/.travis.yml +1 -1
- package/al_log.js +113 -50
- package/al_log_filter.js +117 -0
- package/package.json +4 -1
- package/test/al_log_filter_test.js +159 -0
- package/test/al_log_test.js +126 -5
- package/test/azcollectc_test.js +0 -1
package/.travis.yml
CHANGED
package/al_log.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* @doc
|
|
4
4
|
*
|
|
5
5
|
* Helper utilities for Alert Logic log collector.
|
|
6
|
+
* NOTE: parameters to all functions are passed as (object, callback)
|
|
6
7
|
*
|
|
7
8
|
* @end
|
|
8
9
|
* -----------------------------------------------------------------------------
|
|
@@ -11,6 +12,7 @@ const crypto = require('crypto');
|
|
|
11
12
|
const async = require('async');
|
|
12
13
|
const zlib = require('zlib');
|
|
13
14
|
|
|
15
|
+
const alLogFilter = require('./al_log_filter');
|
|
14
16
|
const alcHealthPb = require('./proto/alc_health.piqi_pb').alc_health;
|
|
15
17
|
const commonProtoPb = require('./proto/common_proto.piqi_pb').common_proto;
|
|
16
18
|
const dictPb = require('./proto/dict.piqi_pb').alc_dict;
|
|
@@ -50,6 +52,11 @@ const PAYLOAD_BATCH_SIZE = 10000000;
|
|
|
50
52
|
* applicationId: 'o365'
|
|
51
53
|
* };
|
|
52
54
|
* Consult 'collected_message' definition in proto/common_proto.piqi.proto
|
|
55
|
+
* @param filterJson - JSON parsed object representing key-value pairs which
|
|
56
|
+
* should exist in a message. For example, {type: 'Security', category: 'Admin'}.
|
|
57
|
+
* NOTE: do NOT use json filter if 'content' is an array of strings.
|
|
58
|
+
* @param filterRegexp - regexp object filter. If content messages are JSON object
|
|
59
|
+
* then regexp filter if applied to a stringified message value.
|
|
53
60
|
* @param callback
|
|
54
61
|
*
|
|
55
62
|
* @return callback - (error, builtPayload, payloadSize)
|
|
@@ -58,46 +65,69 @@ const PAYLOAD_BATCH_SIZE = 10000000;
|
|
|
58
65
|
* For an AWS Lambda via kinesis trigger batch size configuration.
|
|
59
66
|
*/
|
|
60
67
|
|
|
61
|
-
var buildPayload = function (hostId, sourceId, hostmetaElems, content, parseCallback, mainCallback) {
|
|
68
|
+
var buildPayload = function ({hostId, sourceId, hostmetaElems, content, parseCallback, filterJson, filterRegexp}, mainCallback) {
|
|
62
69
|
async.waterfall([
|
|
63
70
|
function(callback) {
|
|
64
|
-
|
|
71
|
+
const params = {
|
|
72
|
+
content: content,
|
|
73
|
+
parseContentFun: parseCallback,
|
|
74
|
+
filterJson: filterJson,
|
|
75
|
+
filterRegexp: filterRegexp
|
|
76
|
+
};
|
|
77
|
+
buildMessages(params, function(err, msg) {
|
|
65
78
|
return callback(err, msg);
|
|
66
79
|
});
|
|
67
80
|
},
|
|
68
81
|
function(msg, callback) {
|
|
69
|
-
|
|
82
|
+
const params = {
|
|
83
|
+
hostId: hostId,
|
|
84
|
+
hostmetaElems: hostmetaElems
|
|
85
|
+
};
|
|
86
|
+
buildHostmeta(params, function(err, meta) {
|
|
70
87
|
return callback(err, meta, msg);
|
|
71
88
|
});
|
|
72
89
|
},
|
|
73
90
|
function(meta, msg, callback) {
|
|
74
|
-
|
|
75
|
-
|
|
91
|
+
const params = {
|
|
92
|
+
sId: sourceId,
|
|
93
|
+
metadata: meta,
|
|
94
|
+
messages:msg
|
|
95
|
+
};
|
|
96
|
+
buildBatch(params, function(err, batch) {
|
|
97
|
+
return callback(err, batch, msg);
|
|
76
98
|
});
|
|
77
99
|
},
|
|
78
|
-
function(batchBuf, callback) {
|
|
79
|
-
|
|
80
|
-
|
|
100
|
+
function(batchBuf, msg, callback) {
|
|
101
|
+
const params = {
|
|
102
|
+
batches: batchBuf
|
|
103
|
+
};
|
|
104
|
+
buildBatchList(params, function(err, batchList) {
|
|
105
|
+
return callback(err, batchList, msg);
|
|
81
106
|
});
|
|
82
107
|
},
|
|
83
|
-
function(batchList, callback) {
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
return callback(null, buf);
|
|
108
|
+
function(batchList, msg, callback) {
|
|
109
|
+
let batchListType = commonProtoPb.collected_batch_list;
|
|
110
|
+
let buf = batchListType.encode(batchList).finish();
|
|
111
|
+
return callback(null, buf, msg);
|
|
87
112
|
}],
|
|
88
|
-
function(err, result) {
|
|
113
|
+
function (err, result, msg) {
|
|
89
114
|
if (err) {
|
|
90
115
|
return mainCallback(err);
|
|
91
116
|
} else {
|
|
117
|
+
// calculate the actual collected messages byte size
|
|
118
|
+
let collectedMessageBytes = 0;
|
|
119
|
+
msg.map(eachMessage => {
|
|
120
|
+
collectedMessageBytes += eachMessage.messageLength;
|
|
121
|
+
});
|
|
92
122
|
zlib.deflate(result, function(defalteErr, compressed) {
|
|
93
123
|
if (defalteErr) {
|
|
94
124
|
return mainCallback(defalteErr);
|
|
95
125
|
} else {
|
|
96
|
-
|
|
126
|
+
let payloadSize = compressed.byteLength;
|
|
97
127
|
if (payloadSize > PAYLOAD_BATCH_SIZE) {
|
|
98
128
|
return mainCallback(`Maximum payload size exceeded: ${payloadSize}`, compressed);
|
|
99
129
|
} else {
|
|
100
|
-
return mainCallback(null, compressed);
|
|
130
|
+
return mainCallback(null, { payload: compressed, payload_size: payloadSize, raw_count: msg.length, raw_bytes: collectedMessageBytes });
|
|
101
131
|
}
|
|
102
132
|
}
|
|
103
133
|
});
|
|
@@ -111,14 +141,12 @@ var buildPayload = function (hostId, sourceId, hostmetaElems, content, parseCall
|
|
|
111
141
|
*
|
|
112
142
|
*/
|
|
113
143
|
|
|
114
|
-
function buildType(type, payload, callback) {
|
|
115
|
-
|
|
144
|
+
function buildType({type, payload}, callback) {
|
|
145
|
+
let verify = type.verify(payload);
|
|
116
146
|
if (verify)
|
|
117
147
|
return callback(verify);
|
|
118
148
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
return callback(null, payloadCreated);
|
|
149
|
+
return callback(null, type.create(payload));
|
|
122
150
|
}
|
|
123
151
|
|
|
124
152
|
/**
|
|
@@ -140,32 +168,41 @@ function buildType(type, payload, callback) {
|
|
|
140
168
|
* @returns callback
|
|
141
169
|
*/
|
|
142
170
|
|
|
143
|
-
function buildHostmeta(hostId, hostmetaElems, callback) {
|
|
144
|
-
|
|
145
|
-
|
|
171
|
+
function buildHostmeta({hostId, hostmetaElems}, callback) {
|
|
172
|
+
let hostmetaType = hostMetadataPb.metadata;
|
|
173
|
+
let hostmeta = {
|
|
146
174
|
elem : hostmetaElems
|
|
147
175
|
};
|
|
148
|
-
|
|
176
|
+
const paramsDict = {
|
|
177
|
+
type: dictPb.dict,
|
|
178
|
+
payload: hostmeta
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
buildType(paramsDict, function(err, hostmetaData){
|
|
149
182
|
if (err) {
|
|
150
183
|
return callback(err);
|
|
151
184
|
} else {
|
|
152
|
-
|
|
185
|
+
let meta = {
|
|
153
186
|
hostUuid : hostId,
|
|
154
187
|
data : hostmetaData,
|
|
155
188
|
dataChecksum : new Buffer('')
|
|
156
189
|
};
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
190
|
+
let sha = crypto.createHash('sha1');
|
|
191
|
+
let hashPayload = hostmetaType.encode(meta).finish();
|
|
192
|
+
let hashValue = sha.update(hashPayload).digest();
|
|
160
193
|
|
|
161
|
-
|
|
194
|
+
let metadataPayload = {
|
|
162
195
|
hostUuid : hostId,
|
|
163
196
|
dataChecksum : hashValue,
|
|
164
197
|
timestamp : Math.floor(Date.now() / 1000),
|
|
165
198
|
data : hostmetaData
|
|
166
199
|
};
|
|
167
200
|
|
|
168
|
-
|
|
201
|
+
const paramsHostmeta = {
|
|
202
|
+
type: hostmetaType,
|
|
203
|
+
payload: metadataPayload
|
|
204
|
+
};
|
|
205
|
+
return buildType(paramsHostmeta, callback);
|
|
169
206
|
}
|
|
170
207
|
});
|
|
171
208
|
}
|
|
@@ -186,46 +223,72 @@ function buildHostmeta(hostId, hostmetaElems, callback) {
|
|
|
186
223
|
* applicationId: 'o365'
|
|
187
224
|
* };
|
|
188
225
|
* Consult 'collected_message' definition in proto/common_proto.piqi.proto
|
|
226
|
+
* @param filterJson - JSON parsed object representing key-value pairs which
|
|
227
|
+
* should exist in a message. For example, {type: 'Security', category: 'Admin'}.
|
|
228
|
+
* @param filterRegexp - regexp object filter. If content messages are JSON object
|
|
229
|
+
* then regexp filter if applied to a stringified message value.
|
|
189
230
|
* @param callback
|
|
190
231
|
* @returns
|
|
191
232
|
*/
|
|
192
233
|
|
|
193
|
-
function buildMessages(content, parseContentFun, callback) {
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
234
|
+
function buildMessages({content, parseContentFun, filterJson, filterRegexp}, callback) {
|
|
235
|
+
const jsonFilteredContent = alLogFilter.filterJson(content, filterJson);
|
|
236
|
+
const reFilter = alLogFilter.initRegExpFilter(filterRegexp);
|
|
237
|
+
|
|
238
|
+
async.reduce(jsonFilteredContent, [], function(memo, item, asyncCallback) {
|
|
239
|
+
let messageType = commonProtoPb.collected_message;
|
|
240
|
+
let messagePayload = parseContentFun(item);
|
|
241
|
+
if (messagePayload && messagePayload.message) {
|
|
242
|
+
// Apply RegExp filter
|
|
243
|
+
const passFilter = reFilter ? reFilter.test(messagePayload.message) : true;
|
|
244
|
+
if (passFilter) {
|
|
245
|
+
const paramsMessage = {
|
|
246
|
+
type: messageType,
|
|
247
|
+
payload: messagePayload
|
|
248
|
+
};
|
|
249
|
+
buildType(paramsMessage, function(err, buf) {
|
|
250
|
+
if (err) {
|
|
251
|
+
return asyncCallback(err);
|
|
252
|
+
} else {
|
|
253
|
+
buf.messageLength = buf.message.length;
|
|
254
|
+
memo.push(buf);
|
|
255
|
+
return asyncCallback(err, memo);
|
|
256
|
+
}
|
|
257
|
+
});
|
|
200
258
|
} else {
|
|
201
|
-
memo
|
|
202
|
-
return asyncCallback(err, memo);
|
|
259
|
+
return asyncCallback(null, memo);
|
|
203
260
|
}
|
|
204
|
-
}
|
|
261
|
+
} else {
|
|
262
|
+
return asyncCallback(null, memo);
|
|
263
|
+
}
|
|
205
264
|
},
|
|
206
265
|
callback);
|
|
207
266
|
}
|
|
208
267
|
|
|
209
|
-
function buildBatch(sId, metadata, messages, callback) {
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
var batchPayload = {
|
|
268
|
+
function buildBatch({sId, metadata, messages}, callback) {
|
|
269
|
+
const batchPayload = {
|
|
213
270
|
sourceId: sId,
|
|
214
271
|
metadata: metadata,
|
|
215
272
|
message: messages
|
|
216
273
|
};
|
|
217
274
|
|
|
218
|
-
|
|
275
|
+
const params = {
|
|
276
|
+
type: commonProtoPb.collected_batch,
|
|
277
|
+
payload: batchPayload
|
|
278
|
+
};
|
|
279
|
+
buildType(params, callback);
|
|
219
280
|
}
|
|
220
281
|
|
|
221
|
-
function buildBatchList(batches, callback) {
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
var batchListPayload = {
|
|
282
|
+
function buildBatchList({batches}, callback) {
|
|
283
|
+
const batchListPayload = {
|
|
225
284
|
elem: [batches]
|
|
226
285
|
};
|
|
227
286
|
|
|
228
|
-
|
|
287
|
+
const params = {
|
|
288
|
+
type: commonProtoPb.collected_batch_list,
|
|
289
|
+
payload: batchListPayload
|
|
290
|
+
};
|
|
291
|
+
buildType(params, callback);
|
|
229
292
|
}
|
|
230
293
|
|
|
231
294
|
|
package/al_log_filter.js
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/* -----------------------------------------------------------------------------
|
|
2
|
+
* @copyright (C) 2021, Alert Logic, Inc
|
|
3
|
+
* @doc
|
|
4
|
+
*
|
|
5
|
+
* Helper log filter utilities for Alert Logic log collector.
|
|
6
|
+
*
|
|
7
|
+
* @end
|
|
8
|
+
* -----------------------------------------------------------------------------
|
|
9
|
+
*/
|
|
10
|
+
const lodashFilter = require('lodash.filter');
|
|
11
|
+
const lodashRemove = require('lodash.remove');
|
|
12
|
+
const lodashcloneDeep = require('lodash.clonedeep');
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* @function initializes JSON filter
|
|
16
|
+
*
|
|
17
|
+
* @param filter - string or object,
|
|
18
|
+
* for example, string '{"a": 1}',
|
|
19
|
+
* object {a:1},
|
|
20
|
+
* deep object '{"a": "firstlevelChild": 1}', '{"a": "firstlevelChild": "secondlevelChild": 2}', '{"a": "...nth levelChild": n},
|
|
21
|
+
* array object '[{"a": 1}, {"b": 2}]',
|
|
22
|
+
*
|
|
23
|
+
* @return filter - inited Json filter or null if json is incorrect
|
|
24
|
+
*/
|
|
25
|
+
var initJsonFilter = function (filter) {
|
|
26
|
+
if (typeof filter === 'string') {
|
|
27
|
+
try {
|
|
28
|
+
return JSON.parse(filter);
|
|
29
|
+
} catch (exception) {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
} else {
|
|
33
|
+
return filter;
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* @function filter messages using JSON like filters.
|
|
39
|
+
*
|
|
40
|
+
* @param messages - array of JSON parsed log messages
|
|
41
|
+
* @param filterString - filter string/object, for example, '{user: \"a\"}'
|
|
42
|
+
*
|
|
43
|
+
* @return array - filtered messages
|
|
44
|
+
* @NOTE: If json filter is bad then 'messages' is returned unfiltered.
|
|
45
|
+
*/
|
|
46
|
+
|
|
47
|
+
var filterJson = function (messages, filter) {
|
|
48
|
+
const filterJ = initJsonFilter(filter);
|
|
49
|
+
if (filterJ) {
|
|
50
|
+
let result = [];
|
|
51
|
+
let clonedMsgs = lodashcloneDeep(messages);
|
|
52
|
+
if (Array.isArray(filterJ)) {
|
|
53
|
+
// Iterate over filterJson and push filtered items into array
|
|
54
|
+
filterJ.forEach(function (e) {
|
|
55
|
+
result = result.concat(lodashRemove(clonedMsgs, function (t) {
|
|
56
|
+
// filter messages with filterJson element
|
|
57
|
+
return lodashFilter([t], e).length;
|
|
58
|
+
}));
|
|
59
|
+
});
|
|
60
|
+
} else {
|
|
61
|
+
result = result.concat(lodashFilter(clonedMsgs, filterJ));
|
|
62
|
+
}
|
|
63
|
+
// Return filtered items
|
|
64
|
+
return result;
|
|
65
|
+
} else {
|
|
66
|
+
return messages;
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* @function initializes reg exp filter
|
|
72
|
+
*
|
|
73
|
+
* @param filter - string or regexp, for example, 'ab+c', /ab+c/
|
|
74
|
+
*
|
|
75
|
+
* @return filter - inited regexp or null if regexp is incorrect
|
|
76
|
+
*/
|
|
77
|
+
var initRegExpFilter = function (filter) {
|
|
78
|
+
if (typeof filter === 'string') {
|
|
79
|
+
try {
|
|
80
|
+
return new RegExp(filter);
|
|
81
|
+
} catch (exception) {
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
} else {
|
|
85
|
+
return filter;
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* @function filters messages using regexp
|
|
91
|
+
*
|
|
92
|
+
* @param messages - array of JSON parsed log messages
|
|
93
|
+
* @param filter - filter string regexp or regexp object, for example, 'ab+c', /ab+c/
|
|
94
|
+
*
|
|
95
|
+
* @return array - filtered messages
|
|
96
|
+
* @NOTE: If regexp filter is bad then 'messages' is returned unfiltered.
|
|
97
|
+
*/
|
|
98
|
+
|
|
99
|
+
var filterRegExp = function (messages, filter) {
|
|
100
|
+
const re = initRegExpFilter(filter);
|
|
101
|
+
if (re) {
|
|
102
|
+
return messages.filter(function (m) {
|
|
103
|
+
return re.test(m);
|
|
104
|
+
});
|
|
105
|
+
} else {
|
|
106
|
+
return messages;
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
module.exports = {
|
|
112
|
+
filterJson: filterJson,
|
|
113
|
+
filterRegExp: filterRegExp,
|
|
114
|
+
initRegExpFilter: initRegExpFilter,
|
|
115
|
+
initJsonFilter: initJsonFilter
|
|
116
|
+
};
|
|
117
|
+
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alertlogic/al-collector-js",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.1",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Alert Logic Collector Common Library",
|
|
6
6
|
"repository": {
|
|
@@ -32,6 +32,9 @@
|
|
|
32
32
|
"dependencies": {
|
|
33
33
|
"async": "3.1.0",
|
|
34
34
|
"debug": "4.1.1",
|
|
35
|
+
"lodash.filter": "^4.6.0",
|
|
36
|
+
"lodash.remove": "^4.7.0",
|
|
37
|
+
"lodash.clonedeep": "^4.5.0",
|
|
35
38
|
"moment": "2.24.0",
|
|
36
39
|
"protobufjs": "6.8.8",
|
|
37
40
|
"request": "2.88.0",
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/* -----------------------------------------------------------------------------
|
|
2
|
+
* @copyright (C) 2021, Alert Logic, Inc
|
|
3
|
+
* @doc
|
|
4
|
+
*
|
|
5
|
+
* Tests for log filtering.
|
|
6
|
+
*
|
|
7
|
+
* @end
|
|
8
|
+
* -----------------------------------------------------------------------------
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
const assert = require('assert');
|
|
12
|
+
const alLogFilter = require('../al_log_filter');
|
|
13
|
+
|
|
14
|
+
describe('Unit Tests', function() {
|
|
15
|
+
describe('Filter Messages', function() {
|
|
16
|
+
let msgJson = [];
|
|
17
|
+
const msgString = [
|
|
18
|
+
'message1',
|
|
19
|
+
'message2',
|
|
20
|
+
'message3'
|
|
21
|
+
];
|
|
22
|
+
|
|
23
|
+
before(function(){
|
|
24
|
+
msgJson = [
|
|
25
|
+
{ message1: 1, text: 'test1' },
|
|
26
|
+
{ message2: 2, text: 'test12'},
|
|
27
|
+
{ messageA: "a", text: 'testa'},
|
|
28
|
+
{ messageB: {
|
|
29
|
+
childTestMsg: 'childTest',
|
|
30
|
+
childTestValue: 'childValue'
|
|
31
|
+
}, text: 'testb'},
|
|
32
|
+
{ messageC: {
|
|
33
|
+
childTestMsg: 'childTest',
|
|
34
|
+
childTestValue: {
|
|
35
|
+
messageC: "c"
|
|
36
|
+
}
|
|
37
|
+
}, text: 'testc'},
|
|
38
|
+
{ messageD: {
|
|
39
|
+
childTestMsg: 'childTestD',
|
|
40
|
+
childTestValue: {
|
|
41
|
+
messageC: "c"
|
|
42
|
+
}
|
|
43
|
+
}, text: 'testd'}
|
|
44
|
+
];
|
|
45
|
+
});
|
|
46
|
+
after(function() {
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it('Sunny case ', function(done) {
|
|
50
|
+
assert.deepEqual([{ message1: 1, text: 'test1' }], alLogFilter.filterJson(msgJson, '{"message1":1}'));
|
|
51
|
+
assert.deepEqual(['message1'], alLogFilter.filterRegExp(msgString, '.*1'));
|
|
52
|
+
assert.deepEqual(['message1', 'message2', 'message3'], alLogFilter.filterRegExp(msgString, '^message.*'));
|
|
53
|
+
return done();
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it('Wrong JSON filter', function(done) {
|
|
57
|
+
assert.deepEqual(msgJson, alLogFilter.filterJson(msgJson, '{"message1":1'));
|
|
58
|
+
return done();
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it('Wrong RegExp filter', function(done) {
|
|
62
|
+
assert.deepEqual(msgString, alLogFilter.filterRegExp(msgString, '['));
|
|
63
|
+
return done();
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it('Undefined filters', function (done) {
|
|
67
|
+
assert.deepEqual(msgString, alLogFilter.filterRegExp(msgString, null));
|
|
68
|
+
assert.deepEqual(msgJson, alLogFilter.filterJson(msgJson));
|
|
69
|
+
return done();
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
it('Should filter array based on object child property', function (done) {
|
|
73
|
+
assert.deepEqual([{
|
|
74
|
+
messageB: {
|
|
75
|
+
childTestMsg: 'childTest',
|
|
76
|
+
childTestValue: 'childValue'
|
|
77
|
+
},
|
|
78
|
+
text: 'testb'
|
|
79
|
+
}], alLogFilter.filterJson(msgJson, '{"messageB":{"childTestMsg":"childTest"}}'));
|
|
80
|
+
return done();
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
it('Should filter array based on object child of child property', function (done) {
|
|
84
|
+
assert.deepEqual([{
|
|
85
|
+
messageC: {
|
|
86
|
+
childTestMsg: 'childTest',
|
|
87
|
+
childTestValue: {
|
|
88
|
+
messageC: "c"
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
text: 'testc'
|
|
92
|
+
}], alLogFilter.filterJson(msgJson, '{"messageC":{"childTestMsg": "childTest","childTestValue":{"messageC":"c"}}}'));
|
|
93
|
+
return done();
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
it('Should filter array based on array of object with AND case', function (done) {
|
|
97
|
+
assert.deepEqual([{
|
|
98
|
+
messageB: {
|
|
99
|
+
childTestMsg: 'childTest',
|
|
100
|
+
childTestValue: 'childValue'
|
|
101
|
+
},
|
|
102
|
+
text: 'testb'
|
|
103
|
+
}, {
|
|
104
|
+
messageC: {
|
|
105
|
+
childTestMsg: 'childTest',
|
|
106
|
+
childTestValue: {
|
|
107
|
+
messageC: "c"
|
|
108
|
+
}
|
|
109
|
+
},
|
|
110
|
+
text: 'testc'
|
|
111
|
+
}], alLogFilter.filterJson(msgJson, '[{"messageB":{"childTestMsg":"childTest"}}, {"messageC":{"childTestMsg": "childTest","childTestValue":{"messageC":"c"}}}]'));
|
|
112
|
+
return done();
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
it('Should filter array based on array of object with OR case', function (done) {
|
|
116
|
+
assert.deepEqual([{
|
|
117
|
+
messageB: {
|
|
118
|
+
childTestMsg: 'childTest',
|
|
119
|
+
childTestValue: 'childValue'
|
|
120
|
+
},
|
|
121
|
+
text: 'testb'
|
|
122
|
+
}], alLogFilter.filterJson(msgJson, '[{"messageB":{"childTestMsg":"childTest"}}, {"messageC":{"childTestMsgT": "childTest","childTestValue":{"messageC":"c"}}}]'));
|
|
123
|
+
return done();
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
it('Two condition match of same object for array based filtering on array of object with OR case', function (done) {
|
|
127
|
+
assert.deepEqual([{
|
|
128
|
+
messageB: {
|
|
129
|
+
childTestMsg: 'childTest',
|
|
130
|
+
childTestValue: 'childValue'
|
|
131
|
+
},
|
|
132
|
+
text: 'testb'
|
|
133
|
+
}], alLogFilter.filterJson(msgJson, '[{"messageB":{"childTestMsg":"childTest"}}, {"messageB":{"childTestValue":"childValue"}}]'));
|
|
134
|
+
return done();
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
it('three condition match of same object for array based filtering on array of object with OR case', function (done) {
|
|
138
|
+
assert.deepEqual([{
|
|
139
|
+
messageB: {
|
|
140
|
+
childTestMsg: 'childTest',
|
|
141
|
+
childTestValue: 'childValue'
|
|
142
|
+
},
|
|
143
|
+
text: 'testb'
|
|
144
|
+
}], alLogFilter.filterJson(msgJson, '[{"messageB":{"childTestMsg":"childTest"}}, {"messageB":{"childTestValue":"childValue"}}, {"text": "testb"}]'));
|
|
145
|
+
return done();
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
it('negative case for array based filtering on array of object with OR case', function (done) {
|
|
149
|
+
assert.deepEqual([{
|
|
150
|
+
messageB: {
|
|
151
|
+
childTestMsg: 'childTest',
|
|
152
|
+
childTestValue: 'childValue'
|
|
153
|
+
},
|
|
154
|
+
text: 'testb'
|
|
155
|
+
}], alLogFilter.filterJson(msgJson, '[{"messageB":{"childTestMsg":"childTest"}}, {"messageB":{"childTestValue":"childValue1"}}]'));
|
|
156
|
+
return done();
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
});
|
package/test/al_log_test.js
CHANGED
|
@@ -54,8 +54,105 @@ describe('Unit Tests', function() {
|
|
|
54
54
|
return messagePayload;
|
|
55
55
|
};
|
|
56
56
|
var expectedPayload = 'eJzjamHi4izOLy1KTtXNTBGK5mLPyC8uATFFdm6e97ZBfLqW665Nbkkbdic+E771WoJByYJLhosvJz85MScepDQvMTdViEuKozg/NxXE5pLg4gSJx5dUFqQKcUtxJlaVFqXGp5XmSfkIHtV4Hc0ABLLcQEKJO9/YzLQ8NSkjPz/biCM3tbg4MT3V0Io/qzg/Tx+sTQ+kwknEEcR2TC7JLEt1ySxKTS7JL6okzjQjIk0DAFuCVYc=';
|
|
57
|
-
|
|
58
|
-
|
|
57
|
+
const params = {
|
|
58
|
+
hostId: 'host-id',
|
|
59
|
+
sourceId: 'source-id',
|
|
60
|
+
hostmetaElems: hml,
|
|
61
|
+
content: msgs,
|
|
62
|
+
parseCallback: parseFun
|
|
63
|
+
};
|
|
64
|
+
alLog.buildPayload(params, function(err, payloadObject){
|
|
65
|
+
assert.equal(expectedPayload, payloadObject.payload.toString('base64'));
|
|
66
|
+
return done();
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
it('Sunny case with JSON filter', function(done) {
|
|
71
|
+
let hostTypeElem = {
|
|
72
|
+
key: 'host_type',
|
|
73
|
+
value: {str: 'azure_fun'}
|
|
74
|
+
};
|
|
75
|
+
let localHostnameElem = {
|
|
76
|
+
key: 'local_hostname',
|
|
77
|
+
value: {str: 'somename'}
|
|
78
|
+
};
|
|
79
|
+
let hml = [localHostnameElem, hostTypeElem];
|
|
80
|
+
let msgs = [
|
|
81
|
+
{message:'message1', prop: 'value1', filter: 'pass'},
|
|
82
|
+
{message:'message2', prop: 'value2'},
|
|
83
|
+
{message:'messagea', prop: 'valuea', filter: 'pass'}
|
|
84
|
+
];
|
|
85
|
+
|
|
86
|
+
let parseFun = function(m) {
|
|
87
|
+
let messagePayload = {
|
|
88
|
+
messageTs: 1542138053,
|
|
89
|
+
priority: 11,
|
|
90
|
+
progName: 'o365webhook',
|
|
91
|
+
pid: undefined,
|
|
92
|
+
message: JSON.stringify(m),
|
|
93
|
+
messageType: 'json/azure.o365',
|
|
94
|
+
messageTypeId: 'AzureActiveDirectory',
|
|
95
|
+
messageTsUs: undefined
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
return messagePayload;
|
|
99
|
+
};
|
|
100
|
+
let expectedPayload = 'eJzjesDExVmcX1qUnKqbmSIUzcWekV9cAmKK7Nw8722D+HQt112b3JI27E58JnzrtQSDkgWXDBdfTn5yYk48SGleYm6qEJcUR3F+biqIzSXBxQkSjy+pLEgV4pbiTKwqLUqNTyvNk6oSPKrxOpoBCGS5gYQSd76xmWl5alJGfn62kVm1Um5qcXFieqqSFYxlqKSjVFCUXwAUKUvMKQXz0zJzSlKLgCIFicXFSrVW/FnF+Xn6YEv0QOY5iTiC2I7JJZllqS6ZRanJJflFlaTbnYhmdyLZdgMAFp90iA==';
|
|
101
|
+
const params = {
|
|
102
|
+
hostId: 'host-id',
|
|
103
|
+
sourceId: 'source-id',
|
|
104
|
+
hostmetaElems: hml,
|
|
105
|
+
content: msgs,
|
|
106
|
+
parseCallback: parseFun,
|
|
107
|
+
filterJson: {filter: 'pass'}
|
|
108
|
+
};
|
|
109
|
+
alLog.buildPayload(params, function(err, payloadObject){
|
|
110
|
+
assert.equal(expectedPayload, payloadObject.payload.toString('base64'));
|
|
111
|
+
return done();
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
it('Sunny case with regexp filter', function(done) {
|
|
116
|
+
let hostTypeElem = {
|
|
117
|
+
key: 'host_type',
|
|
118
|
+
value: {str: 'azure_fun'}
|
|
119
|
+
};
|
|
120
|
+
let localHostnameElem = {
|
|
121
|
+
key: 'local_hostname',
|
|
122
|
+
value: {str: 'somename'}
|
|
123
|
+
};
|
|
124
|
+
let hml = [localHostnameElem, hostTypeElem];
|
|
125
|
+
let msgs = [
|
|
126
|
+
'message1',
|
|
127
|
+
'message2',
|
|
128
|
+
'messagea'
|
|
129
|
+
];
|
|
130
|
+
|
|
131
|
+
let parseFun = function(m) {
|
|
132
|
+
let messagePayload = {
|
|
133
|
+
messageTs: 1542138053,
|
|
134
|
+
priority: 11,
|
|
135
|
+
progName: 'o365webhook',
|
|
136
|
+
pid: undefined,
|
|
137
|
+
message: m,
|
|
138
|
+
messageType: 'json/azure.o365',
|
|
139
|
+
messageTypeId: 'AzureActiveDirectory',
|
|
140
|
+
messageTsUs: undefined
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
return messagePayload;
|
|
144
|
+
};
|
|
145
|
+
let expectedPayload = 'eJzjamHi4izOLy1KTtXNTBGK5mLPyC8uATFFdm6e97ZBfLqW665Nbkkbdic+E771WoJByYJLhosvJz85MScepDQvMTdViEuKozg/NxXE5pLg4gSJx5dUFqQKcUtxJlaVFqXGp5XmSfkIHtV4Hc0ABLLcQEKJO9/YzLQ8NSkjPz/biCM3tbg4MT3V0Io/qzg/Tx+sTQ+kwknEEcR2TC7JLEt1ySxKTS7JL6okzjQjIk0DAFuCVYc=';
|
|
146
|
+
const params = {
|
|
147
|
+
hostId: 'host-id',
|
|
148
|
+
sourceId: 'source-id',
|
|
149
|
+
hostmetaElems: hml,
|
|
150
|
+
content: msgs,
|
|
151
|
+
parseCallback: parseFun,
|
|
152
|
+
filterRegexp: 'message[0-9]'
|
|
153
|
+
};
|
|
154
|
+
alLog.buildPayload(params, function(err, payloadObject){
|
|
155
|
+
assert.equal(expectedPayload, payloadObject.payload.toString('base64'));
|
|
59
156
|
return done();
|
|
60
157
|
});
|
|
61
158
|
});
|
|
@@ -91,7 +188,15 @@ describe('Unit Tests', function() {
|
|
|
91
188
|
messagePayload.message = JSON.stringify(messagePayload);
|
|
92
189
|
return messagePayload;
|
|
93
190
|
};
|
|
94
|
-
|
|
191
|
+
|
|
192
|
+
const params = {
|
|
193
|
+
hostId: 'host-id',
|
|
194
|
+
sourceId: 'source-id',
|
|
195
|
+
hostmetaElems: hml,
|
|
196
|
+
content: msgs,
|
|
197
|
+
parseCallback: parseFun
|
|
198
|
+
};
|
|
199
|
+
alLog.buildPayload(params, function(err, payload){
|
|
95
200
|
sinon.match(err, 'Maximum payload size exceeded');
|
|
96
201
|
return done();
|
|
97
202
|
});
|
|
@@ -125,7 +230,15 @@ describe('Unit Tests', function() {
|
|
|
125
230
|
|
|
126
231
|
return messagePayload;
|
|
127
232
|
};
|
|
128
|
-
|
|
233
|
+
|
|
234
|
+
const params = {
|
|
235
|
+
hostId: 'host-id',
|
|
236
|
+
sourceId: 'source-id',
|
|
237
|
+
hostmetaElems: hml,
|
|
238
|
+
content: msgs,
|
|
239
|
+
parseCallback: parseFun
|
|
240
|
+
};
|
|
241
|
+
alLog.buildPayload(params, function(err, payload){
|
|
129
242
|
assert.equal(err, 'elem.key: string expected');
|
|
130
243
|
return done();
|
|
131
244
|
});
|
|
@@ -156,7 +269,15 @@ describe('Unit Tests', function() {
|
|
|
156
269
|
|
|
157
270
|
return messagePayload;
|
|
158
271
|
};
|
|
159
|
-
|
|
272
|
+
|
|
273
|
+
const params = {
|
|
274
|
+
hostId: 'host-id',
|
|
275
|
+
sourceId: 'source-id',
|
|
276
|
+
hostmetaElems: hml,
|
|
277
|
+
content: msgs,
|
|
278
|
+
parseCallback: parseFun
|
|
279
|
+
};
|
|
280
|
+
alLog.buildPayload(params, function(err, payload){
|
|
160
281
|
assert.equal(err, 'messageTs: integer|Long expected');
|
|
161
282
|
return done();
|
|
162
283
|
});
|
package/test/azcollectc_test.js
CHANGED
|
@@ -207,7 +207,6 @@ describe('Unit Tests', function() {
|
|
|
207
207
|
|
|
208
208
|
fakePost = sinon.stub(AzcollectC.prototype, 'post').callsFake(
|
|
209
209
|
function fakeFn(path, options) {
|
|
210
|
-
console.log('!!!!FAKE POST', path);
|
|
211
210
|
return new Promise(function(resolve, reject) {
|
|
212
211
|
resolve('ok');
|
|
213
212
|
});
|