2012-11-20 6 views
5

OSX 10.8がstdoutに出力され、stderrがConsole.appで終了しなくなりました。基本的なprint文を使ってデバッグ情報を出力するコードをサポートする必要があるため、NSLogを使わずにConsole.appに出力したいと考えています(バックグラウンド情報についてはhttps://bitbucket.org/ronaldoussoren/py2app/issue/77を参照してください)。ASLを使用してconsole.appにログを記録

NSLog出力は、 "syslog -C"を使用してこれらのログラインを表示できるので、ASL(Apple System Log)ログで「何とか」終了します。私は自分のアプリケーションにこのコードを追加しようとした理由です:

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

が、これは単一の変更が含まれています。それが明示的に「aslmsg」引数を使用してASL施設、レベルとReadUIDを設定し、 asl_log_descriptor。これらの引数がなければ、メッセージはConsole.appで終わることはありません。特にReadUIDは、スーパーユーザー権限を持たずにログエントリを読み取ることができる必要があります。

注:簡単にテストするために、 "syslog -C | tail"を使用してコンソールログを読むことができます。私が "sudo syslog -C"を使ったとき、私のプログラムの出力のみが見えました。

1

asl_add_log_file(c、dup(2))を実行する必要はありません。

また、asl_msgではなく、asl_log_descriptorの呼び出しでログレベルを設定することもできます。情報レベルのときにsyslogにメッセージが表示されなかったのは、通知のないメッセージがデフォルトでフィルタにかけられるからです(/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; 
}