Skip to content

Commit 730a2cb

Browse files
Release v1.1.1 (#137)
* chore : Bucket4j 의존성 추가 * chore : Bucket4j config 따로 구현 * feat : 처리량 제한 필터 구현 * refactor : RedisConfig 로컬 --> 배포된 레디스 사용해서 커넥션 생성 로직으로 수정 * feat : 필터체인에 처리량 제한 필터 추가 (최상단) * refactor : Redis @value 경로 통일 * 🔥 Delete: 불필요 workflow 삭제 (#132) * ✨ Feat: unified log save (#136) * 🔥 delete: dev workflow 삭제 * ✨ feat: Unified Log Save 로직 추가 * 🔥 delete: PR 공통에서 관리하도록 변경 --------- Co-authored-by: YoungjaeRo <ryj0330@naver.com> Co-authored-by: 노영재 <146312456+YoungjaeRo@users.noreply.github.com>
1 parent 0d7091f commit 730a2cb

10 files changed

Lines changed: 223 additions & 56 deletions

File tree

.github/PULL_REQUEST_TEMPLATE.md

Lines changed: 0 additions & 26 deletions
This file was deleted.

src/main/java/com/example/Tokkit_server/api_request_log/interceptor/ApiLoggingInterceptor.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
import com.example.Tokkit_server.api_request_log.entity.ApiRequestLog;
44
import com.example.Tokkit_server.api_request_log.repository.ApiRequestLogRepository;
55
import com.example.Tokkit_server.global.util.LoggingUtils;
6+
import com.example.Tokkit_server.unified_log.dto.request.UnifiedLogSaveDto;
7+
import com.example.Tokkit_server.unified_log.service.command.UnifiedLogCommandService;
8+
69
import jakarta.servlet.http.HttpServletRequest;
710
import jakarta.servlet.http.HttpServletResponse;
811
import lombok.RequiredArgsConstructor;
@@ -24,6 +27,7 @@
2427
public class ApiLoggingInterceptor implements HandlerInterceptor {
2528

2629
private final ApiRequestLogRepository logRepository;
30+
private final UnifiedLogCommandService unifiedLogCommandService;
2731

2832
// 요청 시작 시간 기록 (responseTime 계산용)
2933
private static final String START_TIME_ATTR = "apiLogStartTime";
@@ -87,6 +91,7 @@ public void afterCompletion(HttpServletRequest request,
8791
.build();
8892

8993
logRepository.save(logEntity);
94+
unifiedLogCommandService.save(UnifiedLogSaveDto.fromApiRequestLog(logEntity));
9095

9196
log.info("[API LOG][{}] {} {} status={} userId={} merchantId={} {}ms",
9297
traceId, request.getMethod(), endpoint, status, userId, merchantId, responseTimeMs);

src/main/java/com/example/Tokkit_server/login_log/listener/LoginLogListener.java

Lines changed: 32 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
import com.example.Tokkit_server.login_log.entity.LoginLog;
55
import com.example.Tokkit_server.login_log.repository.LoginLogRepository;
66
import com.example.Tokkit_server.merchant.auth.CustomMerchantDetails;
7+
import com.example.Tokkit_server.unified_log.dto.request.UnifiedLogSaveDto;
8+
import com.example.Tokkit_server.unified_log.service.command.UnifiedLogCommandService;
79
import com.example.Tokkit_server.user.auth.CustomUserDetails;
810
import jakarta.servlet.http.HttpServletRequest;
911
import lombok.RequiredArgsConstructor;
@@ -27,6 +29,7 @@
2729
public class LoginLogListener {
2830

2931
private final LoginLogRepository logRepository;
32+
private final UnifiedLogCommandService unifiedLogCommandService;
3033

3134
private HttpServletRequest getCurrentRequest() {
3235
return ((ServletRequestAttributes) currentRequestAttributes()).getRequest();
@@ -52,16 +55,20 @@ public void onLoginSuccess(AuthenticationSuccessEvent event) {
5255

5356
log.info("[LOGIN SUCCESS][traceId={}] userId={} merchantId={} ip={}", traceId, userId, merchantId, ip);
5457

55-
logRepository.save(LoginLog.builder()
56-
.userId(userId)
57-
.merchantId(merchantId)
58-
.event(Event.LOGIN)
59-
.timestamp(LocalDateTime.now())
60-
.userAgent(userAgent)
61-
.success(true)
62-
.traceId(traceId)
63-
.ipAddress(ip)
64-
.build());
58+
59+
LoginLog loginLog = LoginLog.builder()
60+
.userId(userId)
61+
.merchantId(merchantId)
62+
.event(Event.LOGIN)
63+
.timestamp(LocalDateTime.now())
64+
.userAgent(userAgent)
65+
.success(true)
66+
.traceId(traceId)
67+
.ipAddress(ip)
68+
.build();
69+
70+
logRepository.save(loginLog);
71+
unifiedLogCommandService.save(UnifiedLogSaveDto.fromLoginLog(loginLog));
6572
}
6673

6774
@EventListener
@@ -72,16 +79,20 @@ public void onLoginFailure(AbstractAuthenticationFailureEvent event) {
7279

7380
log.warn("[LOGIN FAIL][traceId={}] ip={} reason={}", traceId, ip, event.getException().getMessage());
7481

75-
logRepository.save(LoginLog.builder()
76-
.userId(null)
77-
.merchantId(null)
78-
.event(Event.LOGIN)
79-
.timestamp(LocalDateTime.now())
80-
.userAgent(userAgent)
81-
.success(false)
82-
.reason(event.getException().getMessage())
83-
.traceId(traceId)
84-
.ipAddress(ip)
85-
.build());
82+
LoginLog loginLog = LoginLog.builder()
83+
.userId(null)
84+
.merchantId(null)
85+
.event(Event.LOGIN)
86+
.timestamp(LocalDateTime.now())
87+
.userAgent(userAgent)
88+
.success(false)
89+
.reason(event.getException().getMessage())
90+
.traceId(traceId)
91+
.ipAddress(ip)
92+
.build();
93+
94+
logRepository.save(loginLog);
95+
unifiedLogCommandService.save(UnifiedLogSaveDto.fromLoginLog(loginLog));
96+
8697
}
8798
}

src/main/java/com/example/Tokkit_server/system_error_log/service/SystemErrorLogService.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
import com.example.Tokkit_server.system_error_log.entity.SystemErrorLog;
44
import com.example.Tokkit_server.system_error_log.enums.Severity;
55
import com.example.Tokkit_server.system_error_log.repository.SystemErrorLogRepository;
6+
import com.example.Tokkit_server.unified_log.dto.request.UnifiedLogSaveDto;
7+
import com.example.Tokkit_server.unified_log.service.command.UnifiedLogCommandService;
68
import com.example.Tokkit_server.user.utils.JwtUtil;
79
import jakarta.servlet.http.HttpServletRequest;
810
import lombok.RequiredArgsConstructor;
@@ -17,6 +19,7 @@
1719
public class SystemErrorLogService {
1820

1921
private final SystemErrorLogRepository systemErrorLogRepository;
22+
private final UnifiedLogCommandService unifiedLogCommandService;
2023
private final JwtUtil jwtUtil;
2124

2225
public void logError(Exception e, HttpServletRequest request, String traceId) {
@@ -42,6 +45,7 @@ public void logError(Exception e, HttpServletRequest request, String traceId) {
4245
.build();
4346

4447
systemErrorLogRepository.save(logEntity);
48+
unifiedLogCommandService.save(UnifiedLogSaveDto.fromSystemErrorLog(logEntity));
4549
}
4650

4751
private UserOrMerchant extractUserOrMerchantIdFromRequest(HttpServletRequest request) {

src/main/java/com/example/Tokkit_server/transaction/service/query/TransactionLogService.java

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
import com.example.Tokkit_server.transaction.entity.Transaction;
44
import com.example.Tokkit_server.transaction.enums.TransactionType;
55
import com.example.Tokkit_server.transaction.repository.TransactionRepository;
6+
import com.example.Tokkit_server.unified_log.dto.request.UnifiedLogSaveDto;
7+
import com.example.Tokkit_server.unified_log.service.command.UnifiedLogCommandService;
68
import lombok.RequiredArgsConstructor;
79
import lombok.extern.slf4j.Slf4j;
810
import org.springframework.stereotype.Service;
@@ -13,21 +15,23 @@
1315
public class TransactionLogService {
1416

1517
private final TransactionRepository transactionRepository;
18+
private final UnifiedLogCommandService unifiedLogCommandService;
1619

1720
public void logAndSave(Transaction transaction, Long userId, Long merchantId) {
1821
String traceId = transaction.getTraceId();
1922
String target = (transaction.getType() == TransactionType.RECEIVE) ? "MERCHANT" : "USER";
2023

2124
log.info("[TXN][{}] traceId={}, userId={}, merchantId={}, type={}, status={}, amount={}, desc={}",
22-
target,
23-
traceId,
24-
userId != null ? userId : "-",
25-
merchantId != null ? merchantId : "-",
26-
transaction.getType(),
27-
transaction.getStatus(),
28-
transaction.getAmount(),
29-
transaction.getDescription());
25+
target,
26+
traceId,
27+
userId != null ? userId : "-",
28+
merchantId != null ? merchantId : "-",
29+
transaction.getType(),
30+
transaction.getStatus(),
31+
transaction.getAmount(),
32+
transaction.getDescription());
3033

3134
transactionRepository.save(transaction);
35+
unifiedLogCommandService.save(UnifiedLogSaveDto.fromTransactionLog(transaction));
3236
}
33-
}
37+
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
package com.example.Tokkit_server.unified_log.dto.request;
2+
3+
import java.time.LocalDateTime;
4+
5+
import com.example.Tokkit_server.api_request_log.entity.ApiRequestLog;
6+
import com.example.Tokkit_server.login_log.entity.LoginLog;
7+
import com.example.Tokkit_server.system_error_log.entity.SystemErrorLog;
8+
import com.example.Tokkit_server.transaction.entity.Transaction;
9+
10+
public record UnifiedLogSaveDto(
11+
String logType,
12+
String traceId,
13+
Long userId,
14+
Long merchantId,
15+
LocalDateTime timestamp,
16+
String summary,
17+
18+
String detail,
19+
String statusOrSeverity
20+
) {
21+
22+
public static UnifiedLogSaveDto fromLoginLog(LoginLog log) {
23+
return new UnifiedLogSaveDto(
24+
"LOGIN",
25+
log.getTraceId(),
26+
log.getUserId(),
27+
log.getMerchantId(),
28+
log.getTimestamp(),
29+
log.getEvent() + " - " + log.getIpAddress(),
30+
log.getUserAgent(),
31+
log.getSuccess() ? "SUCCESS" : "FAILURE"
32+
);
33+
}
34+
35+
public static UnifiedLogSaveDto fromApiRequestLog(ApiRequestLog log) {
36+
return new UnifiedLogSaveDto(
37+
"API",
38+
log.getTraceId(),
39+
log.getUserId(),
40+
log.getMerchantId(),
41+
log.getTimestamp(),
42+
log.getMethod() + " " + log.getEndpoint(),
43+
log.getQueryParams() + "\n" + log.getRequestBody(),
44+
String.valueOf(log.getResponseStatus())
45+
);
46+
}
47+
48+
public static UnifiedLogSaveDto fromSystemErrorLog(SystemErrorLog log) {
49+
return new UnifiedLogSaveDto(
50+
"ERROR",
51+
log.getTraceId(),
52+
log.getUserId(),
53+
log.getMerchantId(),
54+
log.getTimestamp(),
55+
log.getEndpoint() + " - " + log.getErrorMessage(),
56+
log.getStackTrace(),
57+
log.getSeverity().toString()
58+
);
59+
}
60+
61+
public static UnifiedLogSaveDto fromTransactionLog(Transaction log) {
62+
return new UnifiedLogSaveDto(
63+
"TRANSACTION",
64+
log.getTraceId(),
65+
null,
66+
null,
67+
log.getCreatedAt(),
68+
log.getType() + " - " + log.getAmount(),
69+
log.getDescription(),
70+
log.getStatus().toString()
71+
);
72+
}
73+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package com.example.Tokkit_server.unified_log.entity;
2+
3+
import java.time.LocalDateTime;
4+
5+
import com.example.Tokkit_server.unified_log.dto.request.UnifiedLogSaveDto;
6+
7+
import jakarta.persistence.Column;
8+
import jakarta.persistence.Entity;
9+
import jakarta.persistence.GeneratedValue;
10+
import jakarta.persistence.GenerationType;
11+
import jakarta.persistence.Id;
12+
import jakarta.persistence.Lob;
13+
import lombok.AccessLevel;
14+
import lombok.AllArgsConstructor;
15+
import lombok.Builder;
16+
import lombok.Getter;
17+
import lombok.NoArgsConstructor;
18+
import lombok.extern.java.Log;
19+
20+
@Entity
21+
@Getter
22+
@NoArgsConstructor(access = AccessLevel.PROTECTED)
23+
@AllArgsConstructor
24+
@Builder
25+
public class UnifiedLog {
26+
@Id
27+
@GeneratedValue(strategy = GenerationType.IDENTITY)
28+
private Long id;
29+
30+
private String logType;
31+
private String traceId;
32+
private Long userId;
33+
private Long merchantId;
34+
private LocalDateTime timestamp;
35+
@Column(columnDefinition = "TEXT")
36+
private String summary;
37+
@Lob
38+
@Column(columnDefinition = "LONGTEXT")
39+
private String detail;
40+
private String statusOrSeverity;
41+
public static UnifiedLog fromDto(UnifiedLogSaveDto dto) {
42+
String detail = dto.detail();
43+
if (detail != null && detail.length() > 3000) {
44+
detail = detail.substring(0, 1000);
45+
}
46+
return UnifiedLog.builder()
47+
.logType(dto.logType())
48+
.traceId(dto.traceId())
49+
.userId(dto.userId())
50+
.merchantId(dto.merchantId())
51+
.timestamp(dto.timestamp())
52+
.summary(dto.summary())
53+
.detail(detail)
54+
.statusOrSeverity(dto.statusOrSeverity())
55+
.build();
56+
}
57+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package com.example.Tokkit_server.unified_log.repository;
2+
3+
import org.springframework.data.jpa.repository.JpaRepository;
4+
5+
import com.example.Tokkit_server.unified_log.entity.UnifiedLog;
6+
7+
public interface UnifiedLogRepository extends JpaRepository<UnifiedLog,Long> {
8+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package com.example.Tokkit_server.unified_log.service.command;
2+
3+
import com.example.Tokkit_server.unified_log.dto.request.UnifiedLogSaveDto;
4+
5+
public interface UnifiedLogCommandService {
6+
public void save(UnifiedLogSaveDto dto);
7+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package com.example.Tokkit_server.unified_log.service.command;
2+
3+
import org.springframework.stereotype.Service;
4+
import org.springframework.transaction.annotation.Transactional;
5+
6+
import com.example.Tokkit_server.unified_log.dto.request.UnifiedLogSaveDto;
7+
import com.example.Tokkit_server.unified_log.entity.UnifiedLog;
8+
import com.example.Tokkit_server.unified_log.repository.UnifiedLogRepository;
9+
10+
import lombok.RequiredArgsConstructor;
11+
12+
@Service
13+
@RequiredArgsConstructor
14+
public class UnifiedLogCommandServiceImpl implements UnifiedLogCommandService {
15+
16+
private final UnifiedLogRepository unifiedLogRepository;
17+
18+
@Override
19+
@Transactional
20+
public void save(UnifiedLogSaveDto dto) {
21+
UnifiedLog entity = UnifiedLog.fromDto(dto);
22+
unifiedLogRepository.save(entity);
23+
}
24+
}

0 commit comments

Comments
 (0)