[WCF] Global Level에서 Exception 처리 또는 기록
2009. 11. 22. 15:46ㆍWEB/WebService
서문
Applcation에서 발생한 Exception을 분석하고 처리하기 위해 Exception을 파일로 기록하려는 경우, 모든 Try, Catch에 Exception을 기록하는 로직을 두는 것은 여간 괴로운 일이 아닙니다. 이러한 코드 작성 방식은 시스템 유지보수에 있어서 더 치명적입니다. 여기에서는 WCF에서 발생하는 Exception을 OS의 EventLog에 기록하는 클래스를 작성하고 WCF Service에 부여하는 방법에 대해서 소개할 것입니다.
Exception을 기록하는 것 뿐만 아니라, Application 전역에서 발생하는 모든 Exception에 대해서 특정한 동작을 부여하고 싶을 분들에게 이 포스트가 도움이 될 수 있습니다.
구현
이 기능의 구현은 WCF를 확장하는 몇 가지 Interface를 구현하고 Web.Config에 설정을 추가하는 것만으로 실현될 수 있습니다.
- IErrorHandler Interface를 구현하여 에러 처리기를 작성합니다.
HandleError Method는 Exception이 발생할 때마다 실행될 것입니다. 마지막에 return false;를 통해 Exception이 Handle되지 않도록 하였습니다.12345678910111213141516171819202122232425using
System;
using
System.ServiceModel.Dispatcher;
using
System.ServiceModel.Channels;
using
System.Diagnostics;
/// <summary>
/// 이벤트 처리기
/// </summary>
public
class
ErrorHandler : IErrorHandler
{
public
void
ProvideFault(Exception error, MessageVersion version,
ref
Message fault)
{
//이 Method는 Exception을 Fault로 바꾸고자 할 때 사용합니다.
}
public
bool
HandleError(Exception error)
{
//1. EventSource 생성
if
(!EventLog.SourceExists(
"NakedStrength"
))
EventLog.CreateEventSource(
"NakedStrength"
,
"Application"
);
//2. Exception 쓰기
EventLog.WriteEntry(
"NakedStrength"
, error.ToString());
return
false
;
}
}
- 동작중인 각 Service에 위에서 작성한 ErrorHandler를 추가하는 Service Behavior의 작성이 필요합니다. 이 것은 IServiceBehavior Interface를 상속함으로서 구현가능합니다.
ApplyDispatchBehavior Method에서 위에서 작성한 ErrorHandler를 생성하여 동작 중인 ServiceChannel에 추가하고 있습니다.123456789101112131415161718192021222324252627
using
System;
using
System.ServiceModel.Description;
using
System.ServiceModel;
using
System.Collections.ObjectModel;
using
System.ServiceModel.Channels;
using
System.ServiceModel.Dispatcher;
/// <summary>
/// ErrorHandler를 모든 Service Channel에 적용하는 ServiceBehavior
/// </summary>
public
class
ErrorServiceBehavior : IServiceBehavior
{
public
void
Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
}
public
void
AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
{
}
public
void
ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
ErrorHandler handler =
new
ErrorHandler();
foreach
(ChannelDispatcher dispatcher
in
serviceHostBase.ChannelDispatchers)
dispatcher.ErrorHandlers.Add(handler);
}
}
- 이제 위에서 생성한 Service Behavior를 Web.Config에 추가하기 위해 Extension Element을 생성해야 합니다.
1234567891011121314151617181920
using
System;
using
System.ServiceModel.Configuration;
/// <summary>
/// 생성한 ErrorServiceBehavior를 Web.Config에 추가히기 위해 확장엘리먼트로 생성
/// </summary>
public
class
ErrorHandlerBehavior : BehaviorExtensionElement
{
protected
override
object
CreateBehavior()
{
return
new
ErrorServiceBehavior();
}
public
override
Type BehaviorType
{
get
{
return
typeof
(ErrorServiceBehavior);
}
}
}
- 마지막으로 WCF의 Web.Config의 <system.serviceModel> Element를 다음과 같이 구성합니다.
1234567891011
<
system.serviceModel
>
<
extensions
>
<
behaviorExtensions
>
<!-- Exception Log 기능 추가 -->
<
add
name
=
"ExceptionLogger"
type
=
"Dispatch.Service.ErrorHandlerBehavior, Dispatch.Service, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
/>
</
behaviorExtensions
>
</
extensions
>
.. 기타 노드
</
system.serviceModel
>
결과
이로서 모든 설정은 마쳤습니다. 이제 Exception을 발생시키면 다음과 같이 Event Log에 기록으로 남을 것입니다. OS의 Event View를 통해 확인하면 다음과 같습니다.
Event Logging에 대한 더 자세한 정보
'WEB > WebService' 카테고리의 다른 글
[WCF-Rest] WCF-Rest를 이용한 동기식 SOAP Receiver (0) | 2009.12.04 |
---|---|
[WCF] WCF-Rest를 이용한 SOAP Receiver (0) | 2009.11.30 |
[WCF] 대용량 데이터를 서버로 전송하기 위해 필요한 설정 (0) | 2009.11.27 |