iOS输出日志到Console.app

有些日志我们希望输出到Mac的Console.app,而非Xcode的控制台

Posted by on January 04, 2021 · 2 mins read

问题

有些时候,我们不希望仅仅将日志输出到Xcode的控制台,而是Mac的Console.app(中文系统也叫控制台,但是独立的控制台App)。例如在非Xcode环境下检查日志,或是因为App Extension(例如开发科学上网常用的Network Extension)。

另外有时我们使用一些Swift以外的语言,例如C/C++等。

我的场景是:在开发Network Extension时,用到了lwIP,是Swift -> Go -> C++的结构,需要在lwIP端输出日志到Console.app。但在网上找了很久都没有很合适的答案。

思路

接下来我们编写一段代码,来测试如下几种类型的日志输出情况:

  • NSLog:使用最多的iOS/Mac日志工具,缺点是仅支持Objective-C/Swift
  • OSLog:Apple希望在iOS 10+之后一统天下的日志库,Objective-C/Swift/C/C++都可支持
  • syslog:FreeBSD支持的系统日志库

验证

第一步,Xcode创建一个App项目:LogApp,语言选Swift其他随意。

第二步,在AppDelegate.swift文件中的启动函数中,输入:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    // Override point for customization after application launch.
    hello();
    NSLog("logtest: NSLog")
    os_log("logtest: os_log")
    ...

第三步,创建一个console.h文件,内容如下:

#ifndef log_h
#define log_h

#include <stdio.h>
#include <syslog.h>
#include <os/log.h>

void hello() {
    printf("logtest: printf\n");
    syslog(LOG_INFO, "logtest: syslog LOG_INFO");
    syslog(LOG_NOTICE, "logtest: syslog LOG_NOTICE");
    os_log_info(OS_LOG_DEFAULT, "logtest: os_log_info in c++");
    os_log_error(OS_LOG_DEFAULT, "logtest: os_log_error in c++");
    os_log_with_type(OS_LOG_DEFAULT, OS_LOG_TYPE_DEFAULT, "logtest: os_log_with_type in c++");
}

#endif /* log_h */

第四步,创建桥接文件LogApp-Bridging-Header.h,内容如下:

#import "console.h"

同时在Build Settings中配置Objective-C Bridging Header的值为LogApp/LogApp-Bridging-Header.h

第五步,运行。

在Xcode控制台中,显示:

logtest: printf
2021-01-04 17:24:22.196717+0800 LogApp[6626:6846463] logtest: syslog LOG_INFO
2021-01-04 17:24:22.196758+0800 LogApp[6626:6846463] logtest: syslog LOG_NOTICE
2021-01-04 17:24:22.196814+0800 LogApp[6626:6846463] logtest: os_log_info in c++
2021-01-04 17:24:22.197344+0800 LogApp[6626:6846463] logtest: os_log_error in c++
2021-01-04 17:24:22.197371+0800 LogApp[6626:6846463] logtest: os_log_with_type in c++
2021-01-04 17:24:22.197675+0800 LogApp[6626:6846463] logtest: NSLog
2021-01-04 17:24:22.197735+0800 LogApp[6626:6846463] logtest: os_log

在Console.app中显示:

默认  17:24:23.023423+0800  LogApp logtest: syslog LOG_NOTICE
错误  17:24:23.023614+0800  LogApp logtest: os_log_error in c++
默认  17:24:23.023643+0800  LogApp logtest: os_log_with_type in c++
默认  17:24:23.023672+0800  LogApp logtest: NSLog
默认  17:24:23.024055+0800  LogApp logtest: os_log

结论如上。