package org.lightfish.business.servermonitoring.control.collectors.logs;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.BiFunction;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.enterprise.inject.Instance;
import javax.inject.Inject;
import javax.json.JsonArray;
import javax.json.JsonObject;
import javax.ws.rs.core.Response;
import org.lightfish.business.configuration.boundary.Configurator;
import org.lightfish.business.servermonitoring.control.collectors.Pair;
import org.lightfish.business.servermonitoring.control.collectors.RestDataCollector;
import org.lightfish.business.servermonitoring.entity.LogRecord;
/**
*
* @author Rob Veldpaus
*/
public class LogCollector implements BiFunction<RestDataCollector, String, Pair> {
@Inject
Logger LOG;
@Inject
Configurator configurator;
@Inject
Instance<Boolean> collectLogs;
public static final String VIEW_LOG_BASE_URI = "view-log/details.json";
@Override
public Pair apply(RestDataCollector collector, String serverInstance) {
if (!collectLogs.get()) {
return null;
}
StringBuilder uriBuilder = new StringBuilder(VIEW_LOG_BASE_URI);
uriBuilder.append("?instanceName=")
.append(serverInstance)
.append("&fromTime=")
.append(getLastRunTime(serverInstance) + 1)
.append("&toTime=")
.append(System.currentTimeMillis() + 1000)
.append("&maximumNumberOfResults=1000");
String fullUri = collector.getProtocol() + collector.getLocation() + "/management/domain/" + uriBuilder.toString();
LOG.info("LogCollector with: " + fullUri);
Response response = collector.getResponse(fullUri);
JsonObject result = response.readEntity(JsonObject.class);
JsonArray recordsArray = result.getJsonArray("records");
List<LogRecord> records = new ArrayList<>(recordsArray.size());
for (int i = 0; i < recordsArray.size(); i++) {
JsonObject currentRecord = recordsArray.getJsonObject(i);
String message = currentRecord.getString("Message");
if (message.length() > 4000) {
message = message.substring(0, 3996) + "...";
}
records.add(
new LogRecord.Builder()
.instanceName(serverInstance)
.level(currentRecord.getString("loggedLevel"))
.loggerName(currentRecord.getString("loggerName"))
.message(message)
.messageId(currentRecord.getString("messageID", ""))
.monitoringTime(new Date(currentRecord.getJsonNumber("loggedDateTimeInMS").longValue()))
.nameValuePairs(splitNameValuePairs(currentRecord.getString("nameValuePairs")))
.build());
}
LOG.log(Level.FINER, "Found {0} log records!", records.size());
if (!records.isEmpty()) {
setLastRunTime(serverInstance, records.get(0).getMonitoringTime().getTime());
LOG.log(Level.FINE, "Last run time is now {0}", getLastRunTime(serverInstance));
}
return new Pair("logs", records);
}
private Map<String, String> splitNameValuePairs(String allPairs) {
String[] splitPairs = allPairs.split(";");
Map<String, String> pairMap = new HashMap<>(splitPairs.length);
for (String currentPair : splitPairs) {
String[] splitPair = currentPair.split("=", 2);
if (splitPair.length == 2) {
pairMap.put(splitPair[0], splitPair[1]);
} else {
LOG.log(Level.WARNING, "Failed to properly parse {0} for name/value pair map", currentPair);
}
}
return pairMap;
}
private long getLastRunTime(String serverInstance) {
String value = configurator.getValue(getLastRunTimeConfigKey(serverInstance));
if (value == null) {
return System.currentTimeMillis() - 10000;
}
return Long.valueOf(value);
}
private void setLastRunTime(String serverInstance, long lastRunTime) {
configurator.setValue(getLastRunTimeConfigKey(serverInstance), String.valueOf(lastRunTime));
}
private String getLastRunTimeConfigKey(String serverInstance) {
return "logs/" + serverInstance + "/last";
}
}