Skip to content

Commit

Permalink
[GCP ]Filter the logs base on logNames and timestamps (#379)
Browse files Browse the repository at this point in the history
* Filter the logs base on logNames and timestamps
  • Loading branch information
rakhimundhada15 authored Oct 21, 2024
1 parent ed6ac6b commit d9313f5
Show file tree
Hide file tree
Showing 5 changed files with 172 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@
"Description": "JSON list of google resources to poll logs from. In the format <resourceType>/<resourceID>",
"Type": "String"
},
"LogNameFilters": {
"Description": "A JSON list of Google Cloud log names used to filter logs. The format should be 'service.googleapis.com%2Flog_type', for example: 'cloudaudit.googleapis.com%2Factivity'.",
"Type": "String"
},
"CollectionStartTs": {
"Description": "Timestamp when log collection starts. For example, 2020-01-13T16:00:00Z",
"Type": "String",
Expand Down Expand Up @@ -113,6 +117,9 @@
"CollectorStreams": {
"Ref": "GoogleResourceIds"
},
"CollectorParamString2": {
"Ref": "LogNameFilters"
},
"CollectionStartTs": {
"Ref": "CollectionStartTs"
}
Expand Down
53 changes: 43 additions & 10 deletions collectors/googlestackdriver/collector.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,15 @@ class GooglestackdriverCollector extends PawsCollector {
endTs = moment(startTs).add(this.pollInterval, 'seconds').toISOString();
}
const resourceNames = JSON.parse(process.env.collector_streams);
const initialStates = resourceNames.map(stream => ({
stream,
nextPage:null,
since: startTs,
until: endTs,
poll_interval_sec: 1
}));
const initialStates = resourceNames
.filter(stream => stream && stream.trim() !== "") // Filter out empty or invalid values
.map(stream => ({
stream,
nextPage: null,
since: startTs,
until: endTs,
poll_interval_sec: 1
}));
return callback(null, initialStates, 1);
}

