package com.sumologic.client;
import java.io.IOException;
import com.amazonaws.services.kinesis.model.Record;
import com.amazonaws.util.json.JSONArray;
import com.amazonaws.util.json.JSONException;
import com.amazonaws.util.json.JSONObject;
import com.sumologic.client.implementations.SumologicTransformer;
import com.sumologic.client.model.CloudWatchLogsMessageModel;
import com.sumologic.client.model.LogEvent;
import org.apache.log4j.Logger;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;
import java.util.List;
import com.fasterxml.jackson.databind.ObjectMapper;
/**
* A custom transfomer for {@link CloudWatchLogsMessageModel} records in JSON format. The output is in a format
* usable for insertions to Sumologic.
*/
public class CloudWatchMessageModelSumologicTransformer
implements SumologicTransformer<CloudWatchLogsMessageModel> {
private static final Logger LOG = Logger.getLogger(CloudWatchMessageModelSumologicTransformer.class.getName());
private static CharsetEncoder encoder = Charset.forName("UTF-8").newEncoder();
/**
* Creates a new KinesisMessageModelSumologicTransformer.
*/
public CloudWatchMessageModelSumologicTransformer() {
super();
}
@Override
public String fromClass(CloudWatchLogsMessageModel message) {
String jsonMessage = "";
JSONObject outputObject;
int recordsInMessageCount = 0;
List<LogEvent> logEvents = message.getLogEvents();
int logEventsSize = logEvents.size();
for (int i=0;i<logEventsSize;i++) {
LogEvent log = logEvents.get(i);
outputObject = new JSONObject();
try {
// Header
outputObject.put("logGroup", message.getLogGroup());
outputObject.put("logStream", message.getLogStream());
outputObject.put("messageType", message.getMessageType());
outputObject.put("owner", message.getOwner());
outputObject.put("subscriptionFilters", new JSONArray(message.getSubscriptionFilters()));
// Body
outputObject.put("id", log.getId());
outputObject.put("message", log.getMessage());
outputObject.put("timestamp", log.getTimestamp());
} catch (JSONException e) {
LOG.error("Unable to convert message into JSON String: "+e.getMessage());
}
jsonMessage += outputObject.toString();
recordsInMessageCount++;
if (i < logEventsSize - 1) {
jsonMessage += '\n';
}
}
return jsonMessage;
}
@Override
public CloudWatchLogsMessageModel toClass(Record record) {
byte[] decodedRecord = record.getData().array();
String stringifiedRecord = SumologicKinesisUtils.decompressGzip(decodedRecord);
if (stringifiedRecord == null) {
LOG.error("Unable to decompress the record: "+new String(record.getData().array())
+"\nNot attempting to transform into a Message Model");
return null;
}
ByteBuffer bufferedData = null;
try {
bufferedData = encoder.encode(CharBuffer.wrap(stringifiedRecord));
} catch (CharacterCodingException e) {
LOG.error("Unable to set the decompressed Record for serializing "+e.getMessage());
}
record.setData(bufferedData);
try {
return new ObjectMapper().readValue(
record.getData().array(),
CloudWatchLogsMessageModel.class);
} catch (IOException e) {
LOG.error("Unable to convert the Record into a POJO: "+stringifiedRecord
+"\nerror: "+e.getMessage());
}
return null;
}
}