iOS os.log 模組

ZY_FlyWay發表於2019-03-14

Logging

有效地將日誌訊息捕獲到記憶體和磁碟。管理日誌行為和永續性。

Framework

  • os

On This Page

Overview

統一日誌系統提供了一個單一的、高效的、高效能的API,用於捕獲跨系統所有級別的訊息傳遞。這個統一的系統將日誌資料集中儲存在記憶體和磁碟上的資料儲存中。系統實現控制日誌行為和永續性的全域性設定,同時通過日誌命令列工具和使用定製日誌配置檔案在除錯期間提供細粒度控制。使用/Applications/Utilities/中的控制檯應用程式和Log命令列工具可以檢視日誌訊息。整合了日誌記錄和活動跟蹤,使問題診斷更容易。如果在日誌記錄時使用活動跟蹤,則會自動關聯相關訊息。

Important

統一日誌可以在iOS 10.0及以後版本、macOS 10.12及以後版本、tvOS 10.0及以後版本、watchOS 3.0及以後版本中使用,並取代了ASL (Apple System Logger)和Syslog api。以前,日誌訊息被寫到磁碟上的特定位置,比如/etc/system.log。統一日誌系統將訊息儲存在記憶體和資料儲存中,而不是寫入基於文字的日誌檔案。

 

Log Levels

統一日誌系統使用了幾個日誌級別,它們對應於應用程式可能需要捕獲的不同型別的訊息,並定義訊息何時儲存到資料儲存中,以及訊息儲存多長時間。系統為每個級別實現標準行為。可以使用日誌命令列工具或自定義配置檔案覆蓋此行為(請參閱除錯時自定義日誌行為)。

default

預設級別的訊息最初儲存在記憶體緩衝區中。在不更改配置的情況下,它們將被壓縮並隨著記憶體緩衝區的填充移動到資料儲存區。它們會一直保留到超過儲存配額,此時,最古老的訊息將被清除。使用此級別捕獲可能導致失敗的資訊。

info

資訊級訊息最初儲存在記憶體緩衝區中。如果不進行配置更改,則不會將它們移動到資料儲存區,並在記憶體緩衝區填充時清除它們。但是,當發生錯誤或錯誤時,它們會在資料儲存中捕獲。當資訊級別的訊息被新增到資料儲存中時,它們將一直保留在那裡,直到超過儲存配額,此時,最古老的訊息將被清除。使用此級別捕獲對故障排除可能有幫助但不是必需的資訊。

debug

除錯級別的訊息只在通過配置更改啟用除錯日誌記錄時在記憶體中捕獲。根據配置的永續性設定清除它們。此級別記錄的訊息包含在開發期間或排除特定問題時可能有用的資訊。除錯日誌記錄用於開發環境,而不是釋出軟體。

error

錯誤級別的訊息總是儲存在資料儲存中。它們會一直保留到超過儲存配額,此時,最古老的訊息將被清除。錯誤級訊息用於報告流程級錯誤。如果存在活動物件,則此級別的日誌記錄將捕獲整個流程鏈的資訊。

fault

故障級訊息總是儲存在資料儲存中。它們會一直保留到超過儲存配額,此時,最古老的訊息將被清除。故障級訊息僅用於捕獲系統級或多程式錯誤。如果存在活動物件,則此級別的日誌記錄將捕獲整個流程鏈的資訊。

Performing Logging

要向日志系統傳送訊息,請呼叫os_log函式,並可以選擇傳遞一個日誌物件和一個日誌級別。提供一個日誌物件(預設常量或自定義OSLog物件)和一個表示訊息的常量字串或格式字串。預設常量導致日誌記錄按照系統的標準行為進行。自定義日誌物件根據特定子系統的日誌概要檔案中包含的設定導致日誌記錄的發生。

Listing 1 

Logging a default-level message

os_log("This is a log message.")

Listing 2 

Logging an info-level message

os_log("This is additional info that may be helpful for troubleshooting.", log: OSLog.default, type: .info)

Listing 3 

Logging a debug-level message for a specific subsystem

let customLog = OSLog(subsystem: "com.your_company.your_subsystem_name.plist", category: "your_category_name")
os_log("This is info that may be helpful during development or debugging.", log: customLog, type: .debug)

 

Important

大於系統最大訊息長度的日誌訊息行在日誌系統儲存時將被截斷。當使用log命令列工具檢視活動的實時流時,完整的訊息是可見的。但是請記住,流日誌資料是一項昂貴的活動。

Privacy

統一日誌系統認為動態字串和複雜的動態物件是私有的,不會自動收集它們。為了確保使用者的隱私,建議日誌訊息嚴格由靜態字串和數字組成。在需要捕獲動態字串的情況下,可以使用關鍵字public顯式地宣告字串public。例如,%{public}s.

 

Formatting Log Messages

要格式化日誌訊息,請使用標準的NSString或printf格式字串,如清單4所示。有關格式化規則,請參閱字串格式說明符。

Listing 4 

Logging a message using a format string

