이번에는 Logging에 대해서 자세히 알아보겠습니다.
많은 큰 시스템들은 메시지 logging 기능을 지원합니다.
ns-3는 선택적이고, multi-level 접근법을 제공합니다.
logging은 디버깅 정보, 경고, 에러 메시지 또는 원하는 정보를 쉽게 얻을 때 사용합니다.
로그 메시지는 여러 레벨이 있습니다.
LOG_INFO를 활성화하면 오직 NS_LOG_INFO 매크로에 의해 제공되는 메시지만 제공되지만, LOG_LEVEL_INFO를 활성화하면 NS_LOG_DEBUG, NS_LOG_WARN 그리고 NS_LOG_ERROR 매크로에 의한 정보까지 모두 제공됩니다.
logging은 환경변수 NS_LOG에 의해 설정될 수 있습니다.
먼저, 이전 first.cc 예제에서는 LOG_LEVEL_INFO로 설정했기 때문에 INFO 와 그 이하의 모든 레벨들이 활성화되었습니다.
(NS_LOG_INFO, NS_LOG_DEBUG, NS_LOG_WARN, NS_LOG_ERROR)
그 결과 아래와 같은 로그 메시지가 출력됩니다.
여기서 우리는 더 많은 정보를 얻기 위해 스크립트를 바꾸고 다시 컴파일하는 대신, 환경변수 NS_LOG를 사용할 수 있습니다.
$ export NS_LOG=UdpEchoClientApplication=level_all
client application에 대해 ALL 레벨로 변경해주었습니다.
그 결과 client application에 대해서는 모든 정보가 찍히게 됩니다. 이전과 비교해서는 NS_LOG_FUNCTION 레벨이 추가되었습니다.
그래서 시뮬레이션이 진행되는 동안 해당 application의 function이 불릴 때 마다
<logging component name>:<method name>의 형태로 메시지를 보여줍니다.
어떤 경우에는 어떤 method가 해당 로그 메시지를 발생시켰는지 알기 어렵습니다. 그럴때는 아래와 같이 해주면 됩니다.
$ export 'NS_LOG=UdpEchoClientApplication=level_all|prefix_func'
server application도 활성화 시키고 싶을 때는
$ export 'NS_LOG=UdpEchoClientApplication=level_all|prefix_func:UdpEchoServerApplication=level_all|prefix_func'
로그 메시지가 언제 발생했는지 알고 싶을 때는
$ export 'NS_LOG=UdpEchoClientApplication=level_all|prefix_func|prefix_time: UdpEchoServerApplication=level_all|prefix_func|prefix_time'
그 결과 더 자세한 로그 메시지가 출력됩니다.
추가적으로, 모든 컴포넌트에 대한 것을 보고싶을 때는
$ export 'NS_LOG=*=level_all|prefix_func|prefix_time'
이 경우에는 output이 매우 많기 때문에, 별도의 파일로 redirection 해줍니다.
$ ./ns3 run scratch/myfirst > log.out 2>&1
다음으로, 스크립트를 수정하지 않고 ns-3가 행동하는 것을 바꿀 수 있는 다른 방법은 command-line argument를 이용하는 것입니다.
그러기 위해서는 먼저 main문 안에 다음과 같이 선언해줍니다.
CommandLine cmd;
cmd.Parse (argc, argv);
그리고 'PrintHelp' 옵션을 주어 실행시켜 줍니다.
$ ./ns3 run "scratch/myfirst --PrintHelp"
그러면 아래와 같은 결과가 나옵니다.
일반적으로 사용할 수 있는 argument 리스트입니다.
이것들 중에서 '--PrintAttributes' 라는 옵션을 보면, typeid는 클래스 이름을 의미합니다. 그래서 first.cc에서 PointToPointNetDevice의 Attribute을 설정해주었던 것을 생각하면서
$ ./ns3 run "scratch/myfirst --PrintAttributes=ns3::PointToPointNetDevice"
위와 같이 명령어를 입력하게되면
저희가 설정했던 attribute 이외의 것들도 모두 확인할 수 있습니다.
$ ./ns3 run "scratch/myfirst
--ns3::PointToPointNetDevice::DataRate=5Mbps
--ns3::PointToPointChannel::Delay=2ms
--ns3::UdpEchoClient::MaxPackets=2"
그리고 attribute 값을 command line에서 변경시킬 수 있습니다.
또한, 자신만의 값을 통제할 수도 있습니다.
uint32_t nPackets = 1;
CommandLine cmd;
cmd.AddValue("nPackets", "Number of packets to echo", nPackets);
cmd.Parse (argc, argv);
먼저 main에서 nPackets라는 지역변수를 선언해주고, AddValue 메서드를 사용해서 등록해줍니다.
$ ./ns3 build
$ ./ns3 run "scratch/myfirst --PrintHelp"
그리고 실행하게 되면
위와 같이 'Program Options'라고 우리만의 옵션이 생기게 됩니다. 기본 옵션과 마찬가지로 값을 변경할 수 있습니다.
이제부터는 Tracing System에 대해서 알아보겠습니다.
시뮬레이션의 목적은 연구에 사용할 유의미한 output을 만들어내는 것입니다.
단순히 print문을 집어넣거나 logging 모듈을 사용할 수도 있지만, 이런 방법들은 문제점이 많습니다. 그래서 tracing system이 제공됩니다.
ns-3 tracing system은 서로 독립적인 tracing source와 tracing sink 개념으로 이루어집니다. 그리고 source를 sink에 연결하는 메커니즘을 사용합니다.
trace source
event를 만들어내고 흥미로운 data에 대한 접근을 제공합니다.
trace source는 그 자체로는 쓸모없고
그 정보(source가 만들어낸)로 실제로 유용한 일을 할 수 있는 코드(sink)와 연결되어야 합니다.
trace sink
source에 의해 제공되는 event와 data의 소비자입니다.
high-level tracing은 helper를 사용하여 미리 정의된 source를 이미 존재하는 sink에 연결합니다.
high-level tracing의 예로는 ASCII, PCAP tracing이 있습니다.
low-level tracing은 source를 custom sink에 직접 연결합니다.
output이 ASCII 파일로 생성되어서 붙여진 이름입니다.
myfirst.cc에서 Simulator::Run()을 호출하기 전에, 아래의 코드를 추가해줍니다.
AsciiTraceHelper ascii;
pointToPoint.EnableAsciiAll (ascii.CreateFileStream ("myfirst.tr"));
마찬가지로 helper를 사용해서 "myfirst.tr"이라는 파일 객체를 만들어주고
EnableAsciiAll()을 호출하여, 모든 point-to-point device들을 ASCII tracing 하게하고
자동으로 trace sink(미리 제공된)가 ASCII 형식으로 패킷에 관한 정보를 작성하게 됩니다.
이제 결과물을 보겠습니다.
output 파일은 한 줄이 매우 긴 여러 줄로 구성되어 있습니다.
각 줄은 trace event에 해당합니다. 위 사진은 한 줄을 보기 쉽게 만든 것입니다.
또 다른 high-level tracing system은 PCAP(packet capture) tracing 입니다.
.pcap 형태의 trace 파일이 생성됩니다. 이 파일은 tcpdump, Wireshark 등에 의해서 분석될 수 있습니다.
pointToPoint.EnablePcapAll ("myfirst");
아까와 동일한 위치에 위 코드를 추가해줍니다.
그리고 실행하게 되면 myfirst-0-0.pcap, myfirst-1-0.pcap 파일이 생성됩니다.
<myfirst>-<node 번호>-<device 번호>.pcap 형태 입니다.
이제 tcpdump를 사용해서 output을 분석 해보겠습니다.
$ tcpdump -nn -tt -r myfirst-0-0.pcap
결과를 확인해보면, 우리가 시나리오를 만든대로 패킷이 전송되었음을 확인할 수 있습니다.
Wireshark 프로그램을 사용해서도 확인할 수 있습니다.
❗❗초보자의 수준에서 작성 된 글입니다❗❗
잘못 된 내용이 있으면 피드백 부탁드립니다.