-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #86 from Akatsuki-USW/develop
- Loading branch information
Showing
10 changed files
with
240 additions
and
29 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
51 changes: 51 additions & 0 deletions
51
src/main/java/bokjak/bokjakserver/web/log/LoggerAspect.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
package bokjak.bokjakserver.web.log; | ||
|
||
import jakarta.servlet.http.HttpServletRequest; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.aspectj.lang.ProceedingJoinPoint; | ||
import org.aspectj.lang.annotation.Around; | ||
import org.aspectj.lang.annotation.Aspect; | ||
import org.aspectj.lang.annotation.Pointcut; | ||
import org.json.simple.JSONObject; | ||
import org.springframework.stereotype.Component; | ||
import org.springframework.web.context.request.RequestContextHolder; | ||
import org.springframework.web.context.request.ServletRequestAttributes; | ||
|
||
import java.util.Enumeration; | ||
import java.util.Objects; | ||
|
||
@Component | ||
@Aspect | ||
@Slf4j | ||
public class LoggerAspect { | ||
@Pointcut("execution(* bokjak.bokjakserver..*Controller.*(..)) || execution(* bokjak.bokjakserver..*GlobalExceptionHandler.*(..))") | ||
// 이런 패턴이 실행될 경우 수행 | ||
public void loggerPointCut() { | ||
} | ||
|
||
@Around("loggerPointCut()") | ||
public Object logRequestUri(ProceedingJoinPoint proceedingJoinPoint) throws Throwable { | ||
Object result = proceedingJoinPoint.proceed(); | ||
ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); | ||
|
||
if (Objects.nonNull(requestAttributes)) { | ||
HttpServletRequest request = requestAttributes.getRequest(); // request 정보를 가져온다. | ||
String controllerName = proceedingJoinPoint.getSignature().getDeclaringType().getSimpleName(); | ||
String methodName = proceedingJoinPoint.getSignature().getName(); | ||
log.info("{}.{}: {} {} PARAM={}", controllerName, methodName, request.getMethod(), request.getRequestURI(), extractParams(request)); // param에 담긴 정보들을 한번에 로깅한다. | ||
} | ||
|
||
return result; | ||
} | ||
|
||
private static JSONObject extractParams(HttpServletRequest request) { // request로부터 param 추출, JSONObject로 변환 | ||
JSONObject jsonObject = new JSONObject(); | ||
Enumeration<String> params = request.getParameterNames(); | ||
while (params.hasMoreElements()) { | ||
String param = params.nextElement(); | ||
String replaceParam = param.replaceAll("\\.", "-"); | ||
jsonObject.put(replaceParam, request.getParameter(param)); | ||
} | ||
return jsonObject; | ||
} | ||
} |
143 changes: 143 additions & 0 deletions
143
src/main/java/bokjak/bokjakserver/web/log/ReadableRequestBodyWrapper.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
package bokjak.bokjakserver.web.log; | ||
|
||
import jakarta.servlet.ReadListener; | ||
import jakarta.servlet.ServletInputStream; | ||
import jakarta.servlet.http.HttpServletRequest; | ||
import jakarta.servlet.http.HttpServletRequestWrapper; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.apache.commons.io.IOUtils; | ||
import org.apache.commons.lang3.StringUtils; | ||
import org.apache.http.entity.ContentType; | ||
import org.json.simple.JSONArray; | ||
import org.json.simple.JSONObject; | ||
import org.json.simple.parser.JSONParser; | ||
|
||
import java.io.BufferedReader; | ||
import java.io.ByteArrayInputStream; | ||
import java.io.InputStream; | ||
import java.io.InputStreamReader; | ||
import java.nio.charset.Charset; | ||
import java.nio.charset.StandardCharsets; | ||
import java.util.Collections; | ||
import java.util.Enumeration; | ||
import java.util.HashMap; | ||
import java.util.Map; | ||
import java.util.stream.Collectors; | ||
|
||
@Slf4j | ||
public class ReadableRequestBodyWrapper extends HttpServletRequestWrapper { | ||
private final Charset encoding; | ||
private byte[] rawData; | ||
private final Map<String, String[]> params = new HashMap<>(); | ||
|
||
public ReadableRequestBodyWrapper(HttpServletRequest request) { | ||
super(request); | ||
this.params.putAll(request.getParameterMap()); // 오리지널 요청의 파라미터들 저장 | ||
|
||
String charEncoding = request.getCharacterEncoding(); // 인코딩 설정 | ||
this.encoding = StringUtils.isBlank(charEncoding) ? StandardCharsets.UTF_8 : Charset.forName(charEncoding); | ||
|
||
try { | ||
// 중요: body가 유실되지 않도록 함. getInputStream -> rawData에 저장 -> getReader() 에서 새 스트림으로 생성 | ||
InputStream inputStream = request.getInputStream(); | ||
this.rawData = IOUtils.toByteArray(inputStream); | ||
|
||
// body 파싱 | ||
String collect = this.getReader().lines().collect(Collectors.joining(System.lineSeparator())); | ||
if (StringUtils.isEmpty(collect)) { // body 가 없을경우 종료 | ||
return; | ||
} | ||
if (request.getContentType() != null && request.getContentType().contains( | ||
ContentType.MULTIPART_FORM_DATA.getMimeType())) { // 파일 업로드시 로깅 제외 | ||
return; | ||
} | ||
|
||
JSONParser jsonParser = new JSONParser(); | ||
Object parse = jsonParser.parse(collect); | ||
if (parse instanceof JSONArray) { | ||
JSONArray jsonArray = (JSONArray) jsonParser.parse(collect); | ||
setParameter("requestBody", jsonArray.toJSONString()); | ||
} else { | ||
JSONObject jsonObject = (JSONObject) jsonParser.parse(collect); | ||
for (Object key : jsonObject.keySet()) { | ||
setParameter(key.toString(), jsonObject.get(key.toString()).toString().replace("\"", "\\\"")); | ||
} | ||
} | ||
} catch (Exception e) { | ||
log.error("ReadableRequestWrapper init error", e); | ||
} | ||
} | ||
|
||
@Override | ||
public String getParameter(String name) { | ||
String[] paramArray = getParameterValues(name); | ||
if (paramArray != null && paramArray.length > 0) { | ||
return paramArray[0]; | ||
} else { | ||
return null; | ||
} | ||
} | ||
|
||
@Override | ||
public Map<String, String[]> getParameterMap() { | ||
return Collections.unmodifiableMap(params); | ||
} | ||
|
||
@Override | ||
public Enumeration<String> getParameterNames() { | ||
return Collections.enumeration(params.keySet()); | ||
} | ||
|
||
@Override | ||
public String[] getParameterValues(String name) { | ||
String[] result = null; | ||
String[] dummyParamValue = params.get(name); | ||
|
||
if (dummyParamValue != null) { | ||
result = new String[dummyParamValue.length]; | ||
System.arraycopy(dummyParamValue, 0, result, 0, dummyParamValue.length); | ||
} | ||
return result; | ||
} | ||
|
||
public void setParameter(String name, String value) { | ||
String[] param = {value}; | ||
setParameter(name, param); | ||
} | ||
|
||
public void setParameter(String name, String[] values) { | ||
params.put(name, values); | ||
} | ||
|
||
@Override | ||
public ServletInputStream getInputStream() { | ||
final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(this.rawData); | ||
|
||
return new ServletInputStream() { | ||
@Override | ||
public boolean isFinished() { | ||
return false; | ||
} | ||
|
||
@Override | ||
public boolean isReady() { | ||
return false; | ||
} | ||
|
||
@Override | ||
public void setReadListener(ReadListener readListener) { | ||
// Do nothing | ||
} | ||
|
||
public int read() { | ||
return byteArrayInputStream.read(); | ||
} | ||
}; | ||
} | ||
|
||
@Override | ||
public BufferedReader getReader() { | ||
return new BufferedReader(new InputStreamReader(this.getInputStream(), this.encoding)); | ||
} | ||
} | ||
|
20 changes: 20 additions & 0 deletions
20
src/main/java/bokjak/bokjakserver/web/log/ReadableRequestBodyWrapperFilter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package bokjak.bokjakserver.web.log; | ||
|
||
import jakarta.servlet.FilterChain; | ||
import jakarta.servlet.ServletException; | ||
import jakarta.servlet.annotation.WebFilter; | ||
import jakarta.servlet.http.HttpServletRequest; | ||
import jakarta.servlet.http.HttpServletResponse; | ||
import org.jetbrains.annotations.NotNull; | ||
import org.springframework.web.filter.OncePerRequestFilter; | ||
|
||
import java.io.IOException; | ||
|
||
@WebFilter(urlPatterns = "/*") // 대상: 전체 URI | ||
public class ReadableRequestBodyWrapperFilter extends OncePerRequestFilter { | ||
@Override | ||
protected void doFilterInternal(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { | ||
filterChain.doFilter(new ReadableRequestBodyWrapper(request), response); // 필터 체인에 커스텀 Wrapper 추가 | ||
} | ||
|
||
} |