asksuite-core
Version:
106 lines (91 loc) • 2.9 kB
JavaScript
const AWS = require('aws-sdk');
const _ = require('lodash');
class AWSCloudWatchCaller {
constructor(awsConfig, logGroupName) {
this.otherParams = _.cloneDeep(awsConfig);
this.cacheLogStream = {};
this.cloudWatchLogs = new AWS.CloudWatchLogs(
Object.assign({ apiVersion: '2014-03-28' }, this.otherParams),
);
this.sequenceTokens = {};
this.queue = {};
this.logGroupName = logGroupName;
}
addToQueue(streamName, message) {
try {
const formattedMsg = {
message /* required */,
timestamp: new Date().getTime() /* required */,
};
this.queue[streamName] = this.queue[streamName] || [];
this.queue[streamName].push(formattedMsg);
} catch (e) {
console.log('error addToQueue ' + streamName, e);
}
}
startScheduler() {
setInterval(() => this.processQueue(), 10000);
}
processQueue() {
const agents = Object.keys(this.queue);
agents.forEach((streamName) => {
const logEvents = this.queue[streamName];
this.queue[streamName] = [];
if (logEvents && Array.isArray(logEvents) && logEvents.length) {
this.call(streamName, logEvents);
}
});
}
async call(streamName, logEvents) {
const logStreamName = `${streamName}`;
const params = {
logEvents,
logGroupName: this.logGroupName,
logStreamName /* required */,
sequenceToken: this.sequenceTokens[logStreamName],
};
try {
await this.createLogStream(logStreamName);
this.cloudWatchLogs.putLogEvents(params, (err, data) => {
if (err) {
if (err.message && err.message.includes('sequenceToken')) {
const matched = err.message.match(/: ((\d)+)/);
if (matched && Array.isArray(matched) && matched.length > 2) {
this.sequenceTokens[logStreamName] = matched[1];
this.call(streamName, logEvents);
}
} else {
console.log('err msg', err.message);
}
} // an error occurred
if (data) {
this.sequenceTokens[logStreamName] = data.nextSequenceToken;
// console.log("data", data);
}
});
} catch (e) {
console.log(e);
console.warn('Error, cannot invoke cloud watch ' + logStreamName);
}
}
createLogStream(name) {
if (this.cacheLogStream[name]) {
return Promise.resolve();
}
return new Promise((resolve) => {
const params = {
logGroupName: this.logGroupName /* required */,
logStreamName: name /* required */,
};
this.cloudWatchLogs.createLogStream(params, (err) => {
if (err && !err.message.includes('already exists')) {
console.log('err', err.message);
} else {
this.cacheLogStream[name] = true;
}
resolve();
});
});
}
}
module.exports = AWSCloudWatchCaller;