로깅
프레임워크 로깅
Photon은 log4net을 이용하여 프레임워크를 로깅합니다.
문서:
https://logging.apache.org/log4net/
로그파일과 위치
3종류의 로그 파일이 있습니다:
1. 관리되지 않는 Photon 소켓 서버 로그:
- Content: 비관리 PhotonSocketServer.exe 코어가 파일에 기록 됩니다.
코어의 예외( Photon 자체의 버그, 유효하지 않는 클라이언트에 대한 직렬화 오류 등 과 같은)뿐만 아니라 Photon의 시작/종료의 모든 상태 메시지 로그가 여기에 기록 됩니다 . - 이름: Photon-(인스턴스명)-Timestamp.log
- 위치: /bin_WinXXX/log
- Log 레벨 환경 설정: n/a
- 로그 파일 위치 변경: PhotonServer.config 내의 각 인스턴스 노드의 "LogFileLocation" 속성을 설정합니다."LogFileLocation" 은 절대 경로 또는 PhotonSocketServer.exe 기준의 상대경로가 될 수 있습니다.
예제:
XML
<Default
MinimumTimeout="5000"
MaximumTimeout="30000"
LogFileLocation="..\MyLogFolder"
>
2. 관리되는 CLR 로그:
내용:
어플리케이션을 호스트 하고 있는 매니지드 .NET 런타임에 의해서 기록됩니다. CLR 의 모든 상태 메시지의 로그 (예: 로드된 .NET 어플리케이션 & 어셈블리에 대한 정보) 와 커스텀 .NET 어플리케이션의 모든 처리되지 않은 예외들이 여기에 기록 됩니다.이름: PhotonCLR.log
위치: /bin_WinXXX/log
로그 레벨 환경설정: /deploy/bin_WinXXX/Photon.local.log4net 에서 적당한 log4net appender 를 설정 하세요.
로그파일 위치 변경: /deploy/bin_WinXXX/Photon.local.log4net 에서 적당한 log4net appender 를 설정 하세요 - "Photon:UnmanagedLogDirectory" 프로퍼티를 사용할 수 있는데 여기에는 PhotonServer.config 파일의 "LogFileLocation" 값이 포함되어 있습니다.
예:
XML
<appender name="A1" type="log4net.Appender.RollingFileAppender">
<file type="log4net.Util.PatternString" value="%property{Photon:UnmanagedLogDirectory}\\PhotonCLR.log" />
<!-- snip -->
</appender>
3. 어플리케이션 로그:
- 내용: Photon 이 호스트 하고 있는 각 .NET 어플리케이션은 각각의 어플리케이션 로그 파일에 로그를 기록 합니다. 여기에는 어플리케이션의 모든 디버그 출력결과가 포함되어 있습니다.
- 이름: {MyApplication}.log
- 위치: /deploy/log
- 로그파일 위치 변경: /deploy/{MyApplication}/bin/log4net.config 에서 적당한 log4net appender 를 설정 하세요.
"Photon:ApplicationLogPath" 프로퍼티를 사용할 수 있는데 기본값으로 /deploy/log 로 설정되어있으며 어플리케이션에서 Setup() 메소드를 통하여 변경할 수 있습니다.
C#
protected override void Setup()
{
// log4net
log4net.GlobalContext.Properties["Photon:ApplicationLogPath"] = Path.Combine(this.ApplicationRootPath, "log");
var configFileInfo = new FileInfo(Path.Combine(this.BinaryPath, "log4net.config"));
if (configFileInfo.Exists)
{
LogManager.SetLoggerFactory(Log4NetLoggerFactory.Instance);
XmlConfigurator.ConfigureAndWatch(configFileInfo);
}
}
- 로그 레벨 환경설정: /deploy/{MyApplication}/bin/log4net.config 파일에서 적당한 log4net appender 를 설정 해주세요.
예제:
XML
<?xml version="1.0" encoding="utf-8" ?>
<log4net debug="true" update="Overwrite">
<appender name="LogFileAppender" type="log4net.Appender.RollingFileAppender">
<file type="log4net.Util.PatternString" value="%property{Photon:ApplicationLogPath}\\{MyApplication}.log" />
<!-- snip -->
</appender>
<root>
<!-- <level value="INFO" /> -->
<!-- <level value="DEBUG" /> -->
<level value="ALL" />
<appender-ref ref="LogFileAppender" />
</root>
</log4net>
FAQ
클라이언트가 연결/연결해제 됐을 때마다 어떻게 로그 항목을 작성하나요?
어플리케이션의 log4net.config 에 다음을 추가해 주세요:
XML
<logger name="Photon.SocketServer.ApplicationBase">
<level value="DEBUG"/>
</logger>
{MyApplication}.log의 출력결과:
Successful connect:
2013-05-02 11:19:02,506 [23] DEBUG Photon.SocketServer.ApplicationBase [(null)] - OnInit - ConnID=17, IP 127.0.0.1 on port 4530
2013-05-02 11:19:02,506 [23] DEBUG Photon.SocketServer.ApplicationBase [(null)] - OnInit - response sent to ConnId 17 with SendResult Ok
Disconnect:
2013-05-02 11:19:07,608 [24] DEBUG Photon.SocketServer.ApplicationBase [(null)] - OnDisconnect - ConnID=17
Photon 이 클라이언트에게 오퍼레이션 응답을 전송할 때 로그 항목을 어떻게 작성하나요?
어플리케이션의 log4net.config 에 다음을 추가해 주세요:
XML
<logger name="Photon.SocketServer.PeerBase">
<level value="DEBUG"/>
</logger>
(MyApplication).log 출력결과:
2013-05-02 11:19:02,569 [21] DEBUG Photon.SocketServer.PeerBase [(null)] - SentOpResponse: ConnID=17, opCode=255, return=0, ChannelId=0 result=Ok size=14 bytes
Photon 이 클라이언트로부터 오퍼레이션 요청을 받았을 때 어떻게 로그항목을 작성하나요?
이 종류의 로깅은 어플리케이션의 Peer 클래스에서 처리하는 것이 가장 좋습니다.(Peer 클래스는 PeerBase 에서 상속된 클래스입니다).
Lite의 예제:
XML
<logger name="Lite.LitePeer">
<level value="DEBUG"/>
</logger>
(MyApplication).log의 출력결과:
2013-05-02 11:19:02,553 [21] DEBUG Lite.LitePeer [(null)] - OnOperationRequest. Code=255
로그 항목의 내용을 OnOperationRequest 메소드에서 변경할 수 있습니다.
Lite.LitePeer의 예제:
C#
protected override void OnOperationRequest(OperationRequest operationRequest, SendParameters sendParameters)
{
if (log.IsDebugEnabled)
{
log.DebugFormat("OnOperationRequest. Code={0}", operationRequest.OperationCode);
}
// snip
}
왜 클라이언트의 연결이 해제 되나요? 어떻게 타임아웃을 디버그 할 수 있나요?
연결 해제에는 4종류가 있습니다.:
- ClientDisconnect: 클라이언트가 연결을 종료
- ManagedDisconnect: 매니지드 .NET 어플리케이션이 PeerBase.Disconnect() 호출
- ServerDisconnect: Photon 내의 예외가 클라이언트의 연결해제의 원인입니다. 비관리되는 Photon 소켓 서버로그에서 예외에 대한 상세내용을 조사 해봐야 합니다.
- TimeoutDisconnect: 특정 시간이 지난 후에도 예상되는 데이터를 수신하지 못한 경우 Photon 이 연결을 종료 하는 경우 입니다.
클라이언트가 왜 연결이 해제 되었는지를 보기 위해서 Peer 에서 OnDisconnect 가 호출 되었을 때 디버그 로그를 작성하도록 어플리케이션을 설정 해 주세요.
Lite 의 예제:
XML
<logger name="Lite.LitePeer">
<level value="DEBUG"/>
</logger>
PeerBase 에서 상속된 Peer 클래스의 OnDisconnect() 메소드는 다음과 같아야 합니다:
C#
protected override void OnDisconnect(DisconnectReason reasonCode, string reasonDetail)
{
if (log.IsDebugEnabled)
{
log.DebugFormat("OnDisconnect: conId={0}, reason={1}, reasonDetail={2}", this.ConnectionId, reasonCode, reasonDetail);
}
// snip
}
(MyApplication).log 출력결과:
2013-05-02 11:19:07,639 [12] DEBUG Lite.LitePeer [(null)] - OnDisconnect: conId=17, reason=ClientDisconnect, reasonDetail=
UDP 사용시: "TimeoutDisconnect" 의 경우 "reasonDetail" 에는 라운드트립타임 내역을 아래와 같이 포함하고 있습니다:
index - sequence - rtt - variance - sentTime - recvTime - cmd_rtt
0 - 326 - 0 - 0 - 830717056 - 830728351 - 11295
1 - 325 - 89 - 19 - 830715918 - 830716042 - 124
2 - 324 - 85 - 14 - 830714826 - 830714904 - 78
3 - 323 - 86 - 17 - 830712751 - 830712813 - 62
4 - 322 - 89 - 14 - 830711659 - 830711737 - 78
5 - 321 - 90 - 16 - 830710551 - 830710645 - 94
6 - 320 - 90 - 19 - 830709428 - 830709537 - 109
7 - 319 - 88 - 19 - 830708320 - 830708414 - 94
8 - 318 - 88 - 23 - 830707197 - 830707306 - 109
9 - 317 - 86 - 24 - 830706105 - 830706183 - 78
10 - 316 - 87 - 29 - 830704701 - 830704763 - 62
... etc ...
각 라인은 다음의 값들로 구성되어 있습니다.
- index (0...49, 0 이 가장 최근값이며 49가 가장 오래된 것입니다. 50 개 항목까지만 보여집니다.)
- sequence - 증가하는 일련번호
- rtt (RoundTripTime - 현재 RTT를 ms으로 표시 - ACK 또는 타임아웃이 발생된 이후 사용 가능함)
- variance (현재 변화량 ms)
- sentTime (명령 전송 시간)
- recvTime (ACK 수신 시간)
- cmd_rtt (명령 전송과 ACK 수신된 시간 차이 ms)
위의 예제에서는 클라이언트는 cmd_rtt 가 62 ms 에서 124 ms 의 값을 가지고 있습니다; 마지막 명령어 전송 이후 11초가 경과되어 ACK 를 수신 받지 못했기 때문에 연결이 해제 되었습니다.
Back to top