Skip to content

Commit

Permalink
샘플 코드 추가
Browse files Browse the repository at this point in the history
  • Loading branch information
jojoldu committed Mar 8, 2024
1 parent e869fb7 commit 836169b
Showing 1 changed file with 42 additions and 13 deletions.
55 changes: 42 additions & 13 deletions posts/logging/loggin_is_feature/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# 로깅도 기능이다.
# 로깅을 나누기


1. 코드 대 로그/메트릭 비율이 낮다.
Expand All @@ -7,12 +7,12 @@
2. 계측 세부 정보에 대해 더 알아야 한다.
코드에는 사용해야 하는 메트릭 이름과 전달해야 하는 정확한 컨텍스트 내용 등이 참조되어 있다.

```typescript
log.error("Lost touch with Reality after " + timeout + "seconds");
log.trace("Distance traveled in the wilderness: " + distance);
```ts
logger.error(`Lost touch with Reality after ${timeout} seconds`);
logger.trace(`Distance traveled in the wilderness: ${distance}`);
```

이 두 기능은 하나의 구현을 공유하는 별개의 기능이다. 설명해 드리겠다.
이 두 기능은 하나의 구현을 공유하는 별개의 기능이다.

- 에러 로깅(오류 및 정보)은 애플리케이션의 사용자 인터페이스의 일부이다.
- 이는 시스템 관리자 및 운영자뿐만 아니라 에러 담당자가 장애를 디버깅하거나 실행 중인 시스템의 진행 상황을 모니터링하기 위해 추적하기 위한 것이다.
Expand All @@ -21,35 +21,64 @@ log.trace("Distance traveled in the wilderness: " + distance);
- 이는 프로그래머가 개발 중인 시스템 내부에서 어떤 일이 일어나고 있는지 이해하는 데 도움을 주기 위한 것이므로 프로덕션 환경에서는 켜지 말아야 한다.

이러한 차이점을 고려할 때 이 두 가지 유형의 로깅에 서로 다른 기술을 사용하는 것을 고려해야 한다.
에러 로깅은 감사나 장애 복구와 같은 누군가의 요구 사항에 따라 테스트 중심으로 이루어져야 한다.
에러 로깅은 감사 로그나 장애 복구와 같은 누군가의 요구 사항에 따라 테스트 중심으로 이루어져야 한다.
테스트를 통해 각 메시지의 용도를 고려하고 제대로 작동하는지 확인할 수 있다.
또한 테스트는 다른 사람들이 이러한 로그 메시지를 분석하기 위해 작성한 도구와 스크립트가 손상되지 않도록 보호한다.
반면에 디버깅 로깅은 시스템에서 일어나는 일을 세밀하게 추적해야 하는 프로그래머의 필요성으로 적용 한다.
디버깅 로깅은 스캐폴딩이므로 테스트를 거칠 필요가 없으며 에러 로그처럼 메시지가 일관적일 필요도 없다.
결국 이러한 메시지를 운영 환경에서 사용하지 않는다.

로깅이 아닌 알림

로거를 포함한 정적 전역 객체에 대한 단위 테스트를 작성하는 것은 서투른 작업이다.
파일 시스템에서 읽거나 테스트를 위해 추가 애펜더 객체를 관리해야 하며, 테스트가 서로 간섭하지 않도록 나중에 정리하고 올바른 로거에 올바른 수준을 설정해야 한다는 점을 기억해야 한다.
테스트의 노이즈는 코드가 도메인과 로깅 인프라의 두 가지 수준에서 작동하고 있음을 알려준다.

```ts
function removeCart(product: Product) {
httpClient.removeProduct(product.id);
if(product.type === ProductType.FOOD) {
logger.info(`Removed Cart ${product.id}, ${product.name}, ${product.price}`);
}
}
```

루프의 기능적인 부분과 (강조된) 로깅 부분 사이의 어휘와 스타일이 달라진 것을 주목해보자. 이 코드는 위치와 렌더링 에러 정보라는 두 가지 작업을 동시에 수행하므로 단일 책임 원칙을 위반한다.
루프의 기능적인 부분과 로깅 부분 사이의 어휘와 스타일이 달라진 것을 주목해보자.
이 코드는 위치와 렌더링 에러 정보라는 두 가지 작업을 동시에 수행하므로 단일 책임 원칙을 위반한다.

```ts
function removeCart(product: Product) {
httpClient.removeProduct(product.id);
probe.removeFood();
}
```

에러 객체가 로거, 메시지 버스, 팝업 창 등으로 구현될 수 있으며, 이 세부 사항은 이 수준의 코드와 관련이 없다.

이 코드는 테스트하기도 더 쉽다.
로깅 프레임워크가 아닌 우리가 에러 객체를 소유하고 있으므로 편의에 따라 모의 구현을 전달하고 테스트 케이스에 로컬로 유지할 수 있다. 또 다른 단순화는 이제 형식이 지정된 문자열의 내용이 아닌 객체에 대해 테스트한다는 것이다. 물론 물론 여전히 에러 구현과 이에 초점을 맞춘 몇 가지 통합 테스트를 작성해야 한다.
로깅 프레임워크가 아닌 우리가 에러 객체를 소유하고 있으므로 편의에 따라 모의 구현을 전달하고 테스트 케이스에 로컬로 유지할 수 있다.
또 다른 단순화는 이제 형식이 지정된 문자열의 내용이 아닌 객체에 대해 테스트한다는 것이다.
물론 여전히 에러 구현과 이에 초점을 맞춘 몇 가지 통합 테스트를 작성해야 한다.


에러 리포팅을 캡슐화한다는 아이디어는 과한 디자인처럼 들리지만 잠시 생각해 볼 가치가 있다. 구현 (로깅)이 아니라 의도 (에러 담당자를 돕는 것)에 따라 코드를 작성한다는 의미이므로 더 표현력이 풍부해진다.
모든 에러 보고는 알려진 몇 군데에서 처리되므로 보고 방식에 일관성을 유지하고 재사용을 장려하기가 더 쉬워진다.
에러 리포팅을 캡슐화한다는 아이디어는 과한 디자인처럼 들리지만 잠시 생각해 볼 가치가 있다.
**구현 (로깅)이 아니라 의도 (에러 담당자를 돕는 것)에 따라 코드를 작성한다는 의미이므로 더 표현력이 풍부**해진다.
모든 에러 보고는 알려진 몇 군데에서 처리되므로 보고 방식에 일관성을 유지하고 재사용을 장려하기가 더 쉬워진다.

또한 Java 패키지가 아닌 애플리케이션 도메인의 관점에서 보고를 구조화하고 제어하는 데 도움이 될 수 있다.
마지막으로, 각 보고서에 대해 테스트를 작성하는 행위는 애매한 오류 조건을 처리하지 않아 로그가 늘어나고 프로덕션 장애로 이어지는 "이 예외를 어떻게 처리해야 할지 모르겠으니 일단 로그하고 계속 진행하겠다"는 증후군을 방지하는 데 도움이 된다.

마지막으로, 각 보고서에 대해 테스트를 작성하는 행위는 **애매한 오류 조건을 처리하지 않아 로그가 늘어나고 프로덕션 장애로 이어지는 "이 예외를 어떻게 처리해야 할지 모르겠으니 일단 로그하고 계속 진행하겠다"는 증후군을 방지하는 데 도움이 된다**.

"도메인 개체 전체에 로깅이 있기 때문에 테스트를 위해 로거를 전달할 수 없다."라는 이의 제기가 있었다.
"모든 곳에 로거를 전달해야 한다."라는 의견이다.
이것이 디자인을 충분히 명확히 하지 않았다는 것을 알려주는 테스트 냄새라고 생각한다.
에러 로깅 중 일부는 실제로는 디버깅 로깅이어야 하거나, 동작을 아직 이해하지 못한 상태에서 작성했기 때문에 필요 이상으로 많은 로깅을 하고 있을 수도 있다.

"도메인 개체 전체에 로깅이 있기 때문에 테스트를 위해 로거를 전달할 수 없다."라는 이의 제기가 있었다. 모든 곳에 로거를 전달해야 한다."라는 의견이다. 저희는 이것이 디자인을 충분히 명확히 하지 않았다는 것을 알려주는 테스트 냄새라고 생각한다. 에러 로깅 중 일부는 실제로는 디버깅 로깅이어야 하거나, 동작을 아직 이해하지 못한 상태에서 작성했기 때문에 필요 이상으로 많은 로깅을 하고 있을 수도 있다. 도메인 코드에 여전히 중복이 너무 많고 대부분의 프로덕션 로깅이 가야 할 '초크 포인트'를 아직 찾지 못했을 가능성이 큽니다.
도메인 코드에 여전히 중복이 너무 많고 대부분의 프로덕션 로깅이 있어야할 진짜 위치를 아직 찾지 못했을 가능성이 크다.

그렇다면 디버깅 로깅은 어떨까요? 작업이 끝나면 철거해야 하는 일회용 비계인가요, 아니면 테스트하고 유지 관리해야 하는 필수 인프라인가요? 시스템에 따라 다르지만 일단 구분을 하고 나면 에러 및 디버깅 로깅을 위해 다른 기술을 사용하는 것에 대해 더 자유롭게 생각할 수 있다.
그렇다면 디버깅 로깅은 어떨까?
작업이 끝나면 철거해야 하는 일회용 장치인가, 아니면 테스트하고 유지 관리해야 하는 필수 인프라인가?
시스템에 따라 다르지만 일단 구분을 하고 나면 에러 및 디버깅 로깅을 위해 다른 기술을 사용하는 것에 대해 더 자유롭게 생각할 수 있다.
심지어 인라인 코드는 중요한 프로덕션 코드의 가독성을 방해하기 때문에 디버깅 로깅에 부적합한 기술이라고 판단할 수도 있다.
대신 몇 가지 측면을 엮을 수 있을지도 모르지만(그것이 표준적인 사용 예시이므로), 그렇지 않을 수도 있지만 적어도 이제 선택의 여지가 명확해졌다.

0 comments on commit 836169b

Please sign in to comment.