为什么Xcode在控制台中打印"[LogMessageLogging] <private>"?

7
为什么在调用地图视图时,Xcode 8 (iOS 10) 在控制台中打印 [LogMessageLogging] <private>?有人能给出一些建议吗?
提示信息为 [LogMessageLogging] <private>

我不知道,但我在我的Xcode 8应用程序中也看到了这个问题,我也有一个地图视图,但我正在努力缩小到底是什么导致了它。我担心它可能会指示对私有API的意外使用。 - devios1
3个回答

14

隐私

统一的日志记录系统认为动态字符串和复杂动态对象是私有数据,不会自动收集它们。为确保用户的隐私,建议日志消息严格由静态字符串数字组成。在必须捕获动态字符串的情况下,您可以使用关键字public明确声明该字符串为公共数据。例如,%{public}s


示例(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!

示例(Swift):

目前在 Swift 中记录字符串似乎存在问题(https://openradar.appspot.com/radar?id=6068967584038912),因此我们需要手动将 C 函数桥接到 Swift:

更新01。 Radar 28599032 已修复,不适用于 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
不确定为什么这个答案没有被标记为已接受的答案,但我在Swift上让它工作了。谢谢。在我看来,os_log_rdar28599032这个名称是一个令人困惑的类名,我以为它是关于其他事情的。我会把我的命名为ObjcOSLog... - mfaani

1

这是MacOS 10.12(Sierra)的一个新功能,即统一的日志系统,它

实现全局设置以控制日志行为和持久性,同时通过日志命令行工具和自定义日志配置文件提供细粒度的调试控制。

基本上,您可以通过os_log指定要记录的级别,这应该使Console更易于使用。要关闭您正在工作的项目的“私有”设置,请在终端中输入以下内容:

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

更多信息请参见自定义日志记录行为调试时

更新:

正如@SunilChauhan指出的那样,上面的链接现在已经失效。搜索日志记录和 NSLog 会得到很多结果,但没有一个相关的。然而,用原始链接中的数字搜索将我带到了一个名为Logging:使用 os_log API的示例项目,它承诺:

演示如何在C、Objective-C和Swift中使用os_log API。它们展示了故障和错误之间的区别以及它们可接受的情况。请参考这些示例,了解如何使用自定义日志类别,如何决定使用哪些日志级别以及如何实时查看日志。

我现在没有时间尝试这个项目,希望对某些人有用。


“日志配置”适用于配置、重置或读取日志系统的设置。目前它支持以下模式:级别持久化。但隐私设置由日志格式(%s%{public}s)和所使用字符串的类型(静态动态)来评估。 - Vlad
2
感谢您的投票 @Vlad。然而,您对使用OSLog的曝光并没有解决系统记录异常或错误但不告诉您错误信息的问题,例如:“[General] <private> [Layout] Unable to simultaneously satisfy constraints:<private>”,这正是OP所询问的内容。 - Elise van Looij
1
@ElisevanLooij 谢谢你的回答,但是上面的命令对我没有用。我仍然可以看到带有<private>的NSLayoutConstraints的日志。另外,你提供的链接似乎已经失效了。 - Sunil Chauhan

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接