package com.jthink.skyeye.web.service;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.jthink.skyeye.data.http.HttpRequest;
import com.jthink.skyeye.base.constant.Constants;
import com.jthink.skyeye.base.dto.EventLog;
import com.jthink.skyeye.web.constant.EsSqlTemplate;
import com.jthink.skyeye.web.dto.StatisticsDto;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Service;
import java.util.*;
/**
* JThink@JThink
*
* @author JThink
* @version 0.0.1
* @desc
* @date 2016-11-29 20:22:54
*/
@Service
@ConfigurationProperties(prefix = "spring.statistic.es")
public class StatisticsService {
private String url;
private String realtimeTemplate;
private String realtimeAllTemplate;
private String offlineTemplate;
private String offlineAllTemplate;
private String searchTemplate;
private String searchAllTemplate;
private static final Logger LOGGER = LoggerFactory.getLogger(StatisticsService.class);
/**
* 根据传递的sql语句查询es
*
* @param sql
* @return
*/
private String query(String sql) {
String response = HttpRequest.get(this.url, sql);
return response;
}
/**
* 根据指定参数返回以天为单位的对应统计信息。
*
* @param eventType
* @param uniqueName
* @param begin
* @param end
* @return
*/
public List<StatisticsDto> statisticsDay(String eventType, String uniqueName, String begin, String end) {
return statistics(eventType, uniqueName, begin, end, Constants.DAY, Constants.DAY);
}
/**
* 根据指定参数返回以秒为单位的对应统计信息。
*
* @param eventType
* @param uniqueName
* @param begin
* @param end
* @return
*/
public List<StatisticsDto> statisticsSec(String eventType, String uniqueName, String begin, String end) {
return statistics(eventType, uniqueName, begin, end, Constants.TIME, Constants.TIME);
}
public List<StatisticsDto> statistics(String eventType, String uniqueName, String begin, String end,
String dateFieldName, String scope) {
String sql;
if (uniqueName.equals(Constants.ALL)) {
sql = this.searchAllTemplate.replace(EsSqlTemplate.EVENTTYPE, eventType)
.replace(EsSqlTemplate.BEGIN, begin).replace(EsSqlTemplate.END, end)
.replaceAll(EsSqlTemplate.DATEFIELD, dateFieldName)
.replace(EsSqlTemplate.SCOPE, scope);
} else {
sql = this.searchTemplate.replace(EsSqlTemplate.EVENTTYPE, eventType)
.replace(EsSqlTemplate.UNIQUENAME, uniqueName)
.replace(EsSqlTemplate.BEGIN, begin).replace(EsSqlTemplate.END, end)
.replaceAll(EsSqlTemplate.DATEFIELD, dateFieldName)
.replace(EsSqlTemplate.SCOPE, scope);
}
return this.parseStatisticsData(this.query(sql), uniqueName, scope);
}
/**
* 解析 es 返回内容
*
* @param resp
* @param groupByFirstField EsSQL 模板中 group by 的第一个字段。(第二个为 status)
* @return List<StatisticsDto>
*/
public List<StatisticsDto> parseStatisticsData(String resp, String name, String groupByFirstField) {
List<StatisticsDto> rtn = new ArrayList<StatisticsDto>();
if (null != resp) {
JSONObject json = JSON.parseObject(resp);
String time;
int succ, fail;
Iterator<Object> timeJSONs, statusJSONs;
JSONObject timeJSON, statusJSON;
timeJSONs = json.getJSONObject("aggregations").getJSONObject(groupByFirstField)
.getJSONArray("buckets").iterator();
while (timeJSONs.hasNext()) {
succ = 0;
fail = 0;
timeJSON = (JSONObject) timeJSONs.next();
statusJSONs = timeJSON.getJSONObject("status").getJSONArray("buckets").iterator();
time = timeJSON.getString("key");
while (statusJSONs.hasNext()) {
statusJSON = (JSONObject) statusJSONs.next();
if (statusJSON.getString("key").equals(EventLog.MONITOR_STATUS_SUCCESS)) {
succ = statusJSON.getIntValue("doc_count");
} else {
fail = statusJSON.getIntValue("doc_count");
}
}
rtn.add(new StatisticsDto(name, time, succ, fail));
}
}
return rtn;
}
/**
* 根据条件构造sql并进行es查询解析返回
*
* @param eventType
* @param uniqueName
* @param begin
* @param end
* @return
*/
public List<StatisticsDto> offlineStatistics(String eventType, String uniqueName, String begin, String end,
String scope) {
String sql = Constants.EMPTY_STR;
if (uniqueName.equals(Constants.ALL)) {
sql = this.offlineAllTemplate.replace(EsSqlTemplate.EVENTTYPE, eventType).replace(EsSqlTemplate.BEGIN,
begin).replace(EsSqlTemplate.END, end).replace(EsSqlTemplate.SCOPE, scope);
} else {
sql = this.offlineTemplate
.replace(EsSqlTemplate.EVENTTYPE, eventType)
.replace(EsSqlTemplate.UNIQUENAME, uniqueName)
.replace(EsSqlTemplate.BEGIN, begin)
.replace(EsSqlTemplate.END, end)
.replace(EsSqlTemplate.SCOPE, scope);
}
return this.parseOfflineData(this.query(sql), scope);
}
/**
* 根据es sql返回的结果进行解析
*
* @param response
* @return
*/
private List<StatisticsDto> parseOfflineData(String response, String scope) {
List<StatisticsDto> dtos = new ArrayList<StatisticsDto>();
if (null == response) {
// 错误
return dtos;
} else {
JSONObject json = JSON.parseObject(response);
Iterator<Object> iterator = json.getJSONObject("aggregations").getJSONObject(scope)
.getJSONArray("buckets").iterator();
while (iterator.hasNext()) {
JSONObject jsonObject = ((JSONObject) iterator.next());
StatisticsDto dto = new StatisticsDto();
dto.setTime(jsonObject.getString("key"));
dtos.add(this.parseStatisticsDto(jsonObject.getJSONObject("status").getJSONArray("buckets").iterator
(), dto));
}
return dtos;
}
}
/**
* 根据条件构造sql并进行es查询解析返回
*
* @param eventType
* @param uniqueName
* @param time
* @return
*/
public StatisticsDto realtimeStatistics(String eventType, String uniqueName, String time) {
String sql = Constants.EMPTY_STR;
if (uniqueName.equals(Constants.ALL)) {
sql = this.realtimeAllTemplate.replace(EsSqlTemplate.EVENTTYPE, eventType).replace(EsSqlTemplate.TIME,
time);
} else {
sql = this.realtimeTemplate.replace(EsSqlTemplate.EVENTTYPE, eventType).replace(EsSqlTemplate.UNIQUENAME,
uniqueName).replace(EsSqlTemplate.TIME, time);
}
StatisticsDto dto = this.parseRealtimeData(this.query(sql));
dto.setTime(time);
return dto;
}
/**
* 根据es sql返回的结果进行解析
*
* @param response
* @return
*/
private StatisticsDto parseRealtimeData(String response) {
if (null == response) {
// 错误
return null;
} else {
JSONObject json = JSON.parseObject(response);
JSONArray buckets = json.getJSONObject("aggregations").getJSONObject("status").getJSONArray("buckets");
StatisticsDto dto = new StatisticsDto();
return this.parseStatisticsDto(buckets.iterator(), dto);
}
}
/**
* 解析StatisticsDto
*
* @param iterator
* @param dto
* @return
*/
private StatisticsDto parseStatisticsDto(Iterator<Object> iterator, StatisticsDto dto) {
while (iterator.hasNext()) {
JSONObject jsonObject = ((JSONObject) iterator.next());
if (jsonObject.getString("key").equals(EventLog.MONITOR_STATUS_FAILED)) {
dto.setFail(jsonObject.getIntValue("doc_count"));
} else {
dto.setSucc(jsonObject.getIntValue("doc_count"));
}
}
return dto;
}
public String getRealtimeTemplate() {
return realtimeTemplate;
}
public void setRealtimeTemplate(String realtimeTemplate) {
this.realtimeTemplate = realtimeTemplate;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getRealtimeAllTemplate() {
return realtimeAllTemplate;
}
public void setRealtimeAllTemplate(String realtimeAllTemplate) {
this.realtimeAllTemplate = realtimeAllTemplate;
}
public String getOfflineTemplate() {
return offlineTemplate;
}
public void setOfflineTemplate(String offlineTemplate) {
this.offlineTemplate = offlineTemplate;
}
public String getOfflineAllTemplate() {
return offlineAllTemplate;
}
public void setOfflineAllTemplate(String offlineAllTemplate) {
this.offlineAllTemplate = offlineAllTemplate;
}
public String getSearchTemplate() {
return searchTemplate;
}
public void setSearchTemplate(String searchTemplate) {
this.searchTemplate = searchTemplate;
}
public String getSearchAllTemplate() {
return searchAllTemplate;
}
public void setSearchAllTemplate(String searchAllTemplate) {
this.searchAllTemplate = searchAllTemplate;
}
}