2012-11-20 14 views
5

zu loggen. In OSX 10.8 endet die Ausgabe zu stdout und stderr nicht mehr in Console.app. Ich möchte in Console.app ausgegeben werden, ohne NSLog zu verwenden, da ich Code unterstützen muss, der grundlegende print-Anweisungen verwendet, um Debug-Informationen zu drucken (für einige Hintergrundinformationen siehe https://bitbucket.org/ronaldoussoren/py2app/issue/77).Verwenden Sie ASL, um zu console.app

NSLog-Ausgabe endet in der ASL (Apple System Log) Protokoll "irgendwie", wie Sie diese Loglines mit "syslog -C" anzeigen können. Deshalb habe ich versucht, diesen Code zu meiner Anwendung hinzufügen:

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

Diese etwas funktioniert: wenn ich Linien auf den stdout Stream schreibe diese Zeilen durch ASL umgewandelt bekommen: Der Ausgang wird nun durch üblichen Logging Präfix vorangestellt:

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

Die Protokolldatei endet jedoch nicht im ASL-Datenspeicher oder in Console.app.

Weiß jemand, was ich falsch mache?

Antwort

2

Der folgende C-Code erscheint zu tun, was ich will:

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

Im Vergleich zu meinem ersten Versuch, dies eine einzige Änderung enthält: es explizit die ASL der Einrichtung setzt, Ebene und ReadUID unter Verwendung eines „aslmsg“ Argumente asl_log_descriptor. Ohne diese Argumente enden die Nachrichten nicht in Console.app. Insbesondere wird die ReadUID benötigt, um die Protokolleinträge lesen zu können, ohne über Super-User-Privilegien zu verfügen.

Hinweis: Zum einfachen Testen können Sie "syslog -C | tail" verwenden, um das Konsolenprotokoll zu lesen. Ohne ReadUID war die Ausgabe meines Programms nur sichtbar, wenn ich "sudo syslog -C" verwendet habe.

1

Die Datei asl_add_log_file (c, dup (2)) muss nicht ausgeführt werden.

Sie können auch die Protokollstufe im Aufruf von asl_log_descriptor und nicht in asl_msg festlegen. Beachten Sie, dass der Grund dafür, dass Ihre Nachrichten in Syslog auf der Info-Ebene nicht angezeigt wurden, darin liegt, dass Nachrichten unterhalb der Benachrichtigung standardmäßig herausgefiltert werden (siehe /etc/asl.conf).

Beispiel:

#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; 
} 
Verwandte Themen