为什么调用 setenv("OS_ACTIVITY_DT_MODE", "disable", 1) 不影响日志记录? 获取模拟器的当前日志首选项:获取某个类别和子系统的状态获取帮助为特定子系统和类别设置日志级别

问题描述

通过在运行方案中将 OS_ACTIVITY_MODE 环境变量设置为 disable,可以在 Swift 中隐藏由 3rd 方库生成的过于冗长的日志 - 如下图所示。

这会使您的应用的所有 NSLog 输出静音。我只想为某些呼叫禁用它。我尝试像这样设置环境变量:

setenv("OS_ACTIVITY_MODE","disable",1)

像这样

putenv(UnsafeMutablePointer<Int8>(mutating: ("OS_ACTIVITY_MODE=disable" as Nsstring).utf8String))

通过调用 print(ProcessInfo.processInfo.environment) 验证环境已更改,但与在 XCode 运行方案中指定不同,日志不受影响。

为什么它不起作用以及如何修复它?

enter image description here

解决方法

因为环境变量通常只在程序启动时读取一次。

在libdispatch 442.1.4中,在_voucher_init中读取OS_ACTIVITY_MODE变量来确定一个内部变量的值; _voucher_init 依次在 libdispatch_init 中调用,它仅在程序启动时调用一次。有趣的是,我在库的更高版本中找不到此代码;也许它已被转移到其他地方。但这并不重要;同样的原则也适用。设置环境变量的值通常不会影响已经初始化的代码,只能用于影响子进程。

至于解决方案,我没有简单的方法。就我个人而言,我会尝试找到一些方法来禁止登录有问题的特定库,或者过滤掉消息:在最坏的情况下,我会使用由我控制的消息进行几次自己的 NSLog 调用在调用库之前和之后,并告诉过滤器忽略两者之间的所有内容。

,

当您将 OS_ACTIVITY_MODE 设置为 disable 时,您会禁用有权访问此环境变量的进程(例如模拟器)的所有日志输出。

当您将该值设置为 infodebug 时,它会启用相应的日志记录模式,除非在某些日志类别的日志记录首选项中禁用

因此,为了仅启用某个日志类别,您必须启用 OS_ACTIVITY_MODE,即,将其设置为 infodebug 或将其保留在默认,然后禁用所有其他类别的日志记录。

有关如何执行此操作的详细信息,请参阅日志的手册页,在控制台中键入 man log

获取模拟器的当前日志首选项:

在控制台输入: xcrun simctl spawn booted log config --status

这基本上意味着:将 log config -status 应用于所有启动的模拟器。

这可能会在您的控制台上打印以下内容:

System mode = INFO STREAM_LIVE PRIVATE_DATA

获取某个类别和子系统的状态

xcrun simctl spawn booted log config --status --subsystem com.mycompany.myapp --category network

这可能会将以下内容打印到控制台:

Mode for 'com.mycompany.myapp(network)'  INFO PERSIST_DEFAULT

获取帮助

如需帮助,工具 xcrun simctllog 有漂亮的手册页和帮助页。

例如: 在控制台中输入 log config --help,它会打印:

usage: log config [options] --mode <modes>
   or: log config [options] --status
   or: log config [options] --reset

description:
    Read or configure settings for the logging system. Configuration
    can act system-wide; or on a subsystem,category,or process level.

options:
    --category <name>             Get/set settings for a given category
    --mode <modes>                Enable given modes
    --process <pid> | <name>      Get/set settings for a given process
    --reset                       Reset settings to defaults
    --status                      Show current settings
    --subsystem <name>            Get/set settings for a given subsystem

modes:
    Modes can be specified as a comma-separated list of key:value pairs.
    Valid keys and their values are:

    level                         off | default | info | debug
    persist                       off | default | info | debug
    stream                        live | default

为特定子系统和类别设置日志级别

xcrun simctl spawn booted log config --mode "level:debug" --subsystem com.mycompany.myapp --category network

再次获取此系统系统的状态并打印类别:

Mode for 'com.mycompany.myapp(network)'  DEBUG PERSIST_DEFAULT