Expand Down Expand Up @@ -97,9 +99,7 @@ class GooglestackdriverCollector extends PawsCollector {

AlLogger.info(`GSTA000001 Collecting data from ${state.since} till ${state.until} for ${state.stream}`);

// TODO: figure out a better way to format this. I'm pretty sure that it needs the newlines in it.
const filter = `timestamp >= "${state.since}"
timestamp < "${state.until}"`;
const filter = collector.generateFilter(state);

let pagesRetireved = 0;

Expand Down Expand Up @@ -182,6 +182,39 @@ timestamp < "${state.until}"`;
});
}

generateFilter(state) {
const logNames = process.env.paws_collector_param_string_2 ? JSON.parse(process.env.paws_collector_param_string_2) : [];
const filterConditions = [];
let logFilterCondition;

if (logNames.length > 0) {
logNames.forEach(logName => {
const trimmedlogName = logName?.trim();

if (trimmedlogName) {
const encodelogName = this.isUriEncoded(logName) ? logName : encodeURIComponent(logName);
filterConditions.push(`logName:"${encodelogName}"`);
} else {
AlLogger.warn("Skipping empty log ID.");
}
});
if (filterConditions.length > 0) {
logFilterCondition = filterConditions.join(" OR ");
}
}
// Construct the basic timestamp filter
let filterQuery = `timestamp >= "${state.since}" AND timestamp < "${state.until}"`;
if (logFilterCondition) {
// Combine the LogName and timesamp filter
filterQuery = `${filterQuery} AND (${logFilterCondition})`;
}
return filterQuery;
}

isUriEncoded(logName) {
return decodeURIComponent(logName) !== logName;
}


_getNextCollectionState(curState, nextPage) {
// Reset the page size for the next collection if it's less than the maximum
Expand Down
34 changes: 17 additions & 17 deletions collectors/googlestackdriver/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "googlestackdriver-collector",
"version": "1.2.14",
"version": "1.2.15",
"description": "Alert Logic AWS based Googlestackdriver Log Collector",
"repository": {},
"private": true,
Expand All @@ -9,28 +9,28 @@
"test": "JUNIT_REPORT_PATH=./test/report.xml nyc --reporter=text mocha --colors"
},
"devDependencies": {
"@aws-sdk/client-cloudformation": "^3.632.0",
"@aws-sdk/client-cloudwatch": "^3.632.0",
"@aws-sdk/client-dynamodb": "^3.632.0",
"@aws-sdk/client-kms": "^3.632.0",
"@aws-sdk/client-lambda": "^3.632.0",
"@aws-sdk/client-s3": "^3.633.0",
"@aws-sdk/client-sqs": "^3.632.0",
"@aws-sdk/client-ssm": "^3.632.0",
"@aws-sdk/client-cloudformation": "^3.666.0",
"@aws-sdk/client-cloudwatch": "^3.666.0",
"@aws-sdk/client-dynamodb": "^3.666.0",
"@aws-sdk/client-kms": "^3.666.0",
"@aws-sdk/client-lambda": "^3.666.0",
"@aws-sdk/client-s3": "^3.666.0",
"@aws-sdk/client-sqs": "^3.666.0",
"@aws-sdk/client-ssm": "^3.666.0",
"jshint": "^2.13.6",
"mocha": "^10.7.3",
"mocha-jenkins-reporter": "^0.4.8",
"nyc": "^17.0.0",
"nyc": "^17.1.0",
"rewire": "^7.0.0",
"sinon": "^18.0.0"
"sinon": "^19.0.2"
},
"dependencies": {
"@alertlogic/al-collector-js": "3.0.12",
"@alertlogic/paws-collector": "2.2.5",
"async": "^3.2.5",
"debug": "^4.3.6",
"google-auth-library": "^9.13.0",
"googleapis": "^140.0.1",
"@alertlogic/al-collector-js": "3.0.14",
"@alertlogic/paws-collector": "2.2.6",
"async": "^3.2.6",
"debug": "^4.3.7",
"google-auth-library": "^9.14.1",
"googleapis": "^144.0.0",
"moment": "2.30.1"
},
"author": "Alert Logic Inc."
Expand Down
108 changes: 104 additions & 4 deletions collectors/googlestackdriver/test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -293,10 +293,8 @@ describe('Unit Tests', function() {
const startDate = moment().subtract(3, 'days');
let since = startDate.toISOString();
let until = startDate.add(2, 'days').toISOString();
const filter = `timestamp >= "${since}"
timestamp < "${until}"`;
const filter = `timestamp >= "${since}" AND timestamp < "${until}"`;
let nextPage = { pageToken: 'http://somenextpage.com', "pageSize": 1000, "resourceNames": ["projects/a-fake-project"], filter };

logginClientStub.callsFake(() => {
return new Promise((res, rej) => {
res({
Expand Down Expand Up @@ -539,4 +537,106 @@ timestamp < "${until}"`;
});
});
});
});
describe('log filter Tests', function() {
it('should generate correct filter excluding empty logType values', function (done) {
let ctx = {
invokedFunctionArn: googlestackdriverMock.FUNCTION_ARN,
fail: function (error) {
assert.fail(error);
done();
},
succeed: function () {
done();
}
};

GooglestackdriverCollector.load().then(function (creds) {
var collector = new GooglestackdriverCollector(ctx, creds, 'googlestackdriver');
const startDate = moment().subtract(20, 'minutes');
let since = startDate.toISOString();
let until = startDate.add(collector.pollInterval, 'seconds').toISOString();
process.env.paws_collector_param_string_2 = "[\"cloudaudit.googleapis.com%2Factivity\",\"\",\"cloudfunctions.googleapis.com/cloud-functions\"]";
const curState = {
since: since,
until: until,
poll_interval_sec: 1,
stream: 'projects/imran-49253',
};
// Expected filter string
const expectedFilter = `timestamp >= "${since}" AND timestamp < "${until}" AND (logName:"cloudaudit.googleapis.com%2Factivity" OR logName:"cloudfunctions.googleapis.com%2Fcloud-functions")`;

// Call the function to generate the filter
const filter = collector.generateFilter(curState);
assert.equal(expectedFilter, filter);
done();
});
});

it('should generate filter without logNameFilter when all logTypes are empty', function (done) {
let ctx = {
invokedFunctionArn: googlestackdriverMock.FUNCTION_ARN,
fail: function (error) {
assert.fail(error);
done();
},
succeed: function () {
done();
}
};

GooglestackdriverCollector.load().then(function (creds) {
var collector = new GooglestackdriverCollector(ctx, creds, 'googlestackdriver');
const startDate = moment().subtract(20, 'minutes');
let since = startDate.toISOString();
let until = startDate.add(collector.pollInterval, 'seconds').toISOString();
process.env.paws_collector_param_string_2 = "[\"\",\"\"]";
const curState = {
since: since,
until: until,
poll_interval_sec: 1,
stream: 'projects/imran-49253',
};
// Expected filter string
const expectedFilter = `timestamp >= "${since}" AND timestamp < "${until}"`;

// Call the function to generate the filter
const filter = collector.generateFilter(curState);
assert.equal(expectedFilter, filter);
done();
});
});
it('should handle case when logTypes is undefined or null', function (done) {
let ctx = {
invokedFunctionArn: googlestackdriverMock.FUNCTION_ARN,
fail: function (error) {
assert.fail(error);
done();
},
succeed: function () {
done();
}
};

GooglestackdriverCollector.load().then(function (creds) {
var collector = new GooglestackdriverCollector(ctx, creds, 'googlestackdriver');
const startDate = moment().subtract(20, 'minutes');
let since = startDate.toISOString();
let until = startDate.add(collector.pollInterval, 'seconds').toISOString();
const curState = {
since: since,
until: until,
poll_interval_sec: 1,
stream: 'projects/imran-49253',
};
// Expected filter string
const expectedFilter = `timestamp >= "${since}" AND timestamp < "${until}"`;

// Call the function to generate the filter
const filter = collector.generateFilter(curState);
assert.equal(expectedFilter, filter);
done();
});
});
});
});

2 changes: 1 addition & 1 deletion ps_spec.yml
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ stages:
- ./build_collector.sh googlestackdriver
env:
ALPS_SERVICE_NAME: "paws-googlestackdriver-collector"
ALPS_SERVICE_VERSION: "1.2.14" #set the value from collector package json
ALPS_SERVICE_VERSION: "1.2.15" #set the value from collector package json
outputs:
file: ./googlestackdriver-collector*
packagers:
Expand Down

0 comments on commit d9313f5

Please sign in to comment.