Debug 클래스
namespace System.Diagnostics
{
public static class Debug
{
public static int IndentSize { get; set; }
public static bool AutoFlush { get; set; }
public static TraceListenerCollection Listeners { get; }
public static int IndentLevel { get; set; }
public static void Close();
public static void Flush();
public static void Indent();
public static void Unindent();
public static void Assert(bool condition);
public static void Assert(bool condition, string message);
public static void Assert(bool condition, string message, string detailMessage);
public static void Assert(bool condition, string message, string detailMessageFormat, params object[] args);
public static void Fail(string message);
public static void Fail(string message, string detailMessage);
public static void Print(string message);
public static void Print(string format, params object[] args);
public static void Write(string message);
public static void Write(object value);
public static void Write(string message, string category);
public static void Write(object value, string category);
public static void WriteIf(bool condition, string message);
public static void WriteIf(bool condition, object value);
public static void WriteIf(bool condition, string message, string category);
public static void WriteIf(bool condition, object value, string category);
public static void WriteLine(string message);
public static void WriteLine(object value);
public static void WriteLine(string message, string category);
public static void WriteLine(object value, string category);
public static void WriteLine(string format, params object[] args);
public static void WriteLineIf(bool condition, string message);
public static void WriteLineIf(bool condition, object value);
public static void WriteLineIf(bool condition, string message, string category);
public static void WriteLineIf(bool condition, object value, string category);
}
}
Trace 클래스
namespace System.Diagnostics
{
public sealed class Trace
{
public static int IndentSize { get; set; }
public static int IndentLevel { get; set; }
public static TraceListenerCollection Listeners { get; }
public static bool AutoFlush { get; set; }
public static CorrelationManager CorrelationManager { get; }
public static bool UseGlobalLock { get; set; }
public static void Close();
public static void Flush();
public static void Refresh();
public static void Indent();
public static void Unindent();
public static void Assert(bool condition);
public static void Assert(bool condition, string message);
public static void Assert(bool condition, string message, string detailMessage);
public static void Fail(string message);
public static void Fail(string message, string detailMessage);
public static void TraceError(string message);
public static void TraceError(string format, params object[] args);
public static void TraceInformation(string message);
public static void TraceInformation(string format, params object[] args);
public static void TraceWarning(string message);
public static void TraceWarning(string format, params object[] args);
public static void Write(string message);
public static void Write(object value);
public static void Write(string message, string category);
public static void Write(object value, string category);
public static void WriteIf(bool condition, string message);
public static void WriteIf(bool condition, object value);
public static void WriteIf(bool condition, string message, string category);
public static void WriteIf(bool condition, object value, string category);
public static void WriteLine(string message);
public static void WriteLine(object value);
public static void WriteLine(string message, string category);
public static void WriteLine(object value, string category);
public static void WriteLineIf(bool condition, string message);
public static void WriteLineIf(bool condition, object value);
public static void WriteLineIf(bool condition, string message, string category);
public static void WriteLineIf(bool condition, object value, string category);
}
}
- 기본적인 로깅 기능과 단언(Assertion) 기능을 제공하는 정적 클래스
- DEBUG나 TRACE 기호가 정의되어 있지 않으면 컴파일러는 해당 메서드 호출을 무시함
- Debug: 디버그 빌드에 사용 - [Conditional("DEBUG")]
- Trace: 디버그 / 릴리즈 빌드에 사용 - [Conditional("TRACE")]
- Write
1. Debug / Trace
* Write: 쓰기
* WriteLine: 쓰고 개행
* WriteIf: 첫번째 인자로 조건, 두번째 인자로 쓸 내용. 조건이 맞으면 쓰기
* WriteLineIf: WriteIf의 개행 버전
2. Trace
* TraceInfomation: 정보 속성으로 표시
* TraceWarning: 경고 속성으로 표시
* TraceError: 오류 속성으로 표시
3. Debug
* Print: WriteLine과 동일...? 책에 자세한 설명이 없다
4. 공통 사항
* 기본적으로 디버거의 출력창에 메세지를 보냄
* 활성 TraceListener에 따라 다른 식으로 행동
* 메시지의 범주(Category)를 뜻하는 또 다른 string 인수를 받는 버전도 존재, 디버그 출력을 분류할 때 유용
- Fail - Debug / Trace
* 메시지를 Listeners 컬렉션에 있는 TraceListener 인스턴스들에 보냄
* TraceListener는 해당 메시지를 디버그 출력 창에 기록하고, 메시지 대화상자도 띄움
* 대화 상자: 무시, 취소, 다시 시도 등의 옵션 제공. 다시 시도하는 경우 디버거가 해당 프로세스에 붙음
Debug.Fail("Fail!");
- Assert - Debug / Trace
* 첫 인수가 false면 둘째 인수로 Fail을 호출
* 어떤 조건을 지정해서 Assert를 호출하는 것은, 그 조건이 반드시 참이어야 함을 단언(Assert)하는 역할을 함
* 해당 단언이 참이 아니라면 코드에 버그가 있는 것
* 둘째 인수(단언 실패 메시지)는 생략 가능
Debug.Assert(File.Exists("data.txt"), "data.txt 파일이 존재하지 않음");
* Assert을 이용한 단언 대신 조건+예외도 가능 - 특히 메서드 인수가 유효하지 않을 때 많이 사용
public void Print(string message)
{
if (message == null)
{
throw new ArgumentNullException("message is null!");
}
// 여기에 실행 코드 기입
}
* 위의 예의 단점
1. 무조건 컴파일 됨
2. Assert보다 덜 유연함 - 단언 실패 처리 방식을 제어할 수 없음
3. 엄밀하게 따져서, 단언이 아님(메서드의 코드에 버그가 있는게 아니라, 호출자의 코드에 버그가 있음을 의미)
청취자 배출 및 종료
- 메시지를 스트림에 기록하기 때문에, 버퍼링(캐싱)이 적용 됨
* 메시지가 출력 스트림이나 파일에 즉시 나타나지 않을 수 있음
* 응용 프로그램이 끝나기 전에 청취자를 반드시 닫거나, 적어도 청취자의 내용을 배출(Flush) 해야 함
그렇지 않으면 버퍼에 남아있던 내용이 사라질 수 있음. 버퍼의 크기는 최대 4K 바이트
- Flush
* 모든 청취자에 대해 Flush를 호출 - 바탕 기록자나 스트림에 대해 Flush가 호출 됨
* 현재 메시지 자료가 확실하게 기록되고 싶을 때 사용
- Close
* 모든 청취자에 대해 Close를 호출 - 바탕 기록자나 스트림에 대해 Close가 호출 됨
* 암묵적으로 Flush를 호출
* 파일 핸들들을 닫음
* 해당 파일이나 스트림에 더 이상 자료를 기록 할 수 없도록 설정
* 응용 프로그램 종료 전에 한번 호출
- AutoFlush
* 이 속성을 true로 설정하면 메시지를 기록 할 때마다 자동으로 Flush가 호출 됨
* 파일이나 스트림 기반 청취자일 경우 true로 사용하는 것이 좋음
TraceListener 클래스
namespace System.Diagnostics
{
public abstract class TraceListener : MarshalByRefObject, IDisposable
{
protected TraceListener();
protected TraceListener(string name);
public TraceFilter Filter { get; set; }
public int IndentSize { get; set; }
public int IndentLevel { get; set; }
protected bool NeedIndent { get; set; }
public virtual bool IsThreadSafe { get; }
public virtual string Name { get; set; }
public StringDictionary Attributes { get; }
public TraceOptions TraceOutputOptions { get; set; }
public virtual void Flush();
public virtual void Close();
public void Dispose();
protected virtual void Dispose(bool disposing);
protected virtual void WriteIndent();
protected internal virtual string[] GetSupportedAttributes();
public virtual void Fail(string message);
public virtual void Fail(string message, string detailMessage);
public virtual void TraceData(TraceEventCache eventCache, string source, TraceEventType eventType, int id, object data);
public virtual void TraceData(TraceEventCache eventCache, string source, TraceEventType eventType, int id, params object[] data);
public virtual void TraceEvent(TraceEventCache eventCache, string source, TraceEventType eventType, int id);
public virtual void TraceEvent(TraceEventCache eventCache, string source, TraceEventType eventType, int id, string message);
public virtual void TraceEvent(TraceEventCache eventCache, string source, TraceEventType eventType, int id, string format, paramsobject[] args);
public virtual void TraceTransfer(TraceEventCache eventCache, string source, int id, string message, Guid relatedActivityId);
public abstract void Write(string message);
public virtual void Write(object o);
public virtual void Write(string message, string category);
public virtual void Write(object o, string category);
public abstract void WriteLine(string message);
public virtual void WriteLine(object o);
public virtual void WriteLine(string message, string category);
public virtual void WriteLine(object o, string category);
}
}
TraceFilter 클래스
namespace System.Diagnostics
{
public abstract class TraceFilter
{
protected TraceFilter();
public abstract bool ShouldTrace(TraceEventCache cache, string source, TraceEventType eventType, int id, string formatOrMessage, object[] args, object data1, object[] data);
}
}
TraceOptions 열거형
namespace System.Diagnostics
{
[Flags]
public enum TraceOptions
{
None = 0, // 아무것도 쓰지 않음
LogicalOperationStack = 1, // CorrelationManager.LogicalOperationStack의 논리 작업 스택표시
DateTime = 2, // DateTime 표시
Timestamp = 4, // GetTimestamp로 표시되는 타임 스탬프 표시
ProcessId = 8, // Process.Id로 표시되는 PID 표시
ThreadId = 16, // Thread.ManagedThreadId의 스레드 ID 표시
Callstack = 32 // Environment.StackTrace의 호출 스택 표시
}
}
- 각 TraceListener 인스턴스는 Write나 Fail, Trace 메서드가 보낸 메시지를 처리하는 임무를 수행
- Debug와 Trace에는 Listeners라는 속성이 있음. 이 속성은 TraceListener 인스턴스의 정적 컬렉션
- 두 클래스 모두, 기본적으로 Listeners 컬렉션에 기본 청취자(DefaultTraceListener)가 하나 들어 있음
1. 현재 프로세스가 VS같은 디버거에 연결되어 있으면 메시지를 디버그 창에 기록, 그렇지 않으면 무시
2. Fail 메서드 호출 시(혹은 단언 실패시) 대화 상자를 띄움
(디버거 부착여부와 무관, DefaultTraceListener에서만 띄움)
- 다른 방향의 메시지 처리를 원하면 기본 청취자를 제거하고 다른 추척 청취자를 추가
* TraceListener를 상속해서 커스텀 가능
* 미리 정의된 형식에서 사용
+ TextWriterTraceListener: 메시지를 Stream 또는 textWriter에 기록하거나 파일에 추가
| ConsoleTraceListener: Console
| DelimitedListTraceListener: CSV, Excel
| XmlWriterTraceListener: XML-encoded data
| EventSchemaTraceListener: end-to-end events to an XML-encoded
+ EventLogTraceListener: 메시지를 윈도우즈 이벤트 로그에 기록
+ EventProviderTraceListener: 메시지를 ETW(Event Tracing for Windows) 하위 시스템에 기록
+ WebPageTraceListener: 메시지를 ASP.NET 웹 페이지에 기록
namespace Practice
{
class Program
{
public static void Main(string[] arg)
{
// 기본 청취자(DefaultTraceListener) 제거
Trace.Listeners.Clear();
// 메시지를 trace.txt 파일에 기록하는 청취자 추가
Trace.Listeners.Add(new TextWriterTraceListener("trace.txt"));
// 콘솔의 출력 스트림을 얻고, 그것을 하나의 청취자로 추가
Trace.Listeners.Add(new TextWriterTraceListener(Console.Out));
// Windows 이벤트 로그용 이벤트 출저를 설정하고 청취자를 생성, 추가
// CreateEventSource를 호출하려면 관리자 권한이 필요
// 대체로 응용 프로그램 설치 시 처리
if(!EventLog.SourceExists("DemoApp"))
{
EventLog.CreateEventSource("DemoApp", "Application");
}
Trace.Listeners.Add(new EventLogTraceListener("DemoApp"));
}
}
}
- TraceFilter 형식의 Filter
* 이를 통해 청취자에 기록할 메시지들을 걸러낼 수 있음
* 미리 정의된 파생 클래스(EventTypeFilter, SourceFilter)
* TraceFilter 클래스를 상속한 클래스를 직접 작성해서 ShouldTrace 메서드를 재정의
- IndentLevel, IndentSize: 들여쓰기 설정
- TraceOutputOptions: 출력 옵션 설정
namespace Practice
{
class Program
{
public static void Main(string[] arg)
{
// 기본 청취자(DefaultTraceListener) 제거
Trace.Listeners.Clear();
// 콘솔의 출력 스트림을 얻고, 그것을 하나의 청취자로 추가
var consoleTL = new TextWriterTraceListener(Console.Out);
Trace.Listeners.Add(consoleTL);
// 출력 설정
consoleTL.TraceOutputOptions = TraceOptions.DateTime | TraceOptions.Callstack;
// 경고 출력
Trace.TraceWarning("주황색 경보!");
}
}
}
'C#' 카테고리의 다른 글
[C#] EventLog (Windows 이벤트 로그) (0) | 2023.10.26 |
---|---|
[C#] StackTrace, StackFrame (0) | 2023.10.24 |
[C#] Debugger (0) | 2023.10.22 |
[C#] Contract, Code Contracts(코드 계약) (0) | 2023.10.20 |
[C#] WeakReference (0) | 2023.10.14 |
[C#] GC, GCSettings, 쓰레기 수거(Garbege Collection) (0) | 2023.10.12 |
[C#] IDisposable (Dispose), 종료자(Finalizer) (0) | 2023.10.10 |
[C#] IStructuralEquatable, IStructuralComparable (0) | 2023.10.08 |