2012-11-20 17 views
5

在OSX 10.8輸出到stdout和stderr不再以Console.app結尾。我想在不使用NSLog的情況下在Console.app中獲取輸出,因爲我需要支持使用基本打印語句打印調試信息的代碼(有關某些背景信息,請參閱https://bitbucket.org/ronaldoussoren/py2app/issue/77)。使用ASL登錄到console.app

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); 

這個有點工作原理:當我寫行到標準輸出流的那些行得到由ASL轉化:

:輸出現在由通常的日誌前綴前綴
Nov 20 13:46:14 Gondolin.local py2app[43722] <Info>: Hello world from py2app launcher 

儘管如此,日誌文件並不會在ASL數據存儲或Console.app中結束。

有誰知道我在做什麼錯?

回答

2

下面的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設施,水平和使用「aslmsg」參數ReadUID asl_log_descriptor。沒有這些參數,這些消息將不會在Console.app中結束。 ReadUID特別需要能夠讀取日誌條目而不具有超級用戶權限。

注意:要輕鬆測試您可以使用「syslog -C | tail」來讀取控制檯日誌。沒有ReadUID,當我使用「sudo syslog -C」時,我的程序的輸出只是可見的。

1

不需要執行asl_add_log_file(c,dup(2))。

此外,您可以在調用asl_log_descriptor而不是asl_msg中設置日誌級別。請注意,在信息級別,您沒有在系統日誌中看到您的消息的原因是因爲默認情況下會過濾掉以下通知的消息(請參閱/etc/asl.conf)。

實施例:

#include <asl.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 

int main() { 
    asl_log_descriptor(NULL, NULL, ASL_LEVEL_INFO, STDOUT_FILENO, ASL_LOG_DESCRIPTOR_WRITE); 
    asl_log_descriptor(NULL, NULL, ASL_LEVEL_NOTICE, STDERR_FILENO, ASL_LOG_DESCRIPTOR_WRITE); 
    fprintf(stdout, "This is written to stdout which will be at log level info."); 
    fprintf(stderr, "This is written to stderr which will be at log level notice."); 
    return 0; 
}