Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why calling setenv("OS_ACTIVITY_DT_MODE", "disable", 1) does not affect logging?

Overly verbose logs produced by 3rd party libraries can be hidden in Swift by setting OS_ACTIVITY_MODE environmnet variable to disable in your run scheme - as shown on the image below.

That silences all NSLog output from your app. I want to disable it only for certain calls. I tried to set the environment variable like this:

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

And like this

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

The environment is changed as verified by calling print(ProcessInfo.processInfo.environment) but there unlike specifying it in XCode run scheme, the logs are not affected.

Why doesn't it work and how to fix it?

enter image description here

like image 380
Rasto Avatar asked Jan 30 '21 16:01

Rasto


Video Answer


2 Answers

When you set OS_ACTIVITY_MODE to disable, you disable all log outputs for processes that have access to this environment variable, for example the simulators.

When you set the value to either info or debug it enables the corresponding logging mode unless it is disabled in the logging preferences for certain log categories.

So in order to enable only a certain log category, you have to enable OS_ACTIVITY_MODE, that is, set it either to info or debug or leave it at the default, and then disable logging for all other categories.

For more information how to do this see the man page for log, type man log in the console.

Get the current log preferences for simulators:

In the console type: xcrun simctl spawn booted log config --status

That basically means: apply log config -status to all booted simulators.

This may print the following to your console:

System mode = INFO STREAM_LIVE PRIVATE_DATA

Get the status for a certain category and subsystem

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

This may print the below to the console:

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

Get Help

For help, the tools xcrun simctl and log have nifty man pages and help pages.

For example: type log config --help into the console, it prints:

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

Set the log level for a specific subsystem and category

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

Get the status again for this sybsystem and category will print:

Mode for 'com.mycompany.myapp(network)'  DEBUG PERSIST_DEFAULT
like image 90
CouchDeveloper Avatar answered Oct 10 '22 08:10

CouchDeveloper


Because environment variables are usually read only once, when the program starts.

In libdispatch 442.1.4, the OS_ACTIVITY_MODE variable is read in _voucher_init to determine a value of an internal variable; _voucher_init is in turn called in libdispatch_init, which is called only once at program startup. Interestingly, I cannot find this code in later versions of the library; perhaps it has been moved somewhere else. But it doesn’t really matter; the same principle applies. Setting the value of an environment variable will usually have no effect on already-initialised code, and can only be used to influence child processes.

As for solutions, I don’t have an easy one. Personally, I would try finding some method to disable logging in the specific library in question, or to filter the messages out: in the worst case, I’d put a couple of my own NSLog calls with messages controlled by me before and after calls to the library, and tell a filter to ignore everything between the two.

like image 36
user3840170 Avatar answered Oct 10 '22 08:10

user3840170