-
Notifications
You must be signed in to change notification settings - Fork 11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Step3-3] observability 추가. #111
base: Sung-Heon
Are you sure you want to change the base?
Conversation
src/main/java/community/whatever/onembackendjava/config/RequestLoggingFilter.java
Outdated
Show resolved
Hide resolved
src/main/java/community/whatever/onembackendjava/config/RequestLoggingFilter.java
Outdated
Show resolved
Hide resolved
if (clientIp == null || clientIp.isEmpty() || "unknown".equalsIgnoreCase(clientIp)) { | ||
clientIp = request.getRemoteAddr(); | ||
} | ||
return clientIp; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이 로직 의도가 무엇인가요?
- if 문 3개의 조건이 같습니다?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ip를 찾기 위한 겁니다.
- 같은 조건이 3번 반복하는 이유는 헤더가 X-Forwarded-For 일지, Proxy-Client-IP일지, WL-Proxy-Client-IP
일지 모르기 때문입니다. 비율이 높은 순으로 되어있습니다. - 음.. 저도 첨에 봤을땐 더 좋은 방법이 없나 고민을 했었는데 for문을 돌리는것보다 이게 직관적이라고 생각했고, 영어로든 한국어로든 ip를 찾는 코드스니펫으로 많이 나오는 코드더라구요.
그렇다면 커뮤니케이션 비용상 굳이 더 창의적인 방법을 고안하거나 효율적인 방법을 고민할 필요가 없겠다는 생각이었습니다.
클라이언트 ip를 가져오는게 그렇게 대단한 로직이 필요한것은 아니니까요.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
사실 저는 이런 코드를 작성해본 적은 없습니다.
- 실무에서는 보통 솔루션을 (datadog, newrelic, sentry) 사용하기 때문 입니다.
private String getClientIp(HttpServletRequest request) {
String clientIp = request.getHeader("X-Forwarded-For");
if (clientIp == null || clientIp.isEmpty() || "unknown".equalsIgnoreCase(clientIp)) {
clientIp = request.getHeader("Proxy-Client-IP"); // clientIp 가 이 값으로 retrun 되는 경우가 발생할 수 있는가?
}
if (clientIp == null || clientIp.isEmpty() || "unknown".equalsIgnoreCase(clientIp)) {
clientIp = request.getHeader("WL-Proxy-Client-IP"); // clientIp 가 이 값으로 retrun 되는 경우가 발생할 수 있는가?
}
if (clientIp == null || clientIp.isEmpty() || "unknown".equalsIgnoreCase(clientIp)) {
clientIp = request.getRemoteAddr(); // 앞의 if 문에서 true 가 나오면 여기도 true 가 나오기 때문에 항상 이 값으로 나오는거 아닌가?
}
return clientIp;
}
근데 전 아무리 읽어봐도 해당 로직이 이해가 잘 안되요.
제가 주석 단 것에 답변을 주실 수 있나요?
통상적으로 쓰이는 코드 스니펫이라는 것은 이해하는데, 그것을 가져와서 내 애플리케이션에 붙이면 이제 내 코드가 되는 것 입니다.
- 향후 이것으로 이슈가 되도 원본 글 작성자를 탓할 수는 없으니까요.
- 관련되어 자체 테스트라도 진행 해보셨나요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
통상적으로 쓰이는 코드 스니펫이라는 것은 이해하는데, 그것을 가져와서 내 애플리케이션에 붙이면 이제 내 코드가 되는 것 입니다.
네 그렇게 생각하고 있습니다.
관련되어 자체 테스트라도 진행 해보셨나요?
네 진행한거 첨부하였습니다.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
private String getClientIp(HttpServletRequest request) {
// 확인할 헤더 목록을 우선순위 순서대로 배열에 저장
String[] headerNames = {
"X-Forwarded-For",
"Proxy-Client-IP",
"WL-Proxy-Client-IP"
};
// 각 헤더를 순차적으로 확인
for (String headerName : headerNames) {
String headerValue = request.getHeader(headerName);
// 유효한 IP 주소가 있는 경우 즉시 반환
if (isValidIp(headerValue)) {
return headerValue;
}
}
// 모든 헤더가 유효하지 않은 경우 remoteAddr 반환
return request.getRemoteAddr();
}
/**
* IP 주소가 유효한지 확인
* null이 아니고, 비어있지 않고, "unknown"이 아닌 경우 유효함
*/
private boolean isValidIp(String ip) {
return ip != null && !ip.isEmpty() && !"unknown".equalsIgnoreCase(ip);
}
흠.. 이렇게 하는게 나을뻔했네요.
(사실 ip주소가져오는 코드를 볼일이 별로없으니..그냥 직관적으로 이해되게.)
다시보니까 filter랑 logger랑 분리하는게 나을것 같아서 그부분도 살짝(?) 리팩토링했습니다. |
if (clientIp == null || clientIp.isEmpty() || "unknown".equalsIgnoreCase(clientIp)) { | ||
clientIp = request.getRemoteAddr(); | ||
} | ||
return clientIp; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
사실 저는 이런 코드를 작성해본 적은 없습니다.
- 실무에서는 보통 솔루션을 (datadog, newrelic, sentry) 사용하기 때문 입니다.
private String getClientIp(HttpServletRequest request) {
String clientIp = request.getHeader("X-Forwarded-For");
if (clientIp == null || clientIp.isEmpty() || "unknown".equalsIgnoreCase(clientIp)) {
clientIp = request.getHeader("Proxy-Client-IP"); // clientIp 가 이 값으로 retrun 되는 경우가 발생할 수 있는가?
}
if (clientIp == null || clientIp.isEmpty() || "unknown".equalsIgnoreCase(clientIp)) {
clientIp = request.getHeader("WL-Proxy-Client-IP"); // clientIp 가 이 값으로 retrun 되는 경우가 발생할 수 있는가?
}
if (clientIp == null || clientIp.isEmpty() || "unknown".equalsIgnoreCase(clientIp)) {
clientIp = request.getRemoteAddr(); // 앞의 if 문에서 true 가 나오면 여기도 true 가 나오기 때문에 항상 이 값으로 나오는거 아닌가?
}
return clientIp;
}
근데 전 아무리 읽어봐도 해당 로직이 이해가 잘 안되요.
제가 주석 단 것에 답변을 주실 수 있나요?
통상적으로 쓰이는 코드 스니펫이라는 것은 이해하는데, 그것을 가져와서 내 애플리케이션에 붙이면 이제 내 코드가 되는 것 입니다.
- 향후 이것으로 이슈가 되도 원본 글 작성자를 탓할 수는 없으니까요.
- 관련되어 자체 테스트라도 진행 해보셨나요?
Zipkin: 분산 트레이싱 (포트: 9411)
Prometheus: 메트릭 수집 (포트: 9090)
Grafana: 대시보드 시각화 (포트: 3000)
네트워크 및 볼륨 설정
RequestLoggingFilter 클래스 구현
모든 HTTP 요청 메서드, URI, 상태 코드, 처리 시간, IP 주소 로깅
POST/PUT/PATCH 요청의 본문(body) 내용 로깅
ContentCachingRequestWrapper를 사용하여 요청 본문 캡처