NS3 Logging Module 日誌模塊

一 概述日誌


日誌是快速獲得腳本和模型的調試信息、警告信息、錯誤信息或者其他信息的首選。
NS3日誌模塊提供了一個直觀的、相對簡單的方法來獲取仿真過程中的有用信息。在NS3中,不同詳盡級別的日誌都是有用的,爲了方便高效,NS3提供了可供選擇的、多級別的方法來記錄日誌,例如可以完全禁用日誌、僅對部分組件可用、或者全局可用。並且NS3將日誌分成了七個詳盡遞增的級別:

NS_LOG_ERROR——Log error messages. 記錄錯誤信息

NS_LOG_WARN——Log warning messgaes. 記錄警告信息

NS_LOG_DEBUG——Log relatively rare, ad-hoc debugging messages. 記錄相對不常見ad-hoc的調試信息

NS_LOG_INFO——Log informational messages about program progress. 記錄程序進展信息

NS_LOG_FUNCTION——Log a message describing each function called. 記錄描述每個調用函數信息

NS_LOG_LOGIC——Log messages describing logical flow within a function. 記錄一個函數內描述邏輯流程的信息

NS_LOG_ALL——Log everything mentioned above. 記錄所有信息

此外,還有一種一直被使用的無條件日誌級別,與日誌級別或者組件選擇無關。

NS_LOG_UNCOND——Log theassociated message unconditionally. 無條件記錄相關消息


每個級別可以被單獨調用或者累計調用。日誌的配置可以通過使用一個shell環境變量或者調用日誌系統函數。

使用日誌


在ns3的目錄/ns3/ns-allinone-3.25/ns-3.25/examples/tutorial下邊有個third.cc程序,它是一個關於UDP的CS模型(服務器和客戶端通信模型),我們拿這個作爲例子講解。
首先,將這個例子複製到 /ns3/ns-allinone-3.25/ns-3.25/scratch
命令./waf –run=scratch/third編譯執行這個程序。
這裏寫圖片描述

輸出的四行數據就是我們的CS通信過程。然而爲什麼會輸出四句話呢?我們在程序中並沒有輸出語句?原因也很簡單,就是本文所講的日誌模塊。也就是說上面的“sent”和“received”的消息來自於UdpEchoClientApplication和UdpEchoServerApplication的日誌消息。我們在third.cc程序中由這樣兩行:

這裏寫圖片描述


LogComponentEnable(“UdpEchoClientApplication”,LOG_LEVEL_INFO); //設置日誌級別爲LOG_LEVEL_INFO,當傳遞一個日誌標誌時,實際上打開了該級別及其以下的所有級別。所以,這行代碼表示打開了NS_LOG_INFO,NS_LOG_DEBUG,NS_LOG_WARN,NS_LOG_ERROR。(高等級包括低等級)。


然而我們可以修改日誌等級,方便我們調試和理解程序實現細節。通過設置NS_LOG環境變量,在不改變腳本和重新編譯的情況下來增加日誌的級別:

幾種常用日誌級別

(1)export ‘NS_LOG=UdpEchoClientApplication=level_all’


設置shell環境變量NS_LOG爲字符串:
UdpEchoClientApplication=level_all
等號左邊:想要設置的日誌組件名稱
等號右邊:要用的日誌級別

這裏寫圖片描述


我們看到輸出的信息比之前增加了。這些額外的調試信息是來自NS_LOG_FUNTION級別的日誌。這些信息顯示了在腳本運行期間程序中每個函數調用過程。

(2)export ‘NS_LOG=UdpEchoClientApplication=level_all|prefix_func’


在某些情況下,很難確定某條日誌消息是由哪個方法產生的。所以,爲了得知日誌消息的來源,可以通過在NS_LOG環境變量中的prefix|func級別來解決。
這裏寫圖片描述


現在每條消息的來源都非常的明確。

(3)export

‘NS_LOG=UdpEchoClientApplication=level_all|prefix_func:UdpEchoServerApplication=level_all|prefix_func’

這樣可以看到來自echo客戶端和服務器的所有日誌消息,這樣方便調試。

這裏寫圖片描述

(4)可以通過prefix_time來知道仿真時間

這裏寫圖片描述


可以看到UdpEchoServer的構造函數在仿真的第0秒被調用。事實上這實在仿真開始之前就完成了,但時間顯示的是0秒。UdpEchoClient的構造函數也是一樣。


在scratch/third.cc腳本中,1秒時啓動回顯服務器應用。可以看到服務器的StartApplication實際上是在1秒時被調用。同樣,客戶端響應程序正如我們所預料的在仿真2秒時開始。


我們現在可以看到仿真的進度了,我們可以看到從ScheduleTransmit函數在客戶端中調用send函數,到回顯服務器中調用HandleRead函數的整個過程了。注意到通過點到點連接發送包消耗時間是3.69毫秒。查看回顯服務器日誌記錄了一條消息告訴你已經響應了數據包。在另一個通道延遲後,可以看到響應客戶端用它HandleRead方法收到響應包。


當碰到一個問題或是不知道那裏出錯了,我們可以選擇使用最詳細的日誌功能,這樣可以很簡單的跟蹤程序,而無需設置斷點並且在調試器中一步步運行代碼,用喜歡的編輯器來打開查看日誌,尋找問題所在。當對錯誤有了大致瞭解之後,我們使用調試器對問題有個非常詳細的檢查。當你的腳本做了完全非預期的事,這種輸出將是非常有用的。如果你使用調試器單步運行,或許你會錯過偏差的部分。日誌使得這些偏差非常明顯。

三 爲自己的腳本添加日誌功能


可以通過幾個宏調用日誌組件給仿真增加新的日誌功能。
例如在first.cc中,我們已經定義了一個組件:
NS_LOG_COMPONENT_DEFINE(“FirstScriptExample”);
我們已經瞭解了通過設置NS_LOG環境變量來給組件啓用日誌功能。我們可以給腳本增加一些日誌功能。用來增加信息級別的日誌消息的宏是NS_LOG_INFO。
現在我們來增加一個日誌消息,顯示本腳本在“創建拓撲”:

這裏寫圖片描述


注:用waf編譯腳本並且清除NS_LOG環境變量,來關掉之前啓用的日誌文件
./waf export NS_LOG=


然後運行腳本,但是看不到新的日誌消息,那是因爲與它相關的日誌組件(FirstScriptExample)沒有被啓用。爲了看到該日誌的消息,必須使用大於或等於NS_LOG_INFO的日誌級別來啓用FirstScriptExample日誌組件。如果只是想要看某個級別的日誌,你可以通過下面的語句來啓用它,

$ export NS_LOG=FirstScriptExample=info


再運行腳本,可以看到“Creating Topology”的日誌消息。

這裏寫圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章