package com.loggingbox.indexer;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
import static org.elasticsearch.node.NodeBuilder.nodeBuilder;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import org.apache.log4j.Logger;
import org.elasticsearch.action.admin.cluster.node.info.NodesInfoRequest;
import org.elasticsearch.action.admin.cluster.node.info.NodesInfoResponse;
import org.elasticsearch.action.bulk.BulkRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.SearchType;
import org.elasticsearch.client.Client;
import org.elasticsearch.common.settings.ImmutableSettings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.index.query.FilterBuilders;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.node.Node;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHitField;
import org.elasticsearch.search.SearchHits;
import org.springframework.stereotype.Component;
import com.log.model.Level;
import com.log.model.Log;
import com.log.model.command.Search;
import com.log.model.result.SearchResult;
import com.log.storage.LogIndexer;
@Component
public class ElasticSearchLogIndexer implements LogIndexer {
private static final Logger LOGGER = Logger
.getLogger(ElasticSearchLogIndexer.class);
private final static String INDEX = "logging_box";
private final static String LOG = "log";
private final static String LOG_SOURCE = "{\"log\":{"
+ "\"properties\" : {" + "\"id\" : {\"index\" : \"not_analyzed\"}"
+ "\"data\" : {\"index\" : \"\"}" + "} " + "}";
private final static String FIELD_ID = "id";
private final static String FIELD_APPLICATION_ID = "applicationId";
private final static String FIELD_HOST = "host";
private final static String FIELD_LEVEL = "level";
private final static String FIELD_TYPE = "type";
private final static String FIELD_DATE = "date";
private final static String FIELD_DATA = "data";
private Client client;
private synchronized final Client getClient() {
if (client == null) {
Settings settings = ImmutableSettings.settingsBuilder()
.put("cluster.name", "elasticsearch")
.put("multicast.enabled", false).put("node.master", true)
.put("index.number_of_shards", 1)
.put("index.number_of_replicas", 0)
.put("transport.tcp.port", 9350)
.put("client.transport.sniff", false).build();
Node node = nodeBuilder().settings(settings).local(true).node();
client = node.client();
NodesInfoResponse rsp = client.admin().cluster()
.nodesInfo(new NodesInfoRequest()).actionGet();
String str = "Cluster:" + rsp.getClusterName() + ". Active nodes:";
str += rsp.getNodesMap().keySet();
System.out.println(str);
client.admin().cluster().prepareHealth().setWaitForGreenStatus()
.execute().actionGet();
checkIndex();
}
return client;
}
private void checkIndex() {
if (!getClient().admin().indices().prepareExists(INDEX).execute()
.actionGet().exists()) {
getClient().admin().indices().prepareCreate(INDEX).execute()
.actionGet();
getClient().admin().indices().preparePutMapping(INDEX)
.setIgnoreConflicts(true).setType(LOG)
.setSource(LOG_SOURCE).execute().actionGet();
}
}
@Override
public void indexLog(Log log) {
try {
getClient().prepareIndex(INDEX, LOG, log.getId())
.setSource(getContentBuilder(log)).execute().actionGet();
} catch (IOException ex) {
LOGGER.error("Failed to index log", ex);
}
}
@Override
public void indexLogs(List<Log> logs) {
try {
BulkRequestBuilder bulkBuilder = getClient().prepareBulk();
for (Log log : logs) {
bulkBuilder = bulkBuilder.add(getClient().prepareIndex(INDEX, LOG,
log.getId()).setSource(getContentBuilder(log)));
}
bulkBuilder.execute().actionGet();
} catch (IOException ex) {
LOGGER.error("Failed to index logs", ex);
}
}
private XContentBuilder getContentBuilder(Log log) throws IOException {
XContentBuilder contentBuilder = jsonBuilder().startObject();
contentBuilder = contentBuilder.field(FIELD_APPLICATION_ID,
log.getApplicationId());
contentBuilder = contentBuilder.field(FIELD_DATE, log.getDate()
.getTime());
contentBuilder = contentBuilder.field(FIELD_DATA, log.getData());
if (log.getHost() != null) {
contentBuilder = contentBuilder
.field(FIELD_HOST, log.getHost());
}
if (log.getType() != null) {
contentBuilder = contentBuilder
.field(FIELD_TYPE, log.getType());
}
if (log.getLevel() != null) {
contentBuilder = contentBuilder.field(FIELD_LEVEL, log
.getLevel().toString());
}
contentBuilder = contentBuilder.field(FIELD_ID, log.getId())
.endObject();
return contentBuilder;
}
@Override
public SearchResult searchLogs(Search search) {
List<Log> logs = new ArrayList<Log>();
QueryBuilder qb = QueryBuilders
.termQuery(FIELD_DATA, search.getToken().toLowerCase());
qb = QueryBuilders.filteredQuery(
qb,
FilterBuilders.termFilter(FIELD_APPLICATION_ID,
search.getApplicationId()));
LOGGER.info(String.format("{%s} Search query {%s} {%s, %s} ",
search.getApplicationId(), search.getToken(), search.getFrom(), search.getSize()));
SearchResult searchResult = new SearchResult();
try {
SearchResponse response = getClient()
.prepareSearch(INDEX)
.setTypes(LOG)
.addFields(FIELD_DATA, FIELD_DATE, FIELD_HOST, FIELD_LEVEL,
FIELD_TYPE)
.setSearchType(SearchType.DFS_QUERY_AND_FETCH).setQuery(qb)
.setFrom(search.getFrom()).setSize(search.getSize()).setExplain(true).execute()
.actionGet();
searchResult.setItemFounds(response.getHits().getTotalHits());
SearchHits hits = response.getHits();
for (SearchHit hit : hits.getHits()) {
String logId = hit.getId();
Log log = new Log();
log.setId(logId);
log.setApplicationId(search.getApplicationId());
Map<String, SearchHitField> fields = hit.getFields();
if (fields.containsKey(FIELD_DATE)) {
log.setDate(new Date(fields.get(FIELD_DATE)
.<Long> getValue()));
}
if (fields.containsKey(FIELD_HOST)) {
log.setHost(fields.get(FIELD_HOST).<String> getValue());
}
if (fields.containsKey(FIELD_DATA)) {
log.setData(fields.get(FIELD_DATA).<String> getValue());
}
if (fields.containsKey(FIELD_LEVEL)) {
log.setLevel(Level.valueOf(fields.get(FIELD_LEVEL)
.<String> getValue()));
}
if (fields.containsKey(FIELD_TYPE)) {
log.setType(fields.get(FIELD_TYPE).<String> getValue());
}
logs.add(log);
}
} catch (Exception ex) {
LOGGER.error(
String.format("Failed to search term {%s}",
search.getToken()), ex);
}
LOGGER.info(String.format("Find {%s} results", logs.size()));
searchResult.setLogs(logs);
searchResult.setApplicationId(search.getApplicationId());
searchResult.setToken(search.getToken());
searchResult.setFrom(search.getFrom());
searchResult.setSize(search.getSize());
return searchResult;
}
}