.NET의 로깅 및 추적 모범 사례


53

추적 및 로깅에 대해 많이 읽었으며 문제의 모범 사례에 대한 황금률을 찾으려고 노력했지만 아무것도 없습니다. 사람들은 좋은 프로그래머가 좋은 추적을한다고하지만, 그렇게하면 경험에서 비롯되어야합니다.

나는 또한 여기와 인터넷을 통해 비슷한 질문을 읽었으며 그것들은 실제로 내가 요구하는 것과 똑같은 것이 아니며 아마도 대답이 만족스럽지 않을 수도 있습니다.

따라서 사람들은 디버거를 연결할 수없는 경우 추적이 응용 프로그램 디버깅 경험을 복제해야한다고 말합니다. 응용 프로그램의 각 제어 지점에서 어떤 경로가 사용되는지 확인할 수 있도록 충분한 컨텍스트를 제공해야합니다.

더 깊이 들어가면 "이벤트 로깅이 세부적인 제어 흐름이 아니라 주요 상태를 캡처한다는 점에서 이벤트 로깅이 추적과 다르다"는 점에서 추적과 이벤트 로깅을 구분할 수도 있습니다.

이제 System.Diagnostics네임 스페이스 에있는 표준 .NET 클래스 만 사용하여 추적 및 로깅을 수행하려고합니다 . TraceSource 클래스는 정적 Trace 클래스보다 작업에 더 좋습니다. Trace 수준을 구별하고 TraceSource 클래스를 사용하려면 Trace 클래스를 사용하는 동안 이벤트 유형을 알려주는 매개 변수를 전달할 수 있기 때문에 사용해야합니다. Trace.WriteLineIf다음과 같은 것들을 확인 SourceSwitch.TraceInformation등을 SourceSwitch.TraceErrors, 그것도 같은 속성이없는 TraceVerbose또는 TraceStart.

이 모든 것을 염두에두고 다음과 같이하는 것이 좋습니다.

  • 메소드를 시작할 때 메소드에 전달 된 매개 변수 값의 문자열 표시와 함께 단일 논리 조작 또는 파이프 라인을 나타내야하는 "시작"이벤트를 추적하십시오.
  • 데이터베이스에 항목을 삽입 할 때 "정보"이벤트를 추적하십시오.
  • 중요한 if / else 문에서 한 경로 또는 다른 경로를 취할 때 "정보"이벤트를 추적하십시오.
  • 복구 가능한 오류인지 여부에 따라 catch 블록에서 "Critical"또는 "Error"를 추적하십시오.
  • 메소드 실행이 완료되면 "중지"이벤트를 추적하십시오.

또한 Verbose 및 Warning 이벤트 유형을 추적하는 것이 가장 좋은시기를 명확히하십시오. 멋진 추적 / 로깅을 가진 코드의 예가 있고 공유 할 의향이 있다면, 그것은 우수 할 것입니다.

참고 : 여기에 좋은 정보가 있지만 여전히 찾고있는 정보는 없습니다 : http://msdn.microsoft.com/en-us/magazine/ff714589.aspx


아마도 stackoverflow에서 선호하는 로깅 방식의 네트 배치 방식 이 도움이 될 수 있습니다.
k3b

로깅을 위해 좋은 패턴을 사용하는 완전한 소스 코드 샘플 애플리케이션?
Kiquenet

솔직히 ... .NET으로 작업하는 경우 아마도 New Relic과 같은 것을 설치하고 완료했을 것입니다. (이것이 게시되었을 당시에는 좋은 옵션이 아닐 수도 있습니다)
svidgen

답변:


17

추적 유형의 중요성은 추적이 코드에있는 위치가 아니라 추적 된 메시지가 어느 정도 중요하기 때문에 선택해야합니다. 예:

메소드를 시작할 때 메소드에 전달 된 매개 변수 값의 문자열 표시와 함께 단일 논리 오퍼레이션 또는 파이프 라인을 나타내야하는 "시작"이벤트를 추적하십시오.

논리적 작업을 시작할 때 시작 유형을 사용하십시오. 이것은 시작 트레이스가 메소드의 시작 부분에 있어야한다는 의미는 아니며 메소드가 시작 트레이스를 가져야한다는 의미도 아닙니다.

대부분의 경우 논리적 작업은 실제로 메서드의 시작 부분에서 시작됩니다. 그렇지 않으면 코드가 올바르게 리팩터링되었는지 스스로에게 문의해야합니다.

