2012-11-20 18 views
5

W systemie OSX 10.8 wyjście na standardowe wyjście i stderr nie kończy się już w Console.app. Chciałbym uzyskać dane wyjściowe w Console.app bez korzystania z NSLog, ponieważ potrzebuję obsługi kodu, który używa podstawowych instrukcji drukowania do drukowania informacji debugowania (zobacz https://bitbucket.org/ronaldoussoren/py2app/issue/77 dla niektórych informacji w tle).Użyj ASL, aby zalogować się do konsoli.app

Wynik NSLog kończy się logiem ASL (Log System Log) "jakoś", ponieważ możesz przeglądać te logline używając "syslog -C". Dlatego starałem dodanie tego kodu do mojego wniosku:

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

To nieco działa: kiedy piszę wiersze do strumienia stdout te linie się przekształconej przez ASL: wyjście jest teraz poprzedzony zwykłego rejestrowania prefix:

Nov 20 13:46:14 Gondolin.local py2app[43722] <Info>: Hello world from py2app launcher 

Plik logu nie kończy się jednak w magazynie danych ASL ani na pliku Console.app.

Czy ktoś wie, co robię źle?

Odpowiedz

2

Poniższy kod C wydaje się robić to, co chcę:

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

porównaniu z moim pierwszym podejściu zawiera pojedynczą zmianę: to wyraźnie ustanawia instrument npm, poziomu i ReadUID użyciem „aslmsg” argument asl_log_descriptor. Bez tych argumentów wiadomości nie znajdą się w Console.app. ReadUID w szczególności jest potrzebny, aby móc czytać wpisy dziennika bez posiadania uprawnień superużytkownika.

Uwaga: w celu łatwego przetestowania można użyć polecenia "syslog -C | tail", aby odczytać dziennik konsoli. Bez ReadUID tylko moje wyjście programu było widoczne, gdy użyłem "sudo syslog -C".

1

Nie trzeba wykonywać pliku asl_add_log_ (c, dup (2)).

Można także ustawić poziom dziennika w wywołaniu asl_log_descriptor, a nie w asl_msg. Zauważ, że powodem, dla którego nie widzisz wiadomości w dzienniku syslog, gdy na poziomie informacji było, ponieważ wiadomości, które są poniżej powiadomienia, są domyślnie odfiltrowane (zobacz /etc/asl.conf).

przykład:

#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; 
} 
Powiązane problemy