Why the Xcode 8 (iOS 10) print [LogMessageLogging]

2020-07-10 08:14发布

问题:

Why does Xcode 8 (iOS 10) print [LogMessageLogging] <private> in the console, when I call the map view?

Can any one give some suggestions?

回答1:

Privacy

The unified logging system considers dynamic strings and complex dynamic objects to be private, and does not collect them automatically. To ensure the privacy of users, it is recommended that log messages consist strictly of static strings and numbers. In situations where it is necessary to capture a dynamic string, you may explicitly declare the string public using the keyword public. For example, %{public}s.

  • Source: https://developer.apple.com/reference/os/1891852-logging
  • WWDC Video: https://developer.apple.com/videos/play/wwdc2016/721/?time=714

Example (ObjC):

os_log_t log = os_log_create("com.example.my-subsystem", "test");

const char *staticString = "I am static string!";
const char *dynamicString = [[NSString stringWithFormat:@"I am %@!", @"dynamic string"]
                             cStringUsingEncoding:NSUTF8StringEncoding];

os_log(log, "Message: %s", staticString);
os_log(log, "Message: %s", dynamicString);
os_log(log, "Message: %{public}s", dynamicString);

// Output
// [test] Message: I am static string!
// [test] Message: <private>
// [test] Message: I am dynamic string!

Example (Swift):

At the moment logging strings seems broken in Swift (https://openradar.appspot.com/radar?id=6068967584038912), so we need manually bridge C functions to Swift:

UPDATE 01. Radar 28599032 is fixes and not applicable for Xcode 10.

// File: os_log_rdar28599032.h
#import <Foundation/Foundation.h>
#import <os/log.h>

void log_private(os_log_t, os_log_type_t, NSString *);
void log_public(os_log_t, os_log_type_t, NSString *);


// File: os_log_rdar28599032.m
#import "os_log_rdar28599032.h"

void log_private(os_log_t log, os_log_type_t type, NSString * message) {
   os_log_with_type(log, type, "%s", [message cStringUsingEncoding:NSUTF8StringEncoding]);
}

void log_public(os_log_t log, os_log_type_t type, NSString * message) {
   os_log_with_type(log, type, "%{public}s", [message cStringUsingEncoding:NSUTF8StringEncoding]);
}


// File: ViewController.swift
import Cocoa
import os.log
import os.activity

class ViewController: NSViewController {

   static let log = OSLog(subsystem: "com.example.my-subsystem", category: "test")
   typealias SelfClass = ViewController

   override func viewDidLoad() {
      super.viewDidLoad()
      log_private(SelfClass.log, .fault, "I am dynamic \("string")!")
      log_public(SelfClass.log, .fault, "I am dynamic \("string")!")
      log_private(SelfClass.log, .fault, #file)
      log_public(SelfClass.log, .fault, #file)
   }

}

// Output
// [test] <private>
// [test] I am dynamic string!
// [test] <private>
// [test] /[REDACTED]/ViewController.swift


回答2:

It's a new feature in MacOS 10.12 (Sierra), a unified logging system that

implements global settings that govern logging behavior and persistence, while at the same time providing fine-grained control during debugging via the log command-line tool and through the use of custom logging configuration profiles.

Basically, you can specify at which level you want to log something through os_log and it should make Console more usable. To turn off the 'private' setting for the project you're working in, type this in the Terminal:

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

More information at Customizing Logging Behavior While Debugging

UPDATE:

As @SunilChauhan pointed out, the link above is now broken. Searching for logging and NSLog gets you a lot of results, none relevant. However, searching on the number in the original links brought me to an example project named Logging: Using the os_log APIs which promises to:

demonstrate using the os_log APIs in C, Objective-C, and Swift. They show the difference between a fault and an error, and the circumstances in which they are acceptable. Refer to these samples to see how to use custom log categories, how to decide which log levels to use, and how to view logs in real time.

I don't have time right now to try out this project, I hope it's of use to someone.



回答3:

The per-bundle-id console command shown in the other answer was not working for me.

This worked:

sudo log config --mode "private_data:on"

https://superuser.com/questions/1311578/in-console-app-how-can-i-reveal-to-what-private-tags-are-actually-referring