2022-09-05-TIL
2022-09-05-TIL
Today I Learned
Logging
애플리케이션 로그를 어디에서, 무엇을, 어떤 형식으로 남길지에 관한 자료를 모았다. 요청·응답 전체를 남기는 방법으로는 서블릿 필터에서 ContentCachingRequestWrapper로 본문을 캐시하는 방식과, Spring이 제공하는 CommonsRequestLoggingFilter를 쓰는 방식이 있다. Filter, Interceptor, AOP 중 어디에서 남길지는 8월 26일 TIL에 정리했다.
로그는 두 부류로 나눠 생각할 수 있다. 시스템 로그는 장애를 찾고 동작을 이해하기 위한 기록이고, 이벤트(데이터) 로그는 사용자 행동을 분석하기 위한 기록이다. 데이터 이벤트 로그 정의 글은 후자를 다룬다. 이벤트 로그는 분석가가 쿼리할 대상이므로 이벤트 이름, 속성, 발생 시점을 미리 정의한 스키마대로 남기는 것이 중요하다.
- https://stackoverflow.com/questions/49467489/logginginterceptor-or-aop-logging
- https://speakerdeck.com/devinjeon/jamag-ndc19-joheun-rogeuran-mueosinga-joheun-rogeureul-wihae-goryeohaeya-hal-geosdeul?slide=22
- https://zzsza.github.io/data/2021/06/13/data-event-log-definition/
- https://www.baeldung.com/spring-http-logging
- https://stackoverflow.com/questions/33744875/spring-boot-how-to-log-all-requests-and-responses-with-exceptions-in-single-pl
- https://coralogix.com/blog/spring-boot-logging-best-practices-guide/
- https://www.papertrail.com/solution/tips/7-best-practices-for-c-logging-with-examples/
- https://prashant-prasannakumaran.co.in/rest-api/logging-best-practices/
- https://stackoverflow.com/questions/576185/logging-best-practices
- https://www.dataset.com/blog/the-10-commandments-of-logging/
- https://www.youtube.com/watch?v=Ftc6YmyU0nQ
- https://www.dataset.com/blog/the-10-commandments-of-logging/
- https://www.youtube.com/watch?v=_V-x6_uj91Y
Good Logging
좋은 로그의 기준을 두 자료로 정리하면 다음과 같다.
Heroku Dev Center 가이드는 무엇을 남길지부터 정하라고 한다. 애플리케이션 에러, 입력·출력 검증 실패, 인증 성공과 실패, 인가 실패, 데이터 가져오기·내보내기 같은 이벤트는 항상 남긴다. 메시지에는 무엇을 했는지, 누가 했는지, 왜 실패했는지와 요청 ID 같은 맥락을 넣는다. Address removed.보다 Address removed by customer. {"addressid":18344857, "customerid":50333}처럼 키-값 구조로 남기면 검색과 집계가 쉬워진다. 개인정보와 비밀 키는 남기지 않고, 레벨은 의미에 맞게 고른다. WARN은 사용자 영향이 없는 잠재적 문제, ERROR는 사용자에게 영향이 있는 문제다(Heroku: Writing Best Practices For Application Logs).
Henrik Warne의 글은 경험에서 나온 조언이다. 로그를 너무 많이 남기는 것보다 부족하게 남기는 경우가 훨씬 흔하다고 보고, 작업의 시작·전환·끝과 실패할 수 있는 지점마다 남기라고 한다. 메시지에는 서버 주소, 파일 이름, 건수 같은 동적인 값을 넣고, grep으로 코드 위치를 바로 찾을 수 있는 고유한 문구를 쓰라고 권한다. 실제 장애를 조사하면서 부족했던 정보를 계속 보강하는 것도 방법으로 든다.
- https://devcenter.heroku.com/articles/writing-best-practices-for-application-logs
- https://www.chaossearch.io/blog/log-management-best-practices
- https://www.loomsystems.com/blog/single-post/2017/01/26/9-logging-best-practices-based-on-hands-on-experience
- https://henrikwarne.com/2020/07/23/good-logging/
- https://www.loggly.com/blog/30-best-practices-logging-scale/
- https://www.atatus.com/blog/9-best-practice-for-application-logging-that-you-must-know/
- https://dev.splunk.com/enterprise/docs/developapps/addsupport/logging/loggingbestpractices/
- https://www.dnsstuff.com/logging-monitoring-best-practices
- https://www.synopsys.com/blogs/software-security/logging-and-monitoring-best-practices/
- https://blog.lulab.net/programmer/what-should-i-log-with-an-intention-method-and-level/
- https://narusas.github.io/2017/11/14/logging.html
Java Logging Best Practices
Java에서 자주 언급되는 관행은 다음과 같다.
- SLF4J 같은 로깅 퍼사드에 의존하고 구현체(Logback, Log4j2)는 설정으로 고른다.
- 문자열 연결 대신 파라미터 치환을 쓴다.
log.debug("user={}", id)는 DEBUG가 꺼져 있으면 메시지를 만들지 않는다. - 예외는 메시지만 남기지 말고 예외 객체를 마지막 인자로 넘겨 스택 트레이스를 함께 남긴다. 같은 예외를 여러 계층에서 반복해 남기지 않는다.
- 여러 서버와 스레드에 흩어진 로그를 한 요청으로 묶으려면 MDC(Mapped Diagnostic Context)에 요청 ID를 넣고 로그 패턴에 출력한다. 스레드 풀을 쓰는 비동기 작업에는 MDC 값이 자동으로 넘어가지 않으므로 직접 전달해야 한다.
1
2
3
4
5
6
MDC.put("requestId", requestId);
try {
log.info("주문 생성 시작 orderId={}", orderId);
} finally {
MDC.clear();
}
- https://sematext.com/blog/java-logging-best-practices/
- https://www.atatus.com/blog/best-practices-in-java-logging/
- https://stackoverflow.com/questions/1770442/java-custom-logger-logging-standards-or-and-best-practices
- https://stackoverflow.com/questions/62987588/logging-best-practices-structure-conditional-logging-filtering
- https://stackoverflow.com/questions/296150/what-are-the-best-practices-to-log-an-error
- https://stackoverflow.com/questions/43496695/java-logging-best-practices-in-multi-node-environment
- https://stackify.com/java-logging-best-practices/
- https://coralogix.com/blog/java-logging-best-practices-for-success-with-your-java-application/
- https://stackoverflow.com/questions/906233/logging-in-java-and-in-general-best-practices
- https://www.alibabacloud.com/blog/java-logging-frameworks-summary-and-best-practices_598223
- https://lightrun.com/best-practices/logging-best-practices-mdc-ingestion-and-scale/
- https://www.atatus.com/blog/best-practices-in-java-logging/
- https://www.papertrail.com/solution/tips/logging-in-java-best-practices-and-tips/
- https://www.loggly.com/use-cases/java-logging-best-practices/
로그 시스템 설계
서버가 여러 대이거나 컨테이너로 자주 교체되면 각 서버의 로그 파일을 직접 보는 방식은 한계가 있다. 그래서 로그 시스템은 보통 수집(각 노드의 에이전트가 로그를 읽음), 전송·버퍼링(Kafka 같은 큐로 순간 부하를 흡수), 저장·색인(Elasticsearch, 오브젝트 스토리지), 조회·시각화(Kibana 등) 단계로 나눈다. Kubernetes 같은 컨테이너 환경에서는 컨테이너가 사라지면 로컬 파일도 함께 사라지므로 표준 출력으로 내보내고 노드 단위 에이전트가 수집하는 구성이 흔하다. 설계할 때는 보존 기간, 비용, 검색 지연, 개인정보 마스킹을 함께 정해야 한다.
- https://netmarble.engineering/observability-logging-b/
- https://techblog.woowahan.com/2536/
- https://brunch.co.kr/@tentuplay/29
- https://www.slideshare.net/SooKyungChoi/log-design
- https://bae200ok.medium.com/%EC%9A%B0%EB%A6%AC%EA%B0%80-%EC%95%8C%EC%95%84%EC%95%BC-%ED%95%A0-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EB%A1%9C%EA%B9%85-b979065819f6
- https://www.ibm.com/docs/ko/db2/11.1?topic=strategies-database-logging
- https://bahnsville.tistory.com/1039
- https://www.youtube.com/watch?v=DphnpWVYeG8
- https://blog.tentuplay.io/en/data-logging-part-2-the-4-steps-of-designing-and-constructing-a-log-system
- https://www.alibabacloud.com/blog/design-and-practices-of-kubernetes-log-systems_596357
랜딩 페이지
랜딩 페이지는 광고나 검색 결과를 클릭한 방문자가 처음 도착하는 페이지로, 가입이나 구매 같은 하나의 행동을 유도하도록 만든 단일 목적 페이지다. 이벤트 로그 설계에서는 유입 경로(광고 캠페인 파라미터)와 전환 여부를 남겨야 랜딩 페이지의 효과를 측정할 수 있다.
- https://ko.wix.com/blog/amp/what-are-landing-pages-how-to-use-them-wisely?utm_source=google&utm_medium=cpc&utm_campaign=14051298432^124501874839&experiment_id=^^535938152124^^_DSA&gclid=Cj0KCQjwmdGYBhDRARIsABmSEeOFhe0S1i1G_CAS_u7iPC0R4Iy-uWTbb-l9m7NhG2_aaEZnoWMJxdcaAjM2EALw_wcB
웹 아키텍처
“신입 웹 개발자일 때 알았더라면 좋았을 기본 웹 아키텍처 개념” 글은 웹 서비스를 이루는 구성 요소를 하나씩 설명한다. DNS, 로드 밸런서, 웹 애플리케이션 서버, 데이터베이스 서버, 캐싱 서비스, 잡 큐와 워커, 전체 텍스트 검색 서비스, 서비스(마이크로서비스), 데이터 파이프라인, 클라우드 스토리지, CDN 순서다. 요청 하나가 DNS 조회부터 로드 밸런서, 애플리케이션 서버, 캐시와 DB를 거쳐 돌아오는 경로를 그려 보는 데 도움이 된다.
- https://kschoi.github.io/cs/the-basic-archtecture-concepts/
참고한 자료외부 출처 4
외부 출처
- spring.io/guides
- Heroku Dev Center: Writing Best Practices For Application Logs
- Henrik Warne: Good Logging
- Spring 공식 가이드 모음이다. REST 서비스, 데이터 접근, 배치, 보안 같은 주제별로 짧은 실습 프로젝트를 제공한다.
댓글
아직 댓글이 없습니다