매개 변수를 추적하는 것도 좋지 않을 수 있습니다 . 사례별로 추적해야 할 사항을 생각해야합니다. 예를 들어, 메소드의 매개 변수를 추적하는 것은 실제로 좋지 않습니다 void Authenticate(string userName, string plainPassword).

데이터베이스에 항목을 삽입 할 때 "정보"이벤트를 추적하십시오.

따라 다릅니다. 일부 품목은 추적해야하지만 모든 품목이 아닙니다.

  • 예를 들어 실제로 데이터베이스에 로그 항목을 삽입한다고 가정하십시오. 로그를 추적 하시겠습니까? 그런 다음 추적을 기록합니까? 그런 다음 추적 기록을 추적합니까?
  • 또 다른 예 : 민감한 데이터를 삽입하고 있습니다. 감사가 필요합니다. 삽입을 감사 한 후 왜 추적합니까?

중요한 if / else 문에서 한 경로 또는 다른 경로를 취할 때 "정보"이벤트를 추적하십시오.

다시 말하지만, 그것은 달려 있습니다.

날씨에 따라 캐치 블록에서 "치명적"또는 "오류"를 추적하십시오. 이는 복구 가능한 오류입니다.

복구 불가능한 오류 이후에 취한 조치는 추적 이상일 수 있습니다. 예를 들어 서버 측에서는 추후 분석을 위해 예외를 데이터베이스에 저장하려고합니다. 또한 일부 예외는 다른 예외보다 덜 중요하며 추적이 필요하지 않습니다.

메소드 실행이 완료되면 "중지"이벤트를 추적하십시오.

첫 번째 요점을 참조하십시오.

Verbose 및 Warning 이벤트 유형을 추적하는 것이 가장 좋은 시점을 알려주십시오.

말 수가 많은:

Verbose는 무언가 정말로 잘못되었을 때 추적해야 할 것을 추적하는 데 사용됩니다. 즉, 대부분의 경우 자세한 메시지 추적을 사용하지 않지만 때로는 일부 경우에 오류가 발생하는 이유를 이해하기 위해 코드의 일부를 디버깅해야합니다.

일반적으로 응용 프로그램 흐름을 실제로 잘 이해할 수있는 자세한 메시지가 많이 있습니다. 또한 다음과 같은 이유로 해당 메시지를 대부분 비활성화해야합니다.

  • 그렇지 않으면 로그가 정말 빠르게 커질 것입니다.
  • 대부분의 시간이 필요하지 않습니다.
  • 여기에는 응용 프로그램 흐름에 대한 중요한 데이터가 포함될 수 있습니다.

자세한 내용은 디버거에 액세스 할 수없는 경우 사용해야하는 도구로 생각하십시오.

경고:

경고 유형 추적은 잘못되고 중요 할 때 사용되지만 오류로 취급하기에는 너무 중요하지 않습니다. 예를 들어 RAM이 부족하면 경고가 표시 될 수 있지만 평소보다 속도가 느리더라도 응용 프로그램을 계속 실행할 수 있으므로 오류를 추적 할 이유가 없습니다.

예 :

  • 예 1 : 애플리케이션이 사용자가 열도록 요청한 파일을 열지 못했습니다. 파일이 존재하고 사용 중이 아니며 권한이 올바르게 설정되었지만 파일 열기를 차단하는 것이 있습니다. 이 경우 응용 프로그램에서이 사례를 관리 할 수없고 사용자가 예상 한대로 계속 작업 할 수 있기 때문에 (즉, 실제로 파일을 읽음) 오류 를 추적하게됩니다 .

  • 예 2 : 첫 번째 예에서 오류를 검사 한 후 파일 경로가 259 자보다 길기 때문에 오류가 발생했습니다. 따라서 코드를 리팩터링하여 잡으십시오 PathTooLongException. 다음에 사용자가 동일한 파일을 열려고하면 새 버전의 응용 프로그램에서 파일이 너무 길어서 파일을 열기 위해 전체 경로를 줄이려면 다른 폴더로 이동해야한다는 메시지가 표시됩니다. 이 신청서. 또한 메시지를 추적 합니다 .

  • 예 3 : 응용 프로그램이 작은 파일을 열고 파싱하는 데 20 초가 걸렸으며 대부분의 파일을 열고 파싱하는 데 10 ~ 100 밀리 초가 걸렸습니다. 파일이 실제로있는 디스크 유형, 파일 시스템, 파일 크기, 정확한 시간, 컴퓨터가 켜져있는 시간 등 관련 정보 로 경고 를 추적합니다 . 사용자가 20 시간이 걸린다고 불평 할 때 파일을 몇 초 동안 열면 추적을 수행하여 어떤 일이 발생하는지 찾습니다. 예를 들어 컴퓨터가 방금 시작했을 때 네트워크 공유에서 파일을로드하는 데 시간이 오래 걸린다는 것을 알 수 있습니다. 지연은 네트워크로 인한 것이며 응용 프로그램과 관련이 없다고 사용자에게 설명합니다.

  • 예 4 : 열린 파일이 잘못 표시됩니다. 실제로 파일에서 데이터가로드 된 후 단계별로 구문 분석되는 방법을 실제로 볼 수있는 상세 추적을 사용 합니다.


