在 OSX 10.8 中,到 stdout 和 stderr 的输出不再在 Console.app 中结束。我想在不使用 NSLog 的情况下在 Console.app 中获取输出,因为我需要支持使用基本打印语句打印调试信息的代码(有关一些背景信息,请参阅 https://bitbucket.org/ronaldoussoren/py2app/issue/77)。
NSLog 输出“以某种方式”最终出现在 ASL(Apple 系统日志)日志中,因为您可以使用“syslog -C”查看这些日志行。这就是为什么我尝试将此代码添加到我的应用程序中的原因:
aslclient c = asl_open("py2app", "com.apple.console", ASL_OPT_NO_DELAY);
int fd = dup(2);
asl_set_filter(c, ASL_FILTER_MASK_UPTO(ASL_LEVEL_DEBUG));
asl_add_log_file(c, fd);
asl_log(c, NULL, ASL_LEVEL_INFO, "Hello world from py2app launcher");
asl_log_descriptor(c, NULL, ASL_LEVEL_INFO, 1, ASL_LOG_DESCRIPTOR_WRITE);
asl_log_descriptor(c, NULL, ASL_LEVEL_INFO, 2, ASL_LOG_DESCRIPTOR_WRITE);
这有点管用:当我向 stdout 流写入行时,这些行会被 ASL 转换:输出现在以通常的日志记录前缀为前缀:
Nov 20 13:46:14 Gondolin.local py2app[43722] <Info>: Hello world from py2app launcher
虽然日志文件最终不会出现在 ASL 数据存储区或 Console.app 中。
有人知道我做错了什么吗?
最佳答案
以下 C 代码似乎可以执行我想要的操作:
#include <asl.h>
#include <unistd.h>
#include <stdio.h>
static void
setup_logging(void)
{
aslmsg msg;
aslclient c = asl_open("py2app", "com.apple.console", 0);
msg = asl_new(ASL_TYPE_MSG);
asl_set(msg, ASL_KEY_FACILITY, "com.apple.console");
asl_set(msg, ASL_KEY_LEVEL, ASL_STRING_NOTICE);
asl_set(msg, ASL_KEY_READ_UID, "-1");
int fd = dup(2);
//asl_set_filter(c, ASL_FILTER_MASK_UPTO(ASL_LEVEL_DEBUG));
asl_add_log_file(c, fd);
asl_log(c, NULL, ASL_LEVEL_INFO, "Hello world from py2app launcher");
asl_log_descriptor(c, msg, ASL_LEVEL_INFO, 1, ASL_LOG_DESCRIPTOR_WRITE);
asl_log_descriptor(c, msg, ASL_LEVEL_INFO, 2, ASL_LOG_DESCRIPTOR_WRITE);
}
int main(void)
{
setup_logging();
printf("hello world, this is a printf\n");
}
与我的第一次尝试相比,这包含一个单一的变化:它使用 asl_log_descriptor 的“aslmsg”参数明确设置 ASL Facility、Level 和 ReadUID。如果没有这些参数,消息将不会在 Console.app 中结束。尤其需要 ReadUID 才能在没有 super 用户权限的情况下读取日志条目。
注意:为了方便测试,您可以使用“syslog -C | tail”来读取控制台日志。如果没有 ReadUID,我的程序输出只有在我使用“sudo syslog -C”时才可见。
关于c - 使用 ASL 登录到 console.app,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13473864/