os_log(OS_LOG_DEFAULT, "Downloaded a file. Size: %zd", fileSize);

除了標準格式字串說明符(如%@和%d)之外,日誌系統還支援通過以%{value_type}d格式內聯表示值型別來對值進行自定義解碼。此外,說明符%。*P可以用來解碼任意二進位制資料。系統包括許多內建的值型別解碼器,如表1所示

Table 1 

Builtin value type decoders

Value type

Custom specifier

Example output

time_t

%{time_t}d

2016-01-12 19:41:37

timeval

%{timeval}.*P

2016-01-12 19:41:37.774236

timespec

%{timespec}.*P

2016-01-12 19:41:37.2382382823

errno

%{errno}d

Broken pipe

iec-bytes

%{iec-bytes}d

2.64 MiB

bitrate

%{bitrate}d

123 kbps

iec-bitrate

%{iec-bitrate}d

118 Kibps

uuid_t

%{uuid_t}.*16P

%{uuid_t}.*P

10742E39-0657-41F8-AB99-878C5EC2DCAA

Viewing Log Messages

使用控制檯應用程式或日誌命令列工具檢視和篩選日誌訊息。

Customizing Logging Behavior While Debugging

日誌記錄行為通常由系統控制。但是,在macOS中除錯時,可以使用log命令列工具的configargument在以root身份登入時為子系統啟用不同的日誌級別。參見清單5,它顯示瞭如何為子系統啟用除錯級日誌記錄。

Listing 5 

Enabling debug-level logging for a subsystem

$ sudo log config --mode "level:debug" --subsystem com.your_company.your_subsystem_name

使用日誌工具的狀態引數檢查子系統的當前日誌級別。參見清單6。

Listing 6 

Checking the log level of a subsystem

$ sudo log config --status --subsystem com.your_company.your_subsystem_name
Mode for 'com.your_company.your_subsystem_name'  DEBUG

您還可以通過在/Library/Preferences/ logging /子系統/目錄中建立和安裝日誌配置檔案屬性列表檔案來覆蓋特定子系統的日誌行為。使用表示子系統的識別符號字串(反向DNS表示法)命名檔案。例如,com.your_company.your_subsystem_name.plist。接下來,將一個或多個設定字典新增到檔案的頂層。預設選項設定字典為整個子系統定義全域性行為設定。類別設定字典為子系統中特定類別的訊息定義行為。參見清單7所示。

Listing 7 

Top level structure of a logging profile

<dict>
    <key>DEFAULT-OPTIONS</key>
    <dict>
       <!-- GLOBAL SUBSYSTEM OR PROCESS SETTINGS -->
    </dict>
    <key>CategoryName</key>
    <dict>
       <!-- CATEGORY SETTINGS -->
    </dict>
</dict>

日誌配置檔案中的每個設定字典都包含一個Level子字典,其中包含以下設定鍵:

Key

Description

Enable

Enables a specific log level.

Persist

Controls whether messages are stored in memory and then saved to the data store, or stored in memory only.

Enable鍵和Persist鍵都接受以下字串值:

Value

Description

Inherit

Explicitly states that the subsystem or category inherits the behavior of its parent. In the case of a category, the parent is the subsystem. In the case of a subsystem, the parent is the system.

Default

Only default-level messages are captured.

Info

Default-level and info-level messages are captured.

Debug

Default-level, info-level, and debug-level messages are captured.

清單8顯示了一個級別子字典的示例,它支援繼承子系統或系統永續性行為的資訊級別日誌記錄。

Listing 8 

日誌配置檔案設定字典中級別子字典的示例

<key>Level</key>
<dict>
    <key>Enable</key>
    <string>Info</string>
    <key>Persist</key>
    <string>Inherit</string>
</dict>

清單9顯示了一個完整日誌概要檔案的示例,它配置了一個子系統來執行資訊級日誌記錄,並在子系統中配置了一個伺服器連線類別來執行除錯級日誌記錄。

Listing 9 

Example of a complete logging profile

<dict>
    <key>DEFAULT-OPTIONS</key>
    <dict>
        <key>Level</key>
        <dict>
            <key>Enable</key>
            <string>Info</string>
            <key>Persist</key>
            <string>Inherit</string>
        </dict>
    </dict>
    <key>server-connections</key>
    <dict>
        <key>Level</key>
        <dict>
            <key>Enable</key>
            <string>Debug</string>
            <key>Persist</key>
            <string>Inherit</string>
        </dict>
    </dict>
</dict>

Note

子系統繼承系統的日誌記錄行為,而類別繼承它們所在子系統的行為。因此,只有當設定與繼承行為不同時,才需要指定設定。

Logging Best Practices

遵循這些指導原則可以生成有用且有效的日誌訊息。

儘可能使用格式字串和說明符自動生成使用者友好的日誌訊息,而不是試圖編寫自定義格式程式碼。參見格式化日誌訊息。

不要在訊息中包含符號資訊或原始檔行號。系統自動捕獲這些資訊。

相關文章