우리가 일하는 곳에서 사용하는 패턴 중 하나는 "KnownErrors"를 경고로, "UnknownErrors"를 오류로 기록하는 것입니다. 인프라 및 경고를 처리하는 방법에 따라 적절하지 않을 수 있지만, 그것은 우리에게 잘 작동합니다.
Andrew Piliser

5
 > say I want to do my tracing and logging using only the standard .NET classes

System.Diagnostics 추적 정보가 어디로 이동해야하는지 (파일, 이벤트 로그, 데이터베이스 등) 구성 할 수 있기 때문에 좋습니다.

불행히도, 사용 System.Diagnostics하려면 디자인 타임 에 어떤 추적 스트림을 따라야 하는지 미리 알고 있어야합니다 . (이 기사의 예에서는 Transfer, Resume, Suspend 등입니다.) 비활성화, 디버그 수준 또는 오류 수준으로 구성 할 수 있습니다.

나는 classlevel / namespacelevel 에서 런타임에 로깅이 얼마나 세부적 인지를 결정할 수있는 로깅 시스템을 선호 합니다. 예를 들어, 모든 디버그 이상에서는 MyNamespace.Business.*그렇지 않습니다 MyNamespace.Business.Calculations.

log4net (또는 Common.logging)을 사용하는 경우 모든 클래스는 고유 한 로거를 가져 오므로 어느 클래스에서 어떤 클래스에 로깅되는지 쉽게 결정할 수 있습니다.

데이터베이스 작업은 별도의 클래스에 있으므로 더 이상 별도의 규칙이 필요하지 않습니다.

Trace an "Information" event when inserting an item into the database.

대신 다음 지침을 따르는 것이 좋습니다.

  • 추적 수준에 기본 워크 플로가 표시되어야합니다
  • 디버그 수준에는 이유와 함께 프로그램 흐름의 결정을 포함하여 워크 플로 내에서 자세한 데이터와 처리가 표시되어야합니다 (DB에 항목이 없기 때문에 새 항목 생성)
  • 서비스 시작 / 중지에 대한 정보 수준 및 시작된 모든 워크 플로 / GUI 작업에 대한 하나의 항목

알다시피, 좋은 정보입니다, 감사합니다! 그러나 여전히 원래 질문에서 묻는 것처럼 상세 및 경고 이벤트 유형의 사용법을 분명히 설명 하시겠습니까? 또한 다른 사람들이 자신의 관점에 기여하도록 요청합니다.이 주제는 인터넷에서 본 것보다 더 깊이 탐구 할 가치가 있기 때문입니다.
Levidad

4

Story 프레임 워크를 사용해 볼 수 있으며, 컨텍스트에 모든 로그를 작성하고 다른 관련 정보를 추가하여 나중에 로그를 읽을 때 필요한 모든 것을 얻을 수 있으므로 로깅에 대한 고유 한 접근 방식이 있습니다.

스토리의 시작과 끝으로 "시작"및 "중지"개념을 자동으로 추가합니다.

또한 규칙 기반 시스템을 사용하면 오류가 있거나 "관리자"사용자가 제공 한 모든 스토리를 인쇄하는 등의 정보를 기반으로 각 스토리 (컨텍스트)로 수행 할 작업을 제어 할 수 있습니다.

이 블로그 게시물 에 대한 추가 정보



1
자세한 정보로 업데이트 된 답변
Amit Apple
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.