mongodb currency 관련 작업

currency 작업 스케줄 추가
This commit is contained in:
2025-06-12 14:19:49 +09:00
parent bef9c41f31
commit b14010f77b
14 changed files with 1463 additions and 143 deletions

View File

@@ -1,5 +1,6 @@
package com.caliverse.admin.Indicators.Indicatorsservice.aggregationservice;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Qualifier;
@@ -25,7 +26,8 @@ public class IndicatorsAuLoadService extends IndicatorsLogLoadServiceBase {
public <T extends IndicatorsLog> List<T> getIndicatorsLogData(String startTime, String endTime, Class<T> clazz) {
Criteria criteria = makeCriteria(startTime, endTime);
List<AggregationOperation> operations = setDefaultOperation(criteria);
// List<AggregationOperation> operations = setDefaultOperation(criteria);
List<AggregationOperation> operations = new ArrayList<>();
Aggregation aggregation = Aggregation.newAggregation(operations);

View File

@@ -1,19 +1,12 @@
package com.caliverse.admin.Indicators.Indicatorsservice.base;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationOperation;
import org.springframework.data.mongodb.core.aggregation.ProjectionOperation;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.stereotype.Service;
import com.caliverse.admin.global.common.constants.AdminConstants;
@Service
public abstract class IndicatorsLogLoadServiceBase implements IndicatorsLogLoadService {
@@ -37,31 +30,6 @@ public abstract class IndicatorsLogLoadServiceBase implements IndicatorsLogLoadS
{
return makeCriteria(startDate, endDate, AdminConstants.MONGO_DB_KEY_LOGTIME);
}
// 24.12.13 현재 사용안함
private AggregationOperation getDefaultProjectOperationName(){
ProjectionOperation projectOperation = Aggregation.project()
.and(AdminConstants.MONGO_DB_KEY_LOGDAY).as(AdminConstants.MONGO_DB_KEY_LOGDAY)
.and(AdminConstants.INDICATORS_KEY_DAU_BY_LANG).as(AdminConstants.INDICATORS_KEY_DAU_BY_LANG)
;
return projectOperation;
}
// 24.12.13 현재 사용안함
protected List<AggregationOperation> setDefaultOperation(Criteria criteria){
List<AggregationOperation> operations = new ArrayList<>();
operations.add(Aggregation.match(criteria));
operations.add(getDefaultProjectOperationName());
return operations;
}
}

View File

@@ -0,0 +1,53 @@
package com.caliverse.admin.Indicators.entity;
import com.caliverse.admin.logs.Indicatordomain.CurrencyMongoLog;
import lombok.Getter;
import lombok.Setter;
import org.springframework.data.mongodb.core.mapping.Document;
import java.util.List;
@Getter
@Setter
@Document(collection = "currency")
public class CurrencyDetailLogInfo extends LogInfoBase{
private String id;
private String logDay;
private String accountId;
private String userGuid;
private String userNickname;
private String tranId;
private String action;
private String logTime;
private String currencyType;
private String amountDeltaType;
private Double deltaAmount;
public CurrencyDetailLogInfo(String id,
String logDay,
String accountId,
String userGuid,
String userNickname,
String tranId,
String action,
String logTime,
String currencyType,
String amountDeltaType,
Double deltaAmount
) {
super(StatisticsType.CURRENCY);
this.id = id;
this.logDay = logDay;
this.accountId = accountId;
this.userGuid = userGuid;
this.userNickname = userNickname;
this.tranId = tranId;
this.action = action;
this.logTime = logTime;
this.currencyType = currencyType;
this.amountDeltaType = amountDeltaType;
this.deltaAmount = deltaAmount;
}
}

View File

@@ -0,0 +1,84 @@
package com.caliverse.admin.Indicators.entity;
import com.caliverse.admin.logs.Indicatordomain.CurrencyMongoLog;
import lombok.Getter;
import lombok.Setter;
import org.springframework.data.mongodb.core.mapping.Document;
import java.util.List;
import java.util.Map;
@Getter
@Setter
@Document(collection = "currency")
public class CurrencyLogInfo extends LogInfoBase{
private String logDay;
private String accountId;
private String userGuid;
private String userNickname;
private Double sapphireAcquired;
private Double sapphireConsumed;
private Double sapphireNet;
private Double goldAcquired;
private Double goldConsumed;
private Double goldNet;
private Double caliumAcquired;
private Double caliumConsumed;
private Double caliumNet;
private Double beamAcquired;
private Double beamConsumed;
private Double beamNet;
private Double rubyAcquired;
private Double rubyConsumed;
private Double rubyNet;
private Integer totalCurrencies;
private List<CurrencyMongoLog.currency> currencies;
public CurrencyLogInfo(String logDay,
String accountId,
String userGuid,
String userNickname,
Double sapphireAcquired,
Double sapphireConsumed,
Double sapphireNet,
Double goldAcquired,
Double goldConsumed,
Double goldNet,
Double caliumAcquired,
Double caliumConsumed,
Double caliumNet,
Double beamAcquired,
Double beamConsumed,
Double beamNet,
Double rubyAcquired,
Double rubyConsumed,
Double rubyNet,
Integer totalCurrencies,
List<CurrencyMongoLog.currency> currencies
) {
super(StatisticsType.CURRENCY);
this.logDay = logDay;
this.accountId = accountId;
this.userGuid = userGuid;
this.userNickname = userNickname;
this.sapphireAcquired = sapphireAcquired;
this.sapphireConsumed = sapphireConsumed;
this.sapphireNet = sapphireNet;
this.goldAcquired = goldAcquired;
this.goldConsumed = goldConsumed;
this.goldNet = goldNet;
this.caliumAcquired = caliumAcquired;
this.caliumConsumed = caliumConsumed;
this.caliumNet = caliumNet;
this.beamAcquired = beamAcquired;
this.beamConsumed = beamConsumed;
this.beamNet = beamNet;
this.rubyAcquired = rubyAcquired;
this.rubyConsumed = rubyConsumed;
this.rubyNet = rubyNet;
this.totalCurrencies = totalCurrencies;
this.currencies = currencies;
}
}

View File

@@ -16,7 +16,8 @@ public enum StatisticsType {
SERVER_INFO,
MONEY,
USER_CREATE,
USER_LOGIN
USER_LOGIN,
CURRENCY
;
public static StatisticsType getStatisticsType(String type) {

View File

@@ -0,0 +1,7 @@
package com.caliverse.admin.Indicators.indicatorrepository;
import com.caliverse.admin.Indicators.entity.CurrencyLogInfo;
import org.springframework.data.mongodb.repository.MongoRepository;
public interface IndicatorCurrencyRepository extends MongoRepository<CurrencyLogInfo, String> {
}

View File

@@ -0,0 +1,44 @@
package com.caliverse.admin.logs.Indicatordomain;
import com.caliverse.admin.global.common.constants.AdminConstants;
import lombok.Builder;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
import org.springframework.data.mongodb.core.mapping.Document;
import java.util.List;
@Document(collection = AdminConstants.MONGO_DB_COLLECTION_LOG)
@Getter
@Setter
public class CurrencyMongoLog extends MongoLogSearchBase{
private Double sapphireAcquired;
private Double sapphireConsumed;
private Double sapphireNet;
private Double goldAcquired;
private Double goldConsumed;
private Double goldNet;
private Double caliumAcquired;
private Double caliumConsumed;
private Double caliumNet;
private Double beamAcquired;
private Double beamConsumed;
private Double beamNet;
private Double rubyAcquired;
private Double rubyConsumed;
private Double rubyNet;
private Integer totalCurrencies;
private List<currency> currencies;
@Data
@Builder
public static class currency {
private String tranId;
private String action;
private String logTime;
private String currencyType;
private String amountDeltaType;
private Double deltaAmount;
}
}

View File

@@ -16,12 +16,13 @@ public class GenericMongoLog extends MongoLogSearchBase{
private Map<String, Object> header;
private Map<String, Object> body;
private String message;
private Integer totalCount;
public Map getMessage() {
if (message == null || message.isEmpty()) {
return new HashMap<>();
}
return CommonUtils.stringByObject(message, Map.class);
}
// public Map getMessage() {
// if (message == null || message.isEmpty()) {
// return new HashMap<>();
// }
// return CommonUtils.stringByObject(message, Map.class);
// }
}

View File

@@ -0,0 +1,422 @@
package com.caliverse.admin.logs.logservice.businesslogservice;
import com.caliverse.admin.global.common.constants.AdminConstants;
import lombok.extern.slf4j.Slf4j;
import org.bson.Document;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.*;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.stereotype.Service;
import java.util.Arrays;
import java.util.List;
@Slf4j
@Service
public class BusinessLogCurrencyService extends BusinessLogServiceBase {
public BusinessLogCurrencyService(@Qualifier("mongoBusinessLogTemplate") MongoTemplate mongoTemplate) {
super(mongoTemplate);
}
public <T> List<T> loadBusinessLogData(String startTime, String endTime, Class<T> class1) {
Criteria criteria = makeCriteria(startTime, endTime);
List<AggregationOperation> operations = setDefaultOperation(criteria);
operations.add(context ->
new Document("$group",
new Document("_id", "$tranId")
.append("logDay", new Document("$first", "$logDay"))
.append("logTime", new Document("$first", "$logTime"))
.append("userGuid", new Document("$first", "$userGuid"))
.append("userNickname", new Document("$first", "$userNickname"))
.append("accountId", new Document("$first", "$accountId"))
.append("action", new Document("$first", "$action"))
.append("documents", new Document("$push", "$$ROOT"))
)
);
operations.add(context ->
new Document("$match",
new Document("documents",
new Document("$elemMatch",
new Document("message",
new Document("$regex", "\"Domain\":\"Currency\"")
)
)
)
)
);
operations.add(context ->
new Document("$sort",
new Document("logTime", 1)
)
);
operations.add(context ->
new Document("$addFields",
new Document("currencyDocuments",
new Document("$filter",
new Document("input", "$documents")
.append("as", "doc")
.append("cond",
new Document("$regexMatch",
new Document("input", "$$doc.message")
.append("regex", "\"Domain\":\"Currency\"")
)
)
)
)
)
);
operations.add(context ->
new Document("$addFields",
new Document("currencyInfo",
new Document("$map",
new Document("input", "$currencyDocuments")
.append("as", "doc")
.append("in",
new Document("currencyType",
new Document("$let",
new Document("vars",
new Document("found",
new Document("$regexFind",
new Document("input", "$$doc.message")
.append("regex", "\"CurrencyType\":\"([^\"]+)\"")
)
)
)
.append("in",
new Document("$arrayElemAt",
Arrays.asList("$$found.captures", 0)
)
)
)
)
.append("amountDeltaType",
new Document("$let",
new Document("vars",
new Document("found",
new Document("$regexFind",
new Document("input", "$$doc.message")
.append("regex", "\"AmountDeltaType\":\"([^\"]+)\"")
)
)
)
.append("in",
new Document("$arrayElemAt",
Arrays.asList("$$found.captures", 0)
)
)
)
)
.append("deltaAmount",
new Document("$let",
new Document("vars",
new Document("found",
new Document("$regexFind",
new Document("input", "$$doc.message")
.append("regex", "\"DeltaAmount\":([^,}]+)")
)
)
)
.append("in",
new Document("$toDouble",
new Document("$arrayElemAt",
Arrays.asList("$$found.captures", 0)
)
)
)
)
)
)
)
)
)
);
operations.add(context ->
new Document("$unwind", "$currencyInfo")
);
operations.add(context ->
new Document("$match",
new Document("currencyInfo.currencyType",
new Document("$ne", null)
)
.append("currencyInfo.amountDeltaType",
new Document("$ne", null)
)
.append("currencyInfo.deltaAmount",
new Document("$ne", null)
)
)
);
operations.add(context ->
new Document("$group",
new Document("_id",
new Document("logDay", "$logDay")
.append("accountId", "$accountId")
)
.append("userGuid", new Document("$first", "$userGuid"))
.append("userNickname", new Document("$first", "$userNickname"))
// Gold
.append("goldAcquired",
new Document("$sum",
new Document("$cond",
Arrays.asList(
new Document("$and",
Arrays.asList(
new Document("$eq", Arrays.asList("$currencyInfo.currencyType", "Gold")),
new Document("$eq", Arrays.asList("$currencyInfo.amountDeltaType", "Acquire"))
)
),
"$currencyInfo.deltaAmount",
0
)
)
)
)
.append("goldConsumed",
new Document("$sum",
new Document("$cond",
Arrays.asList(
new Document("$and",
Arrays.asList(
new Document("$eq", Arrays.asList("$currencyInfo.currencyType", "Gold")),
new Document("$eq", Arrays.asList("$currencyInfo.amountDeltaType", "Consume"))
)
),
new Document("$abs", "$currencyInfo.deltaAmount"),
0
)
)
)
)
// Sapphire
.append("sapphireAcquired",
new Document("$sum",
new Document("$cond",
Arrays.asList(
new Document("$and",
Arrays.asList(
new Document("$eq", Arrays.asList("$currencyInfo.currencyType", "Sapphire")),
new Document("$eq", Arrays.asList("$currencyInfo.amountDeltaType", "Acquire"))
)
),
"$currencyInfo.deltaAmount",
0
)
)
)
)
.append("sapphireConsumed",
new Document("$sum",
new Document("$cond",
Arrays.asList(
new Document("$and",
Arrays.asList(
new Document("$eq", Arrays.asList("$currencyInfo.currencyType", "Sapphire")),
new Document("$eq", Arrays.asList("$currencyInfo.amountDeltaType", "Consume"))
)
),
new Document("$abs", "$currencyInfo.deltaAmount"),
0
)
)
)
)
// Calium
.append("caliumAcquired",
new Document("$sum",
new Document("$cond",
Arrays.asList(
new Document("$and",
Arrays.asList(
new Document("$eq", Arrays.asList("$currencyInfo.currencyType", "Calium")),
new Document("$eq", Arrays.asList("$currencyInfo.amountDeltaType", "Acquire"))
)
),
"$currencyInfo.deltaAmount",
0
)
)
)
)
.append("caliumConsumed",
new Document("$sum",
new Document("$cond",
Arrays.asList(
new Document("$and",
Arrays.asList(
new Document("$eq", Arrays.asList("$currencyInfo.currencyType", "Calium")),
new Document("$eq", Arrays.asList("$currencyInfo.amountDeltaType", "Consume"))
)
),
new Document("$abs", "$currencyInfo.deltaAmount"),
0
)
)
)
)
// Beam
.append("beamAcquired",
new Document("$sum",
new Document("$cond",
Arrays.asList(
new Document("$and",
Arrays.asList(
new Document("$eq", Arrays.asList("$currencyInfo.currencyType", "Beam")),
new Document("$eq", Arrays.asList("$currencyInfo.amountDeltaType", "Acquire"))
)
),
"$currencyInfo.deltaAmount",
0
)
)
)
)
.append("beamConsumed",
new Document("$sum",
new Document("$cond",
Arrays.asList(
new Document("$and",
Arrays.asList(
new Document("$eq", Arrays.asList("$currencyInfo.currencyType", "Beam")),
new Document("$eq", Arrays.asList("$currencyInfo.amountDeltaType", "Consume"))
)
),
new Document("$abs", "$currencyInfo.deltaAmount"),
0
)
)
)
)
// Ruby
.append("rubyAcquired",
new Document("$sum",
new Document("$cond",
Arrays.asList(
new Document("$and",
Arrays.asList(
new Document("$eq", Arrays.asList("$currencyInfo.currencyType", "Ruby")),
new Document("$eq", Arrays.asList("$currencyInfo.amountDeltaType", "Acquire"))
)
),
"$currencyInfo.deltaAmount",
0
)
)
)
)
.append("rubyConsumed",
new Document("$sum",
new Document("$cond",
Arrays.asList(
new Document("$and",
Arrays.asList(
new Document("$eq", Arrays.asList("$currencyInfo.currencyType", "Ruby")),
new Document("$eq", Arrays.asList("$currencyInfo.amountDeltaType", "Consume"))
)
),
new Document("$abs", "$currencyInfo.deltaAmount"),
0
)
)
)
)
.append("totalCurrencies", new Document("$sum", 1))
.append("currencies",
new Document("$push",
new Document("tranId", "$_id")
.append("action", "$action")
.append("logTime", "$logTime")
.append("currencyType", "$currencyInfo.currencyType")
.append("amountDeltaType", "$currencyInfo.amountDeltaType")
.append("deltaAmount", "$currencyInfo.deltaAmount")
)
)
)
);
operations.add(context ->
new Document("$project",
new Document("_id", 0)
.append("logDay", "$_id.logDay")
.append("accountId", "$_id.accountId")
.append("userGuid", 1)
.append("userNickname", 1)
.append("goldAcquired", 1)
.append("goldConsumed", 1)
.append("goldNet",
new Document("$subtract",
Arrays.asList("$goldAcquired", "$goldConsumed")
)
)
.append("sapphireAcquired", 1)
.append("sapphireConsumed", 1)
.append("sapphireNet",
new Document("$subtract",
Arrays.asList("$sapphireAcquired", "$sapphireConsumed")
)
)
.append("caliumAcquired", 1)
.append("caliumConsumed", 1)
.append("caliumNet",
new Document("$subtract",
Arrays.asList("$caliumAcquired", "$caliumConsumed")
)
)
.append("beamAcquired", 1)
.append("beamConsumed", 1)
.append("beamNet",
new Document("$subtract",
Arrays.asList("$beamAcquired", "$beamConsumed")
)
)
.append("rubyAcquired", 1)
.append("rubyConsumed", 1)
.append("rubyNet",
new Document("$subtract",
Arrays.asList("$rubyAcquired", "$rubyConsumed")
)
)
.append("totalCurrencies", 1)
.append("currencies", 1)
)
);
operations.add(context ->
new Document("$sort",
new Document("logTime", 1)
.append("accountId", 1)
)
);
Aggregation aggregation = Aggregation.newAggregation(operations);
log.info("loadBusinessLogData Currency Query: {}", aggregation);
AggregationResults<T> results = getMongoTemplate().aggregate(aggregation, AdminConstants.MONGO_DB_COLLECTION_LOG, class1);
return results.getMappedResults();
}
protected Criteria makeCriteria(String startTime, String endTime) {
return new Criteria()
.andOperator(
Criteria.where(AdminConstants.MONGO_DB_KEY_LOGTIME).gte(startTime)
,Criteria.where(AdminConstants.MONGO_DB_KEY_LOGTIME).lt(endTime)
);
}
}

View File

@@ -1,12 +1,16 @@
package com.caliverse.admin.logs.logservice.businesslogservice;
import com.caliverse.admin.domain.entity.EInputType;
import com.caliverse.admin.domain.entity.Log;
import com.caliverse.admin.domain.entity.common.SearchUserType;
import com.caliverse.admin.domain.entity.log.GenericLog;
import com.caliverse.admin.domain.request.LogGenericRequest;
import com.caliverse.admin.global.common.constants.AdminConstants;
import com.caliverse.admin.global.common.utils.CommonUtils;
import com.caliverse.admin.logs.Indicatordomain.GenericMongoLog;
import com.caliverse.admin.logs.entity.LogAction;
import com.caliverse.admin.logs.entity.LogDomain;
import com.fasterxml.jackson.databind.JsonNode;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.formula.functions.T;
import org.bson.Document;
@@ -24,6 +28,8 @@ import java.time.Duration;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@Slf4j
@Service
@@ -38,14 +44,240 @@ public class BusinessLogGenericService extends BusinessLogServiceBase {
}
public <T> List<T> loadBusinessLogData(LogGenericRequest logGenericRequest, Class<T> class1){
return loadBusinessLogData(logGenericRequest, class1, false);
List<GenericMongoLog> rawLogs = loadRawLogData(logGenericRequest);
List<T> processedLogs = rawLogs.parallelStream()
.map(rawLog -> parseLog(rawLog, class1))
.filter(logData -> {
if (logData == null) {
log.warn("Failed to parse log data - null result returned");
return false;
}
return true;
})
// 추후 조건에 따른 조회방식 처리 필요할듯(정규식은 느리다)
// .filter(logData -> {
// LogAction action = logGenericRequest.getLogAction();
// if(action == null || action.equals(LogAction.None)) return true;
// GenericLog log = (GenericLog) logData;
// return action.name().equals(log.getAction());
// })
// .filter(logData -> {
// LogDomain domain = logGenericRequest.getLogDomain();
// if(domain == null || domain.equals(LogDomain.BASE)) return true;
// GenericLog log = (GenericLog) logData;
// return domain.name().equals(log.getDomain());
// })
// .filter(logData -> {
// SearchUserType searchType = logGenericRequest.getSearchType();
// String searchData = logGenericRequest.getSearchData();
// if(searchData == null || searchData.isEmpty()) return true;
//
// GenericLog log = (GenericLog) logData;
//
// switch (searchType) {
// case ACCOUNT:
// return searchData.equals(log.getAccountId());
// case GUID:
// return searchData.equals(log.getUserGuid());
// case NICKNAME:
// return searchData.equals(log.getUserNickname());
// default:
// return false;
// }
// })
// .filter(logData -> {
// String tranId = logGenericRequest.getTranId();
// if(tranId == null || tranId.isEmpty()) return true;
// GenericLog log = (GenericLog) logData;
// return tranId.equals(log.getTranId());
// })
.toList();
return processedLogs;
}
// public List<Map<String, Object>> loadBusinessLogData(LogGenericRequest logGenericRequest) {
public <T> List<T> loadBusinessLogData(LogGenericRequest logGenericRequest, Class<T> class1, boolean isSimple) {
// LocalDateTime startDt = logGenericRequest.getStartDt().plusHours(9);
// LocalDateTime endDt = logGenericRequest.getEndDt().plusHours(9).plusDays(1);
// 정규식으로 조회시간이 오래걸린다
// public <T> List<T> loadBusinessLogData(LogGenericRequest logGenericRequest, Class<T> class1) {
//
// String startTime = logGenericRequest.getStartDt().toString().substring(0, 10);
// String endTime = logGenericRequest.getEndDt().toString().substring(0, 10);
// LogAction logAction = logGenericRequest.getLogAction();
// LogDomain logDomain = logGenericRequest.getLogDomain();
// SearchUserType searchUserType = logGenericRequest.getSearchType();
// String searchData = logGenericRequest.getSearchData();
// String tranId = logGenericRequest.getTranId();
// List<LogGenericRequest.LogFilter> filters = logGenericRequest.getFilters();
//
// Criteria criteria = makeCriteria(startTime, endTime);
// if(logAction != null && !logAction.equals(LogAction.None)) {
// criteria.and(AdminConstants.MONGO_DB_KEY_MESSAGE)
// .regex(String.format(AdminConstants.REGEX_MSG_ACTION, logAction.name()));
// }
//
// List<AggregationOperation> operations = setDefaultOperation(criteria);
//
//
// if(logDomain != null && !logDomain.equals(LogDomain.BASE)) {
// operations.add(context ->
// new Document("$match",
// new Document(AdminConstants.MONGO_DB_KEY_DOMAIN, logDomain.name())
// )
// );
// }
//
// if(searchUserType != null && !searchData.isEmpty() && !searchUserType.equals(SearchUserType.NONE)) {
// switch(searchUserType){
// case ACCOUNT:
// operations.add(context ->
// new Document("$match",
// new Document(AdminConstants.MONGO_DB_KEY_ACCOUNT_ID, searchData)
// )
// );
// break;
// case GUID:
// operations.add(context ->
// new Document("$match",
// new Document(AdminConstants.MONGO_DB_KEY_USER_GUID, searchData)
// )
// );
// break;
// case NICKNAME:
// operations.add(context ->
// new Document("$match",
// new Document(AdminConstants.MONGO_DB_KEY_USER_NICKNAME, searchData)
// )
// );
// break;
// }
// }
//
// if(tranId != null && !tranId.isEmpty()) {
// operations.add(context ->
// new Document("$match",
// new Document(AdminConstants.MONGO_DB_KEY_TRAN_ID, tranId)
// )
// );
// }
//
// if(filters != null && !filters.isEmpty()) {
// List<Document> filterConditions = new ArrayList<>();
//
// for (LogGenericRequest.LogFilter filter : filters) {
// if (filter.getFieldName() != null && !filter.getFieldName().isEmpty() &&
// filter.getValue() != null) {
//
// Object convertedValue = null;
// String valueStr = filter.getValue();
//
// // OR 조건 패턴 확인 (괄호와 파이프 문자 포함)
// boolean isOrPattern = valueStr.startsWith("(") && valueStr.endsWith(")") && valueStr.contains("|");
//
// if (isOrPattern) {
// // OR 패턴은 문자열 그대로 사용
// convertedValue = valueStr;
// } else {
// // 일반 값 변환
// switch (filter.getFieldType()) {
// case Number:
// try {
// if (valueStr.contains(".")) {
// convertedValue = Double.parseDouble(valueStr);
// } else {
// convertedValue = Long.parseLong(valueStr);
// }
// } catch (NumberFormatException e) {
// log.warn("Failed to convert value to number: {}", valueStr, e);
// convertedValue = valueStr;
// }
// break;
//
// case Boolean:
// convertedValue = Boolean.parseBoolean(valueStr);
// break;
//
// case String:
// case None:
// default:
// convertedValue = valueStr;
// break;
// }
// }
//
// // 중첩된 JSON 구조에 맞게 $regex를 사용한 패턴 매칭
// String regexPattern;
//
// if (isOrPattern) {
// // OR 패턴 처리
// String innerValues = valueStr.substring(1, valueStr.length() - 1);
// String[] parts = innerValues.split("\\|");
//
// // 필드 이름과 함께 각 값에 대한 정규식 패턴 구성
// StringBuilder orPatternBuilder = new StringBuilder();
// orPatternBuilder.append("\"").append(filter.getFieldName()).append("\":(");
//
// for (int i = 0; i < parts.length; i++) {
// if (i > 0) orPatternBuilder.append("|");
//
// String part = parts[i].trim();
// // 필드 타입에 맞게 값 형식화
// if (filter.getFieldType() == EInputType.String) {
// orPatternBuilder.append("\"").append(part.replace("\"", "\\\"")).append("\"");
// } else {
// orPatternBuilder.append(part);
// }
// }
//
// orPatternBuilder.append(")");
// regexPattern = orPatternBuilder.toString();
// } else {
// // 단일 값 처리
// regexPattern = "\"" + filter.getFieldName() + "\":" + CommonUtils.formatValueForRegex(convertedValue);
// }
//
// Document filterDoc = new Document("message", new Document("$regex", regexPattern));
// filterConditions.add(filterDoc);
// }
// }
//
// if (!filterConditions.isEmpty()) {
// operations.add(context -> new Document("$match", new Document("$and", filterConditions)));
// }
// }
//
// // 최종 출력 형식
// operations.add(context ->
// new Document("$sort",
// new Document("logTime", logGenericRequest.getOrderBy().equals("ASC") ? 1 : -1)
// .append(AdminConstants.MONGO_DB_KEY_TRAN_ID, 1)
// )
// );
//
// if (logGenericRequest.getPageNo() != null && logGenericRequest.getPageSize() != null) {
// int skip = (logGenericRequest.getPageNo() - 1) * logGenericRequest.getPageSize();
// operations.add(context -> new Document("$skip", skip));
// operations.add(context -> new Document("$limit", logGenericRequest.getPageSize()));
// }
//
// AggregationOptions options = AggregationOptions.builder()
// .allowDiskUse(true)
// .maxTime(Duration.ofSeconds(600))
// .build();
// Aggregation aggregation = Aggregation.newAggregation(operations).withOptions(options);
// log.info("loadBusinessLogData Generic Query: {}", aggregation);
// AggregationResults<T> results = getMongoTemplate()
// .aggregate(aggregation, AdminConstants.MONGO_DB_COLLECTION_LOG, class1);
// return results.getMappedResults();
// }
protected Criteria makeCriteria(String startTime, String endTime) {
return new Criteria()
.andOperator(
Criteria.where(AdminConstants.MONGO_DB_KEY_LOGTIME).gte(startTime).lt(endTime)
);
}
private List<GenericMongoLog> loadRawLogData(LogGenericRequest logGenericRequest) {
String startTime = logGenericRequest.getStartDt().toString().substring(0, 10);
String endTime = logGenericRequest.getEndDt().toString().substring(0, 10);
LogAction logAction = logGenericRequest.getLogAction();
@@ -56,20 +288,309 @@ public class BusinessLogGenericService extends BusinessLogServiceBase {
List<LogGenericRequest.LogFilter> filters = logGenericRequest.getFilters();
Criteria criteria = makeCriteria(startTime, endTime);
if(logAction != null && !logAction.equals(LogAction.None)) {
criteria.and(AdminConstants.MONGO_DB_KEY_MESSAGE)
.regex(String.format(AdminConstants.REGEX_MSG_ACTION, logAction.name()));
List<AggregationOperation> operations = new ArrayList<>();
operations.add(Aggregation.match(criteria));
if(logDomain != null && !logDomain.equals(LogDomain.BASE)) {
operations.add(context ->
new Document("$match",
new Document(AdminConstants.MONGO_DB_KEY_MESSAGE,
new Document("$regex", String.format(AdminConstants.REGEX_MSG_DOMAIN, logDomain.name()))
)
)
);
}
List<AggregationOperation> operations = setDefaultOperation(criteria);
if(logAction != null && !logAction.equals(LogAction.None)) {
operations.add(context ->
new Document("$match",
new Document(AdminConstants.MONGO_DB_KEY_MESSAGE,
new Document("$regex", String.format(AdminConstants.REGEX_MSG_ACTION, logAction.name()))
)
)
);
}
// if(logAction != null && !logAction.equals(LogAction.None)) {
// operations.add(context ->
// new Document("$match",
// new Document(AdminConstants.MONGO_DB_KEY_ACTION, logAction.name())
// )
// );
// }
if(searchUserType != null && !searchData.isEmpty() && !searchUserType.equals(SearchUserType.NONE)) {
switch(searchUserType){
case ACCOUNT:
operations.add(context ->
new Document("$match",
new Document(AdminConstants.MONGO_DB_KEY_MESSAGE,
new Document("$regex", String.format("\"AccountId\":\"%s\"", searchData))
)
)
);
break;
case GUID:
operations.add(context ->
new Document("$match",
new Document(AdminConstants.MONGO_DB_KEY_MESSAGE,
new Document("$regex", String.format("\"UserGuid\":\"%s\"", searchData))
)
)
);
break;
case NICKNAME:
operations.add(context ->
new Document("$match",
new Document(AdminConstants.MONGO_DB_KEY_MESSAGE,
new Document("$regex", String.format("\"UserNickname\":\"%s\"", searchData))
)
)
);
break;
}
}
if(tranId != null && !tranId.isEmpty()) {
operations.add(context ->
new Document("$match",
new Document(AdminConstants.MONGO_DB_KEY_MESSAGE,
new Document("$regex", String.format("\"TranId\":\"%s\"", tranId))
)
)
);
}
operations.add(context ->
new Document("$project",
new Document(AdminConstants.MONGO_DB_KEY_LOGTIME, 1)
.append(AdminConstants.MONGO_DB_KEY_MESSAGE, 1)
)
);
if(filters != null && !filters.isEmpty()) {
List<Document> filterConditions = new ArrayList<>();
for (LogGenericRequest.LogFilter filter : filters) {
if (filter.getFieldName() != null && !filter.getFieldName().isEmpty() &&
filter.getValue() != null) {
Object convertedValue = null;
String valueStr = filter.getValue();
// OR 조건 패턴 확인 (괄호와 파이프 문자 포함)
boolean isOrPattern = valueStr.startsWith("(") && valueStr.endsWith(")") && valueStr.contains("|");
if (isOrPattern) {
// OR 패턴은 문자열 그대로 사용
convertedValue = valueStr;
} else {
// 일반 값 변환
switch (filter.getFieldType()) {
case Number:
try {
if (valueStr.contains(".")) {
convertedValue = Double.parseDouble(valueStr);
} else {
convertedValue = Long.parseLong(valueStr);
}
} catch (NumberFormatException e) {
log.warn("Failed to convert value to number: {}", valueStr, e);
convertedValue = valueStr;
}
break;
case Boolean:
convertedValue = Boolean.parseBoolean(valueStr);
break;
case String:
case None:
default:
convertedValue = valueStr;
break;
}
}
// 중첩된 JSON 구조에 맞게 $regex를 사용한 패턴 매칭
String regexPattern;
if (isOrPattern) {
// OR 패턴 처리
String innerValues = valueStr.substring(1, valueStr.length() - 1);
String[] parts = innerValues.split("\\|");
// 필드 이름과 함께 각 값에 대한 정규식 패턴 구성
StringBuilder orPatternBuilder = new StringBuilder();
orPatternBuilder.append("\"").append(filter.getFieldName()).append("\":(");
for (int i = 0; i < parts.length; i++) {
if (i > 0) orPatternBuilder.append("|");
String part = parts[i].trim();
// 필드 타입에 맞게 값 형식화
if (filter.getFieldType() == EInputType.String) {
orPatternBuilder.append("\"").append(part.replace("\"", "\\\"")).append("\"");
} else {
orPatternBuilder.append(part);
}
}
orPatternBuilder.append(")");
regexPattern = orPatternBuilder.toString();
} else {
// 단일 값 처리
regexPattern = "\"" + filter.getFieldName() + "\":" + CommonUtils.formatValueForRegex(convertedValue);
}
Document filterDoc = new Document("message", new Document("$regex", regexPattern));
filterConditions.add(filterDoc);
}
}
if (!filterConditions.isEmpty()) {
operations.add(context -> new Document("$match", new Document("$and", filterConditions)));
}
}
operations.add(context ->
new Document("$sort",
new Document("logTime", logGenericRequest.getOrderBy().equals("ASC") ? 1 : -1)
)
);
if (logGenericRequest.getPageNo() != null && logGenericRequest.getPageSize() != null) {
int skip = (logGenericRequest.getPageNo() - 1) * logGenericRequest.getPageSize();
operations.add(context -> new Document("$skip", skip));
operations.add(context -> new Document("$limit", logGenericRequest.getPageSize()));
}
AggregationOptions options = AggregationOptions.builder()
.allowDiskUse(true)
.maxTime(Duration.ofSeconds(600))
.build();
Aggregation aggregation = Aggregation.newAggregation(operations).withOptions(options);
log.info("loadRawLogData Generic Query: {}", aggregation);
AggregationResults<GenericMongoLog> results = getMongoTemplate()
.aggregate(aggregation, AdminConstants.MONGO_DB_COLLECTION_LOG, GenericMongoLog.class);
return results.getMappedResults();
}
public Integer getRawLogCount(LogGenericRequest logGenericRequest) {
String startTime = logGenericRequest.getStartDt().toString().substring(0, 10);
String endTime = logGenericRequest.getEndDt().toString().substring(0, 10);
LogAction logAction = logGenericRequest.getLogAction();
LogDomain logDomain = logGenericRequest.getLogDomain();
SearchUserType searchUserType = logGenericRequest.getSearchType();
String searchData = logGenericRequest.getSearchData();
String tranId = logGenericRequest.getTranId();
List<LogGenericRequest.LogFilter> filters = logGenericRequest.getFilters();
Criteria criteria = makeCriteria(startTime, endTime);
List<AggregationOperation> operations = new ArrayList<>();
operations.add(Aggregation.match(criteria));
operations.add(context ->
new Document("$addFields",
new Document("userGuid",
new Document("$let",
new Document("vars",
new Document("found",
new Document("$regexFind",
new Document("input", "$message")
.append("regex", "\"UserGuid\":\"([^\"]+)\"")
)
)
)
.append("in",
new Document("$arrayElemAt", Arrays.asList("$$found.captures", 0))
)
)
)
.append("userNickname",
new Document("$let",
new Document("vars",
new Document("found",
new Document("$regexFind",
new Document("input", "$message")
.append("regex", "\"UserNickname\":\"([^\"]+)\"")
)
)
)
.append("in",
new Document("$arrayElemAt", Arrays.asList("$$found.captures", 0))
)
)
)
.append("accountId",
new Document("$let",
new Document("vars",
new Document("found",
new Document("$regexFind",
new Document("input", "$message")
.append("regex", "\"AccountId\":\"([^\"]+)\"")
)
)
)
.append("in",
new Document("$arrayElemAt", Arrays.asList("$$found.captures", 0))
)
)
)
.append("tranId",
new Document("$let",
new Document("vars",
new Document("found",
new Document("$regexFind",
new Document("input", "$message")
.append("regex", "\"TranId\":\"([^\"]+)\"")
)
)
)
.append("in",
new Document("$arrayElemAt", Arrays.asList("$$found.captures", 0))
)
)
)
.append("action",
new Document("$let",
new Document("vars",
new Document("found",
new Document("$regexFind",
new Document("input", "$message")
.append("regex", "\"Action\":\"([^\"]+)\"")
)
)
)
.append("in",
new Document("$arrayElemAt", Arrays.asList("$$found.captures", 0))
)
)
)
.append("domain",
new Document("$let",
new Document("vars",
new Document("found",
new Document("$regexFind",
new Document("input", "$message")
.append("regex", "\"Domain\":\"([^\"]+)\"")
)
)
)
.append("in",
new Document("$arrayElemAt", Arrays.asList("$$found.captures", 0))
)
)
)
)
);
if(logAction != null && !logAction.equals(LogAction.None)) {
operations.add(context ->
new Document("$match",
new Document(AdminConstants.MONGO_DB_KEY_ACTION, logAction.name())
)
);
}
if(logDomain != null && !logDomain.equals(LogDomain.BASE)) {
operations.add(context ->
@@ -198,100 +719,93 @@ public class BusinessLogGenericService extends BusinessLogServiceBase {
}
}
if(isSimple){
operations.add(context ->
new Document("$project",
new Document(AdminConstants.MONGO_DB_KEY_ACCOUNT_ID, 1)
.append(AdminConstants.MONGO_DB_KEY_USER_GUID, 1)
.append(AdminConstants.MONGO_DB_KEY_USER_NICKNAME, 1)
.append(AdminConstants.MONGO_DB_KEY_LOGTIME, 1)
.append("body", 1)
)
);
}
// 최종 출력 형식
operations.add(context ->
new Document("$sort",
new Document("logTime", logGenericRequest.getOrderBy().equals("ASC") ? 1 : -1)
.append(AdminConstants.MONGO_DB_KEY_TRAN_ID, 1)
)
new Document("$count", "totalCount")
);
AggregationOptions options = AggregationOptions.builder()
.allowDiskUse(true)
.maxTime(Duration.ofSeconds(600))
.build();
Aggregation aggregation = Aggregation.newAggregation(operations).withOptions(options);
log.info("loadBusinessLogData Generic Query: {}", aggregation);
AggregationResults<T> results = getMongoTemplate()
.aggregate(aggregation, AdminConstants.MONGO_DB_COLLECTION_LOG, class1);
return results.getMappedResults();
log.info("loadRawLogData Generic Query: {}", aggregation);
AggregationResults<GenericMongoLog> results = getMongoTemplate()
.aggregate(aggregation, AdminConstants.MONGO_DB_COLLECTION_LOG, GenericMongoLog.class);
if (results.getMappedResults().isEmpty()) return 0;
return results.getMappedResults().get(0).getTotalCount();
}
protected Criteria makeCriteria(String startTime, String endTime) {
return new Criteria()
.andOperator(
Criteria.where(AdminConstants.MONGO_DB_KEY_LOGTIME).gte(startTime).lt(endTime)
);
}
private <T> T parseLog(GenericMongoLog rawLog, Class<T> class1) {
try {
JsonNode messageNode = CommonUtils.stringByJsonNode(rawLog.getMessage());
JsonNode header = messageNode.get("Header");
JsonNode body = messageNode.get("Body");
private Map<String, Object> flattenDocument(Document document) {
Map<String, Object> result = new LinkedHashMap<>();
flattenDocumentRecursive(document, "", result);
return result;
}
// 필드 추출 (정규식 대신 JSON 파싱)
String userGuid = extractStringValue(header, "UserGuid");
String userNickname = extractStringValue(header, "UserNickname");
String accountId = extractStringValue(header, "AccountId");
String tranId = extractStringValue(header, "TranId");
String action = extractStringValue(body, "Action");
String domain = extractDomainFromInfos(body);
private void flattenDocumentRecursive(Object obj, String prefix, Map<String, Object> result) {
if (obj instanceof Document) {
Document doc = (Document) obj;
for (String key : doc.keySet()) {
Object value = doc.get(key);
String newKey = prefix.isEmpty() ? key : prefix + "." + key;
// 타겟 객체 생성
if (class1 == GenericLog.class) {
Map<String, Object> headerMap = CommonUtils.nodeByValue(header, Map.class);
Map<String, Object> bodyMap = CommonUtils.nodeByValue(body, Map.class);
if (value instanceof Document || value instanceof Map) {
flattenDocumentRecursive(value, newKey, result);
} else if (value instanceof List) {
// 리스트의 각 항목에 대해 처리
List<?> list = (List<?>) value;
result.put(newKey, list);
GenericLog log = GenericLog.builder()
.logTime(rawLog.getLogTime())
.userGuid(userGuid)
.userNickname(userNickname)
.accountId(accountId)
.tranId(tranId)
.action(action)
.domain(domain)
.header(headerMap)
.body(bodyMap)
.build();
// 리스트 항목이 복잡한 객체인 경우 각각 평탄화
for (int i = 0; i < list.size(); i++) {
Object listItem = list.get(i);
if (listItem instanceof Document || listItem instanceof Map) {
flattenDocumentRecursive(listItem, newKey + "[" + i + "]", result);
}
}
} else {
result.put(newKey, value);
}
return (T) log;
}
} else if (obj instanceof Map) {
Map<?, ?> map = (Map<?, ?>) obj;
for (Map.Entry<?, ?> entry : map.entrySet()) {
String key = entry.getKey().toString();
Object value = entry.getValue();
String newKey = prefix.isEmpty() ? key : prefix + "." + key;
if (value instanceof Document || value instanceof Map) {
flattenDocumentRecursive(value, newKey, result);
} else if (value instanceof List) {
// 리스트의 각 항목에 대해 처리
List<?> list = (List<?>) value;
result.put(newKey, list);
} catch (Exception e) {
log.warn("Failed to parse log: {}", e.getMessage());
}
return null;
}
// 리스트 항목이 복잡한 객체인 경우 각각 평탄화
for (int i = 0; i < list.size(); i++) {
Object listItem = list.get(i);
if (listItem instanceof Document || listItem instanceof Map) {
flattenDocumentRecursive(listItem, newKey + "[" + i + "]", result);
}
}
} else {
result.put(newKey, value);
private String extractStringValue(JsonNode node, String fieldName) {
if (node == null) return "";
JsonNode valueNode = node.get(fieldName);
if(valueNode != null && !valueNode.isNull()) return valueNode.asText();
if(node.has("Actor")){
JsonNode actor = node.get("Actor");
JsonNode actorNode = actor.get(fieldName);
if(actorNode != null) {
return actorNode.isNull() ? "" : actorNode.asText();
}
}
return "";
}
private String extractDomainFromInfos(JsonNode body) {
if (body != null && body.has("Infos") && body.get("Infos").isArray()) {
JsonNode infos = body.get("Infos");
if (!infos.isEmpty()) {
JsonNode firstInfo = infos.get(0);
if (firstInfo.has("Domain")) {
return firstInfo.get("Domain").asText();
}
}
}
return "";
}
}

View File

@@ -103,7 +103,7 @@ public abstract class BusinessLogServiceBase implements IBusinessLogService {
new Document("$toString",
new Document("$arrayElemAt", List.of("$userGuid.captures", 0))
),
"None"
""
)
)
)
@@ -113,7 +113,7 @@ public abstract class BusinessLogServiceBase implements IBusinessLogService {
new Document("$toString",
new Document("$arrayElemAt", List.of("$userNickname.captures", 0))
),
"None"
""
)
)
)
@@ -123,7 +123,7 @@ public abstract class BusinessLogServiceBase implements IBusinessLogService {
new Document("$toString",
new Document("$arrayElemAt", List.of("$accountId.captures", 0))
),
"None"
""
)
)
)

View File

@@ -0,0 +1,210 @@
package com.caliverse.admin.logs.logservice.indicators;
import com.caliverse.admin.Indicators.Indicatordomain.IndicatorsLog;
import com.caliverse.admin.Indicators.Indicatorsservice.base.IndicatorsLogLoadServiceBase;
import com.caliverse.admin.Indicators.entity.CurrencyLogInfo;
import com.caliverse.admin.Indicators.indicatorrepository.IndicatorCurrencyRepository;
import com.caliverse.admin.domain.entity.common.SearchUserType;
import com.caliverse.admin.global.common.constants.AdminConstants;
import com.caliverse.admin.logs.Indicatordomain.CurrencyMongoLog;
import com.caliverse.admin.logs.logservice.businesslogservice.BusinessLogCurrencyService;
import com.caliverse.admin.mongodb.dto.MongoPageResult;
import lombok.extern.slf4j.Slf4j;
import org.bson.Document;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.*;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
@Slf4j
@Service
public class IndicatorsCurrencyService extends IndicatorsLogLoadServiceBase {
@Autowired private IndicatorCurrencyRepository indicatorCurrencyRepository;
@Autowired private BusinessLogCurrencyService currencyService;
public IndicatorsCurrencyService(@Qualifier("mongoIndicatorTemplate") MongoTemplate mongoTemplate) {
super(mongoTemplate);
}
public void collectCurrency(String startTime, String endTime){
String logTimeStr = startTime.substring(0, 10);
List<CurrencyMongoLog> indicatorsLog = null;
indicatorsLog = currencyService.loadBusinessLogData(startTime, endTime, CurrencyMongoLog.class);
if (indicatorsLog == null || indicatorsLog.isEmpty()) {
log.info("collectCurrency indicatorsLog Log logDay: {} null", logTimeStr);
return;
}
for(CurrencyMongoLog mongo_log : indicatorsLog){
String logDay = mongo_log.getLogDay();
CurrencyLogInfo currencyLog = new CurrencyLogInfo(logDay,
mongo_log.getAccountId(),
mongo_log.getUserGuid(),
mongo_log.getUserNickname(),
mongo_log.getSapphireAcquired(),
mongo_log.getSapphireConsumed(),
mongo_log.getSapphireNet(),
mongo_log.getGoldAcquired(),
mongo_log.getGoldConsumed(),
mongo_log.getGoldNet(),
mongo_log.getCaliumAcquired(),
mongo_log.getCaliumConsumed(),
mongo_log.getCaliumNet(),
mongo_log.getBeamAcquired(),
mongo_log.getBeamConsumed(),
mongo_log.getBeamNet(),
mongo_log.getRubyAcquired(),
mongo_log.getRubyConsumed(),
mongo_log.getRubyNet(),
mongo_log.getTotalCurrencies(),
mongo_log.getCurrencies()
);
log.info("collectCurrency Currency Log Save logDay: {}, info: {}", logDay, currencyLog);
saveStatLogData(currencyLog);
}
}
private void saveStatLogData(IndicatorsLog indicatorsLog) {
if (indicatorsLog instanceof CurrencyLogInfo logInfo) {
try {
indicatorCurrencyRepository.save(logInfo);
} catch (Exception e) {
log.error("Error Repository Write CurrencyLogInfo: {}, Message: {}", logInfo, e.getMessage());
}
} else {
log.error("Not instanceof CurrencyLogInfo");
}
}
@Override
public <T extends IndicatorsLog> List<T> getIndicatorsLogData(String startTime, String endTime, Class<T> clazz) {
Criteria criteria = makeCriteria(startTime, endTime, AdminConstants.MONGO_DB_KEY_LOGDAY);
ProjectionOperation projection = Aggregation.project()
.and("_id").as("id")
.and(AdminConstants.MONGO_DB_KEY_LOGDAY).as("logDay")
.and(AdminConstants.MONGO_DB_KEY_ACCOUNT_ID).as("accountId")
.and(AdminConstants.MONGO_DB_KEY_USER_GUID).as("userGuid")
.and(AdminConstants.MONGO_DB_KEY_USER_NICKNAME).as("userNickname")
.and("sapphireAcquired").as("sapphireAcquired")
.and("sapphireConsumed").as("sapphireConsumed")
.and("sapphireNet").as("sapphireNet")
.and("goldAcquired").as("goldAcquired")
.and("goldConsumed").as("goldConsumed")
.and("goldNet").as("goldNet")
.and("caliumAcquired").as("caliumAcquired")
.and("caliumConsumed").as("caliumConsumed")
.and("caliumNet").as("caliumNet")
.and("beamAcquired").as("beamAcquired")
.and("beamConsumed").as("beamConsumed")
.and("beamNet").as("beamNet")
.and("rubyAcquired").as("rubyAcquired")
.and("rubyConsumed").as("rubyConsumed")
.and("rubyNet").as("rubyNet")
.and("totalCurrencies").as("totalCurrencies")
.and("currencies").as("currencies");
List<AggregationOperation> operations = List.of(
Aggregation.match(criteria),
projection,
Aggregation.sort(Sort.Direction.ASC, AdminConstants.MONGO_DB_KEY_LOGDAY)
);
Aggregation aggregation = Aggregation.newAggregation(operations);
return mongoTemplate.aggregate(aggregation, AdminConstants.MONGO_DB_COLLECTION_CURRENCY, clazz).getMappedResults();
}
public <T extends IndicatorsLog> MongoPageResult<T> getCurrencyDetailLogData(
String searchType,
String searchData,
String tranId,
String startTime,
String endTime,
String orderBy,
Integer page,
Integer size,
Class<T> clazz
) {
Criteria criteria = makeCriteria(startTime, endTime, AdminConstants.MONGO_DB_KEY_LOGDAY);
if(tranId != null && !tranId.isEmpty()){
criteria.and("currencies.tranId").is(tranId);
}
if(searchData != null && !searchData.isEmpty()){
switch (searchType){
case "GUID":
criteria.and("userGuid").is(searchData);
break;
case "NICKNAME":
criteria.and("userNickname").is(searchData);
break;
case "ACCOUNT":
criteria.and("accountId").is(searchData);
break;
default:
log.error("searchType: {} not support", searchType);
return null;
}
}
UnwindOperation unwindOperation = Aggregation.unwind("currencies");
ProjectionOperation projection = Aggregation.project()
.and("_id").as("id")
.and(AdminConstants.MONGO_DB_KEY_LOGDAY).as("logDay")
.and(AdminConstants.MONGO_DB_KEY_ACCOUNT_ID).as("accountId")
.and(AdminConstants.MONGO_DB_KEY_USER_GUID).as("userGuid")
.and(AdminConstants.MONGO_DB_KEY_USER_NICKNAME).as("userNickname")
.and("currencies.tranId").as("tranId")
.and("currencies.logTime").as("logTime")
.and("currencies.action").as("action")
.and("currencies.currencyType").as("currencyType")
.and("currencies.amountDeltaType").as("amountDeltaType")
.and("currencies.deltaAmount").as("deltaAmount");
List<AggregationOperation> baseOperations = List.of(
Aggregation.match(criteria),
unwindOperation,
projection,
Aggregation.sort(orderBy.equals("ASC") ? Sort.Direction.ASC : Sort.Direction.DESC, AdminConstants.MONGO_DB_KEY_LOGDAY)
);
int totalCount = 0;
if(page != null && page != 0) {
List<AggregationOperation> countOperations = new ArrayList<>(baseOperations);
countOperations.add(Aggregation.count().as("total"));
Aggregation countAggregation = Aggregation.newAggregation(countOperations);
Document countResult = mongoTemplate.aggregate(countAggregation, AdminConstants.MONGO_DB_COLLECTION_CURRENCY, Document.class)
.getUniqueMappedResult();
totalCount = countResult != null ? countResult.getInteger("total") : 0;
}
List<AggregationOperation> dataOperations = new ArrayList<>(baseOperations);
if(page != null && page != 0) {
int skip = (page - 1) * size;
dataOperations.add(Aggregation.skip((long) skip));
dataOperations.add(Aggregation.limit(size));
}
Aggregation aggregation = Aggregation.newAggregation(dataOperations);
List<T> items = mongoTemplate.aggregate(aggregation, AdminConstants.MONGO_DB_COLLECTION_CURRENCY, clazz)
.getMappedResults();
return new MongoPageResult<>(items, totalCount);
}
}

View File

@@ -0,0 +1,16 @@
package com.caliverse.admin.mongodb.dto;
import lombok.Data;
import java.util.List;
@Data
public class MongoPageResult<T> {
private final List<T> items;
private final int totalCount;
public MongoPageResult(List<T> items, int totalCount) {
this.items = items;
this.totalCount = totalCount;
}
}

View File

@@ -1,20 +1,11 @@
package com.caliverse.admin.scheduler.batch;
import com.caliverse.admin.domain.RabbitMq.MessageHandlerService;
import com.caliverse.admin.domain.service.BlackListService;
import com.caliverse.admin.domain.service.EventService;
import com.caliverse.admin.domain.service.MailService;
import com.caliverse.admin.domain.service.NoticeService;
import com.caliverse.admin.global.common.constants.AdminConstants;
import com.caliverse.admin.global.common.utils.ExcelUtils;
import com.caliverse.admin.logs.Indicatordomain.StartEndTime;
import com.caliverse.admin.logs.logservice.LogServiceHelper;
import com.caliverse.admin.logs.logservice.indicators.*;
import com.caliverse.admin.redis.service.RedisUserInfoService;
import com.caliverse.admin.scheduler.DynamicScheduler;
import com.caliverse.admin.scheduler.SchedulerManager;
import com.caliverse.admin.scheduler.batch.service.LogCompressService;
import com.caliverse.admin.scheduler.entity.SchedulerType;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
@@ -34,6 +25,7 @@ public class ScheduleRunnerBatch {
@Autowired private IndicatorsUserCreateService userCreateService;
@Autowired private IndicatorsUserLoginService userLoginService;
@Autowired private IndicatorsCurrencyService currencyService;
//log backup
@Scheduled(cron = "00 00 00 1 * ?") // 매월 1일에 실행
@@ -53,4 +45,10 @@ public class ScheduleRunnerBatch {
userLoginService.collectUserLogin(startEndTime.getStartTime(), startEndTime.getEndTime());
}
@Scheduled(cron = "00 31 0 * * *") // 매일 UTC 기준 00시 31분 00초에 실행
public void currencyInfoScheduler() {
StartEndTime startEndTime = LogServiceHelper.getCurrentLogSearchEndTime(AdminConstants.STAT_DAY_NUM);
currencyService.collectCurrency(startEndTime.getStartTime(), startEndTime.getEndTime());
}
}