로깅 모범 사례 [폐쇄]


323

사람들이 실제 응용 프로그램에서 추적 및 로깅을 처리하는 방법에 대한 이야기를 듣고 싶습니다. 다음은 답변을 설명하는 데 도움이되는 몇 가지 질문입니다.

프레임 워크

어떤 프레임 워크를 사용하십니까?

  • log4net
  • 시스템 진단 진단
  • System.Diagnostics.TraceSource
  • 로깅 응용 프로그램 블록
  • 다른?

추적을 사용하는 경우 Trace.Correlation.StartLogicalOperation을 사용합니까?

이 코드를 수동으로 작성합니까, 아니면 특정 형태 지향 프로그래밍을 사용하여 작성합니까? 코드 스 니펫을 공유 하시겠습니까?

추적 소스에 대해 세분화 된 형태를 제공합니까? 예를 들어 WPF TraceSources를 사용하면 다양한 수준에서 구성 할 수 있습니다.

  • System.Windows- 모든 WPF에 대한 설정
  • System.Windows.Animation- 애니메이션 전용으로 재정의합니다.

청취자

어떤 로그 출력을 사용합니까?

  • 텍스트 파일
  • XML 파일
  • 이벤트 로그
  • 다른?

파일을 사용하는 경우 롤링 로그 또는 단일 파일 만 사용합니까? 사람들이 사용할 수있는 로그를 어떻게 만들 수 있습니까?

보기

로그를보기 위해 어떤 도구를 사용합니까?

  • 메모장
  • 꼬리
  • 이벤트 뷰어
  • 시스템 센터 운영 관리자 / Microsoft 운영 관리자
  • WCF 서비스 추적 뷰어
  • 다른?

ASP.NET 솔루션을 구축하는 경우 ASP.NET 상태 모니터링도 사용합니까? 상태 모니터 이벤트에 추적 출력을 포함합니까? Trace.axd는 어떻습니까?

맞춤형 성능 카운터는 어떻습니까?


3
300 upvotes로 이와 같은 질문을하는 사람들이 위키 형식을 제안하거나 programmers.stackexchange에 게시 하거나이 유형의 질문이 환영받지 못하면 Quora를 제안 할 수 있다면 도움이 될 것입니다. 분명히 질문은 실제로 매우 건설적입니다 .StackOverflow가 원하는 기준에 맞지 않습니다. programmers.stackexchange.com/questions/57064/… 에는 24 개의 공감대가 있습니다. 아마도 StackOverflow에 무언가가 빠져 있습니까?
Niall Connaughton

이 질문이 Q & A 형식을 위반하면이 질문이 아닌 Q & A 형식으로 잘못되었습니다. 때로는 질문을 종결해야하는지 여부에 대한 결정은 제공된 답변의 기능이어야하며 일부 개방형 질문은 토론을 불러 일으키지 만 다른 질문은 사용자에게 이와 같은 귀중한 컨텐츠를 제공하도록 초대합니다!
Matthias Wolf 8

1
이 질문 (특히 가장 좋은 답변)은 누군가 블로그 게시물을 다음과 같이 사용하려는 경우 아마도 블로그 게시물의 훌륭한 기초가 될 것입니다 ... 객관적인 질문으로, 실제로는 적합하지 않습니다. 아래에 좋은 정보가 있으므로 잠금 장치가 있습니다.
Shog9

답변:


232

최신 정보: System.Diagnostics에 대한 확장으로 원하는 누락 된 리스너를 제공하려면 CodePlex의 Essential.Diagnostics ( http://essentialdiagnostics.codeplex.com/ )를 참조하십시오


프레임 워크

Q : 어떤 프레임 워크를 사용하십니까?

A : .NET 2.0에 내장 된 System.Diagnostics.TraceSource

응용 프로그램을위한 강력하고 유연한 고성능 로깅을 제공하지만 많은 개발자는 해당 기능을 인식하지 못하고 완전히 활용하지 못합니다.

추가 기능이 유용하거나 기능이 존재하지만 문서화가 잘되지 않은 영역이 있지만 이것이 전체 로깅 프레임 워크 (확장 가능하도록 설계됨)를 버리고 일부 대체 대안과 같이 완전히 대체해야한다는 의미는 아닙니다. (NLog, log4net, Common.Logging 및 심지어 EntLib 로깅).

로깅 문을 응용 프로그램에 추가하고 휠을 다시 발명하는 방식을 변경하는 대신 필요한 곳에서 System.Diagnostics 프레임 워크를 확장했습니다.

EntLib조차도 다른 프레임 워크는 Not Invented Here Syndrome으로 고통 받고 있으며 System.Diagnostics (예 : 로그 문 작성 방법)에서 이미 완벽하게 작동하는 기본 사항을 다시 발명하는 데 시간을 낭비했다고 생각합니다. 존재하는 몇 가지 틈새를 채우는 대신 요컨대, 사용하지 마십시오. 필요하지 않습니다.

알려지지 않은 기능 :

  • 형식 문자열과 인수를 사용하는 TraceEvent 오버로드를 사용하면 Filter.ShouldTrace ()가 성공할 때까지 매개 변수가 별도의 참조로 유지되므로 성능에 도움이 될 수 있습니다. 이는 시스템에서 메시지가 실제로 기록 될 때까지 매개 변수 값에서 비싼 ToString () 호출을 의미하지 않습니다.
  • Trace.CorrelationManager를 사용하면 동일한 논리 연산에 대한 로그 문을 상관시킬 수 있습니다 (아래 참조).
  • VisualBasic.Logging.FileLogTraceListener는 로그 파일에 쓰기에 적합하며 파일 회전을 지원합니다. VisualBasic 네임 스페이스에서도 DLL을 포함시켜 C # (또는 다른 언어) 프로젝트에서 쉽게 사용할 수 있습니다.
  • 여러 인수와 비어 있거나 널 형식 문자열로 TraceEvent를 호출하면 EventLogTraceListener를 사용할 때 현지화 된 메시지 자원을 사용하는 경우 인수가 EventLog.WriteEntry ()로 직접 전달됩니다.
  • WCF의 Service Trace Viewer 도구는 WCF를 사용하지 않더라도 활동 상관 로그 파일의 그래프를 보는 데 유용합니다. 이를 통해 여러 스레드 / 활동이 관련된 복잡한 문제를 디버깅 할 수 있습니다.
  • 모든 리스너를 지우거나 기본값을 제거하여 오버 헤드를 피하십시오. 그렇지 않으면 Default는 모든 것을 추적 시스템으로 전달하고 모든 ToString () 오버 헤드를 발생시킵니다.

확장하고자하는 영역 (필요한 경우) :

  • 데이터베이스 추적 리스너
  • 컬러 콘솔 트레이스 리스너
  • MSMQ / 이메일 / WMI 추적 리스너 (필요한 경우)
  • 동적 구성 변경을 위해 Trace.Refresh를 호출하도록 FileSystemWatcher를 구현하십시오.

다른 권장 사항 :

구조화 된 이벤트 ID를 사용하고 참조 목록을 유지하십시오 (예 : 열거 형으로 문서화).

시스템의 각 (중요한) 이벤트에 대해 고유 한 이벤트 ID를 갖는 것은 특정 문제를 연관시키고 찾는 데 매우 유용합니다. 이벤트 ID를 기록 / 사용하는 특정 코드를 쉽게 추적 할 수 있으며 일반적인 오류에 대한 지침을 쉽게 제공 할 수 있습니다 (예 : 오류 5178은 데이터베이스 연결 문자열이 잘못되었음을 의미합니다).

이벤트 ID는 특정 코드를 몰라도 범주별로 처리 할 수있는 일종의 구조 (이메일 및 HTTP에 사용 된 응답 코드 이론과 유사)를 따라야합니다.

예 : 첫 번째 숫자는 일반 클래스를 자세히 설명 할 수 있습니다. 1xxx는 '시작'작업에 사용할 수 있고, 2xxx는 정상적인 동작에 사용할 수 있으며, 3xxx는 활동 추적에 사용할 수 있으며, 4xxx는 경고에 대해, 5xxx는 오류에 대해, 8xxx는 '중지'작업에 대해서는, 9xxx는 치명적 오류에 사용됩니다. 기타

두 번째 숫자는 영역을 자세히 설명 할 수 있습니다 (예 : 데이터베이스 정보의 경우 21xx (데이터베이스 경고의 경우 41xx, 데이터베이스 오류의 경우 51xx), 계산 모드의 경우 22xx (계산 경고의 경우 42xx 등), 다른 모듈의 경우 23xx 등).

할당 된 구조화 된 이벤트 ID를 사용하여 필터에 사용할 수도 있습니다.

Q : 추적을 사용하는 경우 Trace.Correlation.StartLogicalOperation을 사용합니까?

A : Trace.CorrelationManager는 모든 종류의 멀티 스레드 환경에서 요일을 상관시키는 데 매우 유용합니다.

상관 시키려면 최소한 각 논리적 작업마다 ActivityId를 한 번 설정해야합니다.

그런 다음 시작 / 중지 및 LogicalOperationStack을 간단한 스택 기반 컨텍스트에 사용할 수 있습니다. 보다 복잡한 컨텍스트 (예 : 비동기 작업)의 경우 새 ActivityId에 TraceTransfer를 사용하여 (변경하기 전에) 상관 관계를 허용합니다.

서비스 추적 뷰어 도구는 WCF를 사용하지 않더라도 활동 그래프를 보는 데 유용 할 수 있습니다.

Q :이 코드를 수동으로 작성합니까, 아니면 형태 지향 프로그래밍을 사용하여 작성합니까? 코드 스 니펫을 공유 하시겠습니까?

A : (a) 생성시 컨텍스트를 설정하고 (b) 폐기시 컨텍스트를 재설정하는 범위 클래스 (예 : LogicalOperationScope)를 생성 할 수 있습니다.

이를 통해 다음과 같은 코드를 작성하여 자동 랩 조작을 수행 할 수 있습니다.

  using( LogicalOperationScope operation = new LogicalOperationScope("Operation") )
  {
    // .. do work here
  }

작성시 범위는 필요한 경우 먼저 ActivityId를 설정하고 StartLogicalOperation을 호출 한 다음 TraceEventType.Start 메시지를 로깅 할 수 있습니다. Dispose에서 Stop 메시지를 기록한 다음 StopLogicalOperation을 호출 할 수 있습니다.

Q : 미량 소스에 대해 세분화 된 형태를 제공합니까? 예를 들어 WPF TraceSources를 사용하면 다양한 수준에서 구성 할 수 있습니다.

A : 예. 시스템이 커질수록 여러 개의 추적 소스가 유용하고 중요합니다.

합리적 규모의 시스템에 대해 모든 경고 이상 또는 모든 정보 이상 메시지를 일관되게 기록하려고하지만 활동 추적 (시작, 중지 등) 및 상세 로깅의 양이 너무 많아집니다.

스위치를 하나만 켜거나 끄는 대신 한 번에 시스템의 한 섹션에 대해이 정보를 켤 수 있습니다.

이렇게하면 일반적으로 로깅 (모든 경고, 오류 등)에서 중요한 문제를 찾은 다음 원하는 섹션에서 "확대"하고 활동 추적 또는 디버그 수준으로 설정할 수 있습니다.

필요한 트레이스 소스의 수는 애플리케이션에 따라 다릅니다. 예를 들어 어셈블리 또는 애플리케이션의 주요 섹션 당 하나의 트레이스 소스가 필요할 수 있습니다.

더 세밀하게 조정 된 제어가 필요한 경우 개별 부울 스위치를 추가하여 원시 메시지 덤프와 같은 특정 대용량 추적을 설정 / 해제하십시오. 또는 WCF / WPF와 유사한 별도의 추적 소스를 사용할 수 있습니다.

Activity Tracing과 일반 (기타) 로깅에 대해 별도의 추적 소스를 고려할 수도 있는데, 원하는 방식으로 필터를 좀 더 쉽게 구성 할 수 있기 때문입니다.

다른 소스를 사용하더라도 메시지는 ActivityId를 통해 상관 될 수 있으므로 필요한만큼 사용하십시오.


청취자

Q : 어떤 로그 출력을 사용합니까?

이것은 작성중인 응용 프로그램 유형과 기록되는 내용에 따라 달라질 수 있습니다. 일반적으로 다른 것들이 다른 장소 (예 : 다중 출력)에갑니다.

일반적으로 출력을 세 그룹으로 분류합니다.

(1) 이벤트-Windows 이벤트 로그 (및 추적 파일)

예를 들어 서버 / 서비스를 작성하는 경우 Windows에서 가장 좋은 방법은 Windows 이벤트 로그를 사용하는 것입니다 (보고 할 UI가 없음).

이 경우 모든 치명적, 오류, 경고 및 (서비스 수준) 정보 이벤트는 Windows 이벤트 로그로 이동해야합니다. 정보 수준은 "서비스 시작", "서비스 중지됨", "Xyz에 연결됨"및 "일정이 시작됨"과 같이 이벤트 로그에 표시하려는 이러한 높은 수준의 이벤트 유형에 예약되어 있어야합니다. , "사용자 로그온"등

경우에 따라 추적 시스템을 통하지 않고 응용 프로그램의 내장 부분으로 이벤트 로그에 기록 할 수 있습니다 (예 : 이벤트 로그 항목을 직접 작성). 즉, 실수로 끌 수 없습니다. (여전히 추적 시스템에서 동일한 이벤트를 기록하여 상관시킬 수 있습니다.)

반대로 Windows GUI 응용 프로그램은 일반적으로 Windows GUI 응용 프로그램을 사용자에게보고하지만 Windows 이벤트 로그에도 기록 할 수 있습니다.

이벤트에는 관련 성능 카운터 (예 : 오류 수 / 초)가있을 수 있으며 이벤트 로그에 직접 기록, 성능 카운터, 추적 시스템에 기록 및 사용자에게보고하도록 조정하는 것이 중요 할 수 있습니다. 동시.

즉, 특정 시간에 사용자에게 오류 메시지가 표시되면 Windows 이벤트 로그에서 동일한 오류 메시지를 찾은 다음 추적 로그에서 동일한 타임 스탬프를 가진 동일한 이벤트를 다른 추적 세부 정보와 함께 찾을 수 있어야합니다.

(2) 활동-애플리케이션 로그 파일 또는 데이터베이스 테이블 (및 추적 파일)

이는 웹 페이지 제공, 주식 시장 거래 접수, 주문 접수, 계산 수행 등 시스템이 수행하는 정기적 인 활동입니다.

활동 추적 (시작, 중지 등)이 여기에서 유용합니다 (오른쪽 세분성).

또한 특정 응용 프로그램 로그 (감사 로그라고도 함)를 사용하는 것이 매우 일반적입니다. 일반적으로 이것은 데이터베이스 테이블 또는 응용 프로그램 로그 파일이며 구조화 된 데이터 (예 : 필드 집합)를 포함합니다.

응용 프로그램에 따라 여기가 약간 흐려질 수 있습니다. 각 요청을 웹 로그에 기록하는 웹 서버가 좋은 예입니다. 유사한 예는 각 작업이 응용 프로그램 별 세부 정보와 함께 기록되는 메시징 시스템 또는 계산 시스템 일 수 있습니다.

좋은 예는 주식 시장 거래 또는 판매 주문 시스템입니다. 이러한 시스템에서는 중요한 비즈니스 가치가 있으므로 이미 활동을 로깅하고 있지만 다른 작업과 연관시키는 원칙은 여전히 ​​중요합니다.

사용자 지정 응용 프로그램 로그뿐만 아니라 활동에는 종종 관련 트랜잭션 카운터 (예 : 초당 트랜잭션 수)가 있습니다.

일반적으로 성능 카운터를 늘리고 추적 시스템에 기록 할 때 서로 다른 시스템에서 활동 기록을 조정해야합니다. 즉, 응용 프로그램 로그에 기록합니다. 동시에 (또는 코드에서 서로 직접) 모두 수행하면 문제가 코드의 다른 시간 / 위치에서 발생하는 것보다 디버깅 문제가 더 쉽습니다.

(3) 디버그 추적-텍스트 파일 또는 XML 또는 데이터베이스 일 수 있습니다.

이것은 상세 레벨 이하의 정보입니다 (예 : 원시 데이터 덤프를 켜거나 끄는 사용자 정의 부울 스위치). 이것은 하위 활동 수준에서 시스템이 수행하는 작업에 대한 내장이나 세부 정보를 제공합니다.

이것은 응용 프로그램의 개별 섹션 (따라서 여러 소스)에 대해 켜거나 끌 수있는 수준입니다. 이 이벤트로 인해 Windows 이벤트 로그가 복잡 해지는 것을 원하지 않습니다. 때때로 데이터베이스가 사용되지만 특정 시간 후에 제거 된 로그 파일을 롤링 할 가능성이 높습니다.

이 정보와 응용 프로그램 로그 파일의 큰 차이점은 구조화되지 않았다는 것입니다. 응용 프로그램 로그에 To, From, Amount 등의 필드가있을 수 있지만 Verbose 디버그 추적은 프로그래머가 입력 한 모든 것 (예 : "값 X = {value}, Y = false"또는 " 다시 시도하십시오 "

한 가지 중요한 방법은 응용 프로그램 로그 파일 또는 Windows 이벤트 로그에 넣은 내용이 동일한 세부 정보 (예 : 타임 스탬프)로 추적 시스템에 기록되도록하는 것입니다. 그러면 조사 할 때 다른 로그를 상관시킬 수 있습니다.

서비스 추적 뷰어와 같이 복잡한 상관 관계로 인해 특정 로그 뷰어를 사용하려는 경우 XML과 같은 적절한 형식을 사용해야합니다. 그렇지 않으면 간단한 텍스트 파일만으로도 충분합니다. 낮은 수준에서는 정보가 크게 구조화되어 있지 않으므로 배열 덤프, 스택 덤프 등을 찾을 수 있습니다. 더 높은 수준에서 더 구조화 된 로그와 다시 상관 관계가있을 수있는 경우 괜찮아

Q : 파일을 사용하는 경우 롤링 로그 또는 단일 파일 만 사용합니까? 사람들이 사용할 수있는 로그를 어떻게 만들 수 있습니까?

A : 파일의 경우 일반적으로 관리 효율성 관점에서 로그 파일을 롤링하려고합니다 (System.Diagnostics에서는 단순히 VisualBasic.Logging.FileLogTraceListener를 사용함).

다시 가용성은 시스템에 따라 다릅니다. 파일에 대해서만 이야기하는 경우 서버 / 서비스를 위해 필요한 경우 롤링 파일에 액세스 할 수 있습니다. Windows 이벤트 로그 또는 데이터베이스 응용 프로그램 로그에는 자체 액세스 메커니즘이 있습니다.

파일 시스템에 쉽게 액세스 할 수 없으면 데이터베이스에 대한 디버그 추적이 더 쉬울 수 있습니다. [즉, 데이터베이스 TraceListener 구현].

Windows GUI 응용 프로그램에서 본 흥미로운 솔루션 중 하나는 실행 중에 "플라이트 레코더"에 매우 자세한 추적 정보를 기록한 다음 문제가없는 경우 종료하면 파일을 삭제한다는 것입니다.

그러나 충돌이 발생하거나 문제가 발생하면 파일이 삭제되지 않은 것입니다. 오류가 발생하거나 다음에 파일을 실행할 때 파일을 확인한 후 압축 (예 : 7zip)하여 이메일로 보내거나 사용할 수있게하는 등의 조치를 취할 수 있습니다.

요즘 많은 시스템은 (예 : 개인 정보 보호 등의 이유로 사용자와 확인한 후) 중앙 서버에 자동으로 장애보고를 통합합니다.


보기

Q : 로그를보기 위해 어떤 도구를 사용합니까?

A : 다른 이유로 여러 개의 로그가있는 경우 여러 뷰어를 사용합니다.

Notepad / vi / Notepad ++ 또는 기타 텍스트 편집기는 일반 텍스트 로그의 기본입니다.

전송 작업과 같은 복잡한 작업이있는 경우 서비스 추적 뷰어와 같은 특수 도구를 사용하는 것이 분명합니다. 그러나 필요하지 않은 경우 텍스트 편집기가 더 쉽습니다.

일반적으로 높은 수준의 정보를 Windows 이벤트 로그에 기록 할 때 구조화 된 방식으로 개요를 신속하게 얻을 수있는 빠른 방법을 제공합니다 (예 : 오류 / 경고 아이콘 찾기). 최소한 로그가 시작점을 제공하지만 로그에 충분하지 않은 경우 텍스트 파일을 통한 헌팅 만 시작하면됩니다. (이 시점에서 로그가 전체를 조정했는지 확인하십시오).

일반적으로 Windows 이벤트 로그는 이러한 중요한 이벤트를 MOM 또는 OpenView와 같은 모니터링 도구에서 사용할 수 있도록합니다.

기타

데이터베이스에 로그인하면 정보를 쉽게 필터링하고 정렬 할 수 있습니다 (예 : 특정 활동 ID 확대). 텍스트 파일을 사용하면 Grep / PowerShell 또는 유사 항목을 사용하여 원하는 부분 GUID에서 필터링 할 수 있습니다.

MS Excel (또는 다른 스프레드 시트 프로그램). 다른 값이 다른 열에 들어가도록 올바른 구분 기호를 사용하여 정보를 가져올 수있는 경우 구조화 된 정보 또는 반 구조화 된 정보를 분석하는 데 유용 할 수 있습니다.

디버그 / 테스트에서 서비스를 실행할 때 일반적으로 간단하게 콘솔 응용 프로그램에서 서비스를 호스팅합니다. 컬러 콘솔 로거가 유용하다는 것을 알았습니다 (예 : 빨간색은 경고, 노란색은 경고 등). 사용자 정의 추적 리스너를 구현해야합니다.

프레임 워크에는 컬러 콘솔 로거 또는 데이터베이스 로거가 포함되어 있지 않으므로 지금 필요한 경우 작성해야합니다 (너무 어렵지는 않습니다).

여러 프레임 워크 (log4net, EntLib 등)가 바퀴를 다시 발명하고 기본 로깅, 필터링 및 텍스트 파일, Windows 이벤트 로그 및 XML 파일에 대한 로깅을 각각 자체적으로 다시 구현하는 데 시간을 낭비했다는 사실이 정말 귀찮습니다. 다른 방법 (로그 진술은 각각 다릅니다); 그런 다음 각각은 이미 존재하는 대부분의 데이터베이스 로거와 같은 자체 버전의 데이터베이스 로거를 구현했으며 필요한 것은 System.Diagnostics에 대한 추적 리스너가 몇 개 더 필요한 경우입니다. 중복 노력의 큰 낭비에 대해 이야기하십시오.

Q : ASP.NET 솔루션을 구축하는 경우 ASP.NET 상태 모니터링도 사용합니까? 상태 모니터 이벤트에 추적 출력을 포함합니까? Trace.axd는 어떻습니까?

필요에 따라 이러한 기능을 켜거나 끌 수 있습니다. Trace.axd는 서버가 특정 것에 응답하는 방법을 디버깅하는 데 매우 유용하지만 일반적으로 많이 사용되는 환경이나 장기 추적에는 유용하지 않습니다.

Q : 사용자 지정 성능 카운터는 어떻습니까?

전문적인 응용 프로그램, 특히 서버 / 서비스의 경우 성능 모니터 카운터와 Windows 이벤트 로그에 모두 기록되는 기능을 갖추기를 기대합니다. 이들은 Windows의 표준 도구이며 사용해야합니다.

사용하는 성능 카운터 및 이벤트 로그에 대한 설치 관리자를 포함해야합니다. 설치시 (관리자로 설치할 때) 작성해야합니다. 응용 프로그램이 정상적으로 실행되면 관리 권한이 없어야하므로 누락 된 로그를 만들 수 없습니다.

이것은 비 관리자로 개발하는 연습을하는 좋은 이유입니다 (서비스를 설치해야 할 때 별도의 관리자 계정이 있어야 함). 이벤트 로그에 쓰는 경우 .NET은 처음 기록 할 때 자동으로 누락 된 로그를 만듭니다. 관리자가 아닌 사람으로 개발하는 경우이를 조기에 포착하여 고객이 시스템을 설치 한 후 시스템 관리자가 실행되지 않아 사용할 수없는 경우를 피할 수 있습니다.


참고 : 파일에 대한 Microsoft 추적이 충돌하는 문제가 발생했습니다. 동일한 파일에 여러 프로세스 (또는 스레드)를 작성하고 충돌하는 경우 로그 파일에서 파일 시스템 독점 액세스 잠금 오류가 발생합니다.
Jay

1
System.Diagnostics 인프라는 스레드로부터 안전합니다. 기본 동작은 프레임 워크 잠금이지만, 자체 잠금을 제공하는 경우 TraceListener.IsThreadSafe를 재정의 할 수 있습니다. msdn.microsoft.com/en-us/library/…를 참조 하십시오 . 여러 프로세스의 경우 일반적으로 별도의 파일에 쓰지만 Service Trace Viewer는 여러 추적 파일 (예 : 여러 시스템에서)을로드하고 ActivityId를 통해 서로 연관시킬 수 있습니다.
Sly Gryphon 2016 년

1
TraceEvent ()를 사용하여 예외를 기록하는 방법을 제안 할 수 있습니까?
Dmitriy Sosunov

1
플래그로 컴파일 된 코드가 거의없는 프로덕션 환경에서 사용할 수 없도록 System.Diagnostics.Trace장식 된 주요 단점 중 하나가 아닙니까? [Conditional("TRACE")]TRACE
Asbjørn Ulsberg

2
@asbjornu Visual Studio의 기본 릴리스 빌드 구성에는 TRACE가 정의되어 있습니다 (릴리스 빌드에서는 해제 된 DEBUG). 그러나 명령 행에서 빌드하는 경우이를 켜야합니다.
교활한 그리폰

40

내 경우에는 플랫폼 유연성 (desktop .Net / Compact Framework, 32 / 64-bit) 관점에서 log4net을 추천하는 합창단에 합류해야합니다.

그러나 개인 레이블 API로 랩핑하는 것은 주요 안티 패턴 입니다. log4net.ILoggerCommons Logging 래퍼 API 의 .Net 대응 이므로 이미 커플 링이 최소화되어 있으며 Apache 라이브러리이기 때문에 제어를 포기하지 않기 때문에 일반적으로 걱정할 필요가 없습니다. 곰팡내 나게 하다.

내가 본 대부분의 집 래퍼 라이브러리는 하나 이상의 결함을 커밋합니다.

  1. 다른 선택성 이득없이 클래스 당 권장 로거 패턴 의 정밀한 해상도를 잃는 글로벌 싱글 톤 로거 (또는 이에 상응하는 정적 진입 점)를 사용합니다 .
  2. 선택적 Exception인수 를 노출하지 못하면 여러 가지 문제가 발생합니다.
    • 예외 로깅 정책을 유지하기가 더 어려워 지므로 예외와 일관되게 수행되지 않습니다.
    • 일관된 정책을 사용하더라도 예외를 문자열로 지정하면 데이터가 조기에 손실됩니다. ILayout이벤트 체인을 결정하기 위해 예외에 대한 자세한 드릴 다운을 수행 하는 사용자 정의 데코레이터를 작성했습니다 .
  3. 속성 을 노출하지 못하면IsLevelEnabled 영역 또는 로깅 수준이 해제되어있을 때 서식 코드를 건너 뛸 수있는 기능이 무시됩니다.

1
나는 log4j 주위의 (끔찍한) 사내 랩퍼를 다소 덜 끔찍한 것으로 리팩토링하는 임무를 맡았습니다 (아직 꽤 나쁘지 만, 그것은 log4j에 주어진 요구 사항을 충족시키는 결과입니다). 전역 정적 진입 점을 제거하려고 시도했지만 격추되었습니다. 나는 정말로 요점을 얻지 못한다. 설정에서 log4j는 너무 확장되고 꼬여서 실제로 이벤트 디스패처로 사용되고 있습니다. 누군가가 "이것을 위해 어떻게 log4j를 사용할 수 있습니까?" log4를 똑바로 사용하거나 자신의 프레임 워크를 작성하십시오. 중간 길은 고통 스럽습니다.
Adam Jaskiewicz

25
log4net을 래핑하지 않는 권장 사항에 동의하지 않습니다. 씬 제공자 모델 API로 랩핑하면 클래스 라이브러리 사용자가 선호하는 로깅 프레임 워크를 연결할 수 있습니다. YMMV는 물론 "주요 반 패턴"으로 묘사하는 것은 약간 독단적입니다. 또한 "리튬 결함"이있는 랩퍼 라이브러리가 있다는 사실은 잘 작성된 랩퍼에 대한 좋은 주장이 아닙니다.
Joe

1
반 패턴이라고 부른다고해서 항상 100 % 나쁜 생각은 아닙니다. 조심하지 않으면 구석에 페인트 칠하는 경향이 있습니다. 또한 ILog / LogManager 자체는 log4net 어셈블리에 번들로 제공되는 커먼즈 로깅 이미지에서 잘 작성된 래퍼 미니 라이브러리이지만 추출하여 CLR에 대한 적절한 커먼즈 로깅으로 변환 할 이유가 없습니다.
Jeffrey Hantin 2016 년

18

나는 종종 asp.net에서 개발하지 않지만 로거와 관련하여 많은 모범 사례가 보편적이라고 생각합니다. 몇 년 동안 내가 배운 로깅에 대한 나의 임의의 생각은 다음과 같습니다.

프레임 워크

  • slf4j와 같은 로거 추상화 프레임 워크를 사용하거나 자신의 롤을 사용하여 로거 구현을 API에서 분리하십시오. 수많은 로거 프레임 워크가 등장하고 번거 로움없이 많은 새로운 로거 프레임 워크를 채택하는 것이 좋습니다.
  • 다양한 출력 형식을 지원하는 프레임 워크를 찾으십시오.
  • 플러그인 / 맞춤 필터를 지원하는 프레임 워크를 찾으십시오.
  • 외부 파일로 구성 할 수있는 프레임 워크를 사용하여 고객 / 소비자가 로그 출력을 쉽게 조정하여 상업용 로그 관리 응용 프로그램에서 쉽게 읽을 수 있도록합니다.
  • 사용자 정의 로깅 수준을 넘어서는 안됩니다. 그렇지 않으면 다른 로깅 프레임 워크로 이동할 수 없습니다.

로거 출력

  • 심각한 오류가 발생할 수있는 로깅에 대한 XML / RSS 스타일 로그를 피하십시오. 로거가 닫힘을 쓰지 않고 전원 스위치가 꺼지면 중요합니다.</xxx> 태그를 로그가 손상 합니다.
  • 로그 스레드. 그렇지 않으면 프로그램 흐름을 추적하기가 매우 어려울 수 있습니다.
  • 로그를 국제화해야하는 경우 개발자가 영어 (또는 선택한 언어)로만 로그인하도록 할 수 있습니다.
  • 경우에 따라 로깅 쿼리를 SQL 쿼리에 삽입하는 옵션을 사용하면 디버깅 상황에서 생명을 구할 수 있습니다. 같은 :
    -클래스 호출 : com.foocorp.foopackage.FooClass : 9021
    SELECT * FROM foo;
  • 클래스 수준 로깅을 원합니다. 일반적으로 정적 로거 인스턴스도 원하지 않습니다. 미세 최적화 할 가치가 없습니다.
  • 모든 예외가 동일하게 생성되는 것은 아니기 때문에 기록 된 예외를 표시하고 분류하는 것이 때때로 유용합니다. 따라서 중요한 상태에 대한 알림을 보내야하는 로그 모니터가있는 경우 중요한 예외의 하위 집합을 미리 알고 있으면 도움이됩니다.
  • 복제 필터는 시력과 하드 디스크를 절약합니다. 같은 로깅 문을 10 ^ 10000000 번 반복하고 싶습니까? 다음과 같은 메시지를 얻는 것이 낫지 않습니까? This is my logging statement - Repeated 100 times

또한 이 질문을 참조하십시오 .


5
중복 필터는 좋은 생각입니다
폴 Stovell

나는 깨진 태그 문제에 동의했지만 대부분의 훌륭한 XML 작성자는 어쨌든 완전한 XML을 사용하지 않으므로 (즉, 루트 요소 없음) XML DOM을로드하지 않고 기록 할 수 있습니다. 드문 경우지만 부분적으로 작성된 항목에서 문제가 발생하면 수동으로 수정할 수 있습니다.
Paul Stovell

나는 몇 년 동안 XML 로깅을 계속해서 해왔다. 이제 나에게는 지나친 것 같습니다. 응용 프로그램 상태의 RSS 피드가 필요한 경우 로그 모니터링 유틸리티를 사용하여 RSS 피드를 구현하는 것이 더 좋습니다.
Elijah

RSS에 동의합니다. 항목을 더 잘 이해할 수있는 시각화 도구에 대해 더 많이 생각하고 있습니다. 텍스트 파일을 사용하면 일반적으로 한 줄에 항목을 유지하려고합니다. 그러나 때로는 스택 추적 또는 직렬화 된 객체를 포함하려고합니다. 그 (같은 WCF에서 사용)을 XML 로그가 유용의
폴 Stovell

SQL 쿼리의 계측에 대해 +1 이것은 실제로 데이터베이스 추적과 응용 프로그램 추적의 상관 관계에 매우 유용합니다. 내 DAL에서 수동으로 수행하지만이 기술에 어떤 도구 지원이 있는지 궁금합니다.
Constantin

17

빵과 버터가 Java이기 때문에 .Net에 대한 로깅에 대해서는 언급 할 자격이 없지만 지난 8 년 동안 로깅에서 마이그레이션을 수행하여 귀하의 질문에 유용한 유추를 찾을 수 있습니다.

JVM 내의 모든 스레드에서 사용 된 싱글 톤 로거로 시작하여 전체 프로세스의 로깅 레벨을 설정했습니다. 시스템의 특정 부분까지도 디버깅해야한다면 큰 로그가 생겼으므로 교훈 1은 로깅을 분할하는 것입니다.

로거의 현재 구현에서는 하나를 기본값으로 정의하여 여러 인스턴스를 허용합니다. 로깅 수준이 다른 여러 하위 로거를 인스턴스화 할 수 있지만이 아키텍처의 가장 유용한 측면은 로깅 속성을 변경하여 개별 패키지 및 클래스에 대한 로거를 만드는 기능입니다. 두 번째 교훈은 코드를 변경하지 않고 동작을 재정의 할 수있는 유연한 시스템을 만드는 것입니다.

우리는 Log4J를 감싸는 Apache 공통 로깅 라이브러리를 사용하고 있습니다.

도움이 되었기를 바랍니다!

* 편집하다 *

아래 Jeffrey Hantin의 게시물을 읽은 후 내부 로깅 래퍼가 실제로 무엇이되었는지 주목해야한다는 것을 깨달았습니다. 이제는 기본적으로 팩토리이며 올바른 특성 파일 (기존 이유로 기본 위치로 이동되지 않은)을 사용하여 작업 로거를 얻는 데 엄격하게 사용됩니다. 이제 명령 줄에서 로깅 구성 파일을 지정할 수 있기 때문에 더 작아 질 것으로 생각되며 새 응용 프로그램을 시작하는 경우 로거를 래핑하지 않아도된다는 그의 진술에 분명히 동의합니다.


답변 해주셔서 감사합니다. 하위 로거를 코드에서 수동으로 작성합니까 (즉, 하드 코딩되어 있습니까) 또는 자동 / 암시 적 방식으로 작성합니까?
Paul Stovell

아니요 ... 패키지 또는 클래스의 logging.properties 파일에 로깅 구성을 추가하면 해당 구성마다 로깅되지만 특별히 구성되지 않은 패키지 또는 클래스는 기본 수준으로 로깅됩니다.
Steve Moyer

9

우리는 로그 인스턴스에 대한 싱글 톤 래퍼와 함께 로깅 공급자로 Log4Net을 사용합니다 (단일 톤이 검토 중이지만 좋은지 아닌지 질문).

우리는 다음과 같은 이유로 그것을 선택했습니다.

  • 다양한 환경에서 간단한 구성 / 재구성
  • 사전 구축 된 어 펜더 수
  • 우리가 사용하는 CMS 중 하나가 이미 내장되어있었습니다.
  • 멋진 로그 수준과 그 구성

ASP.NET 개발 관점에서 말한 것입니다.

.NET 프레임 워크에있는 Trace를 사용하면 몇 가지 장점을 알 수 있지만 주로 작업하는 구성 요소가 실제로 Trace 호출을 수행하지 않기 때문에 완전히 팔리지는 않습니다. 내가 자주 사용하는 유일한 것은System.Net.Mail 내가 말할 수있는 것입니다.

그래서 우리는 log4net을 감싸는 라이브러리를 가지고 있으며 우리 코드에는 다음과 같은 것들이 필요합니다.

Logger.Instance.Warn("Something to warn about");
Logger.Instance.Fatal("Something went bad!", new Exception());

try {
  var i = int.Parse("Hello World");
} catch(FormatException, ex) {
  Logger.Instance.Error(ex);
}

메서드 내에서 로깅 수준이 활성화되어 있는지 확인하여 log4net API에 대한 중복 호출이 없으므로 (디버그가 활성화되어 있지 않으면 디버그 문이 무시 됨) 시간이 걸릴 때 직접 확인을 할 수 있도록 업데이트하도록하겠습니다. 이렇게하면 평가가 수행되지 않아야 할 때 수행되는 것을 방지 할 수 있습니다. 예 :

Logger.Instance.Debug(string.Format("Something to debug at {0}", DateTime.Now);

이것은 다음이 될 것입니다 :

if(Logger.DebugEnabled) Logger.Instance.Debug(string.Format("Something to debug at {0}", DateTime.Now);

(약간의 집행 시간을 절약하십시오)

기본적으로 두 위치에 로그인합니다.

  1. 웹 사이트의 파일 시스템 (비 서비스 파일 확장자)
  2. 오류 및 치명적인 이메일 전송

파일은 매일 또는 10MB (IIRC)의 롤링으로 수행됩니다. EventLog는 종종 사이트에 제공하려는 것보다 더 높은 보안이 필요할 수 있으므로 EventLog를 사용하지 않습니다.

메모장이 로그를 읽는 데 효과적입니다.


로깅 프레임 워크는 싱글 톤이 오용되지 않는 몇 가지 사례 중 하나입니다.
mmcdole

로거와 관련된 컨텍스트를 제공하려는 경우 일 수 있습니다. 그러나 동시성 처리에 도움을 수행
아론 파월에게

7
나는 분명히 싱글 톤을 버릴 것입니다. 확실히 전달되는 단일 인스턴스 를 가질 수 있습니다 (바람직하게 IOC / DI 컨테이너에 있음). 나는 또한 인터셉터로 벌목을 옮기려고 노력할 것이다 ....
yfeldblum

2
단일 인스턴스의 팬도 아닙니다. 각 클래스에 고유 한 이름의 로거를 부여하여 모듈별로 로깅을 설정하거나 해제하는 것이 쉬워졌습니다.
Jeffrey Hantin

8

어떤 프레임 워크를 사용하십니까?

로깅 응용 프로그램 블록과 .Net 프레임 워크 비트를 중심으로 작동하는 사용자 지정 로깅 도우미를 혼합하여 사용합니다. LAB는 서비스 방법 시작 / 종료를위한 별도의 일반 추적 파일과 예기치 않은 문제에 대한 특정 오류 파일이 포함 된 상당히 광범위한 로그 파일을 출력하도록 구성되어 있습니다. 구성에는 디버그 지원을위한 날짜 / 시간, 스레드, pId 등이 포함되며 전체 예외 세부 사항 및 스택 (예기치 않은 예외의 경우)이 포함됩니다.

사용자 정의 로깅 도우미는 Trace.Correlation을 사용하며 특히 WF의 로깅 컨텍스트에서 편리합니다. 예를 들어, 일련의 순차적 워크 플로를 호출하는 상태 머신이 있습니다. 이러한 각 호출 활동에서 시작 (StartLogicalOperation을 사용하여)을 기록한 다음 마지막에 gereric return 이벤트 핸들러를 사용하여 논리 연산을 중지합니다.

이는 복잡한 비즈니스 시퀀스에서 오류를 디버깅하려고 할 때 활동 실행 시퀀스를 기반으로 If / Else 브랜치 결정 등을보다 신속하게 결정할 수 있기 때문에 몇 번 유용하다는 것이 입증되었습니다.

어떤 로그 출력을 사용합니까?

우리는 텍스트 파일과 XML 파일을 사용합니다. 텍스트 파일은 앱 블록을 통해 구성되지만 WF 서비스에서 XML 출력을 얻습니다. 이를 통해 런타임 비즈니스 (지속성 등)와 일반 비즈니스 유형 예외를 캡처 할 수 있습니다. 텍스트 파일은 일 및 크기별로 롤링 된 롤링 로그입니다 (총 1MB의 크기는 롤오버 지점이라고 생각합니다).

로그를보기 위해 어떤 도구를 사용합니까?

보고있는 출력 그룹에 따라 메모장과 WCF 서비스 추적 뷰어를 사용하고 있습니다. WCF 서비스 추적 뷰어는 출력 설정이 올바르게되어 있고 출력을 훨씬 간단하게 읽을 수있는 경우 정말 유용합니다. 어쨌든 오류가 어디 있는지 대략 알면 잘 주석이 달린 텍스트 파일을 읽는 것만으로도 좋습니다.

로그는 단일 디렉토리로 전송 된 다음 소스 서비스를 기반으로 하위 디렉토리로 분할됩니다. 루트 디렉토리는 지원 사용자 그룹에 의해 액세스 제어되는 웹 사이트를 통해 노출됩니다. 이를 통해 요청을하지 않고도 생산 로그를 살펴보고 생산 데이터에 대한 긴 레드 테이프 프로세스를 진행할 수 있습니다.


6

이 도구의 저자 인 우리는 물론 .NET 응용 프로그램의 로깅 및 추적에 SmartInspect 를 사용 합니다. 일반적으로 라이브 로깅에는 명명 된 파이프 프로토콜을 사용하고 최종 사용자 로그에는 (암호화 된) 이진 로그 파일을 사용합니다. SmartInspect Console을 뷰어 및 모니터링 도구로 사용합니다.

실제로 .NET을위한 로깅 프레임 워크와 툴이 꽤 있습니다. DotNetLogging.com 에있는 다양한 도구에 대한 개요와 비교가 있습니다.


5

답변에는 많은 권장 사항이 있습니다.

일반적인 모범 사례는 누가 로그를 읽을 것인지 고려하는 것입니다. 내 경우에는 클라이언트 사이트의 관리자가됩니다. 그래서 나는 그들에게 행동 할 수있는 메시지를 기록합니다. 예를 들어, "응용 프로그램을 초기화 할 수 없습니다. 이것은 일반적으로 ......


1

우리는 웹 애플리케이션에서 log4net을 사용합니다.

XML 구성 파일을 변경하여 런타임에 로깅을 사용자 정의 할 수있는 기능은 응용 프로그램이 런타임에 오작동하고 자세한 정보가 필요한 경우 매우 유용합니다.

또한 특정 클래스 나 속성을 대상으로 로그인 할 수 있습니다. 오류가 발생한 위치를 알고있을 때 매우 유용합니다. 전형적인 예는 NHibernate로, SQL이 데이터베이스로가는 것을보고 싶어합니다.

편집하다:

모든 이벤트를 데이터베이스와 추적 시스템에 씁니다. 오류 또는 예외에 사용하는 이벤트 로그 대부분의 이벤트를 데이터베이스에 기록하여 사용자 정의 보고서를 작성하고 사용자가 애플리케이션에서 바로 원하는 경우 사용자가 로그를 볼 수 있도록합니다.


사용 방법에 대한 자세한 정보를 제공 할 수 있습니까? 파일이나 이벤트 로그에 기록합니까? 롤링 로그 파일입니까? 보안을 유지하거나 백업하려면 어떻게합니까? 실제 사용에 관심이 있습니다.
Paul Stovell

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