Api在iOS 8上读取设备日志

时间:2015-02-24 00:12:54

标签: ios objective-c ios7 ios8 ios8.1

this app "System Console"(由名为Electric Labs Ltd的公司制作)如何访问iOS 8上的设备日志?

我尝试做同样的事情,但我得到的只是我自己的应用程序的日志消息。 我在Apple System Logging facility的示例后面使用this article "Accessing the iOS System Log"的api。

我知道由于iOS 7+中的沙箱子系统,我的应用只能看到自己的日志消息。但我想知道"系统控制台" app避免这种限制吗?

2 个答案:

答案 0 :(得分:5)

看来你可以阅读" syslog.sock"。我在Github上找到了一个在iOS8下工作的项目:https://github.com/eswick/ondeviceconsole

我创建了以下测试代码(空项目)并运行它以在控制台中查看当前的日志记录信息。它识别启动Mail应用程序,Notes应用程序等。信息需要解析,但这是一个不同的问题。 (警告:下面令人作呕的代码!)用于善,而不是邪恶;)

//
//  ViewController.m
//  LogTest
//
//  Created by Freek Sanders on 26-02-15.

#import "ViewController.h"
#import <asl.h>

#import <sys/socket.h>
#import <sys/un.h>

#import <unistd.h>
#import <fcntl.h>
#import <poll.h>



#define SOCKET_PATH "/var/run/lockdown/syslog.sock"

#define COLOR_RESET         "\e[m"
#define COLOR_NORMAL        "\e[0m"
#define COLOR_DARK          "\e[2m"
#define COLOR_RED           "\e[0;31m"
#define COLOR_DARK_RED      "\e[2;31m"
#define COLOR_GREEN         "\e[0;32m"
#define COLOR_DARK_GREEN    "\e[2;32m"
#define COLOR_YELLOW        "\e[0;33m"
#define COLOR_DARK_YELLOW   "\e[2;33m"
#define COLOR_BLUE          "\e[0;34m"
#define COLOR_DARK_BLUE     "\e[2;34m"
#define COLOR_MAGENTA       "\e[0;35m"
#define COLOR_DARK_MAGENTA  "\e[2;35m"
#define COLOR_CYAN          "\e[0;36m"
#define COLOR_DARK_CYAN     "\e[2;36m"
#define COLOR_WHITE         "\e[0;37m"
#define COLOR_DARK_WHITE    "\e[0;37m"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    int nfd = unix_connect(SOCKET_PATH);

    // write "watch" command to socket to begin receiving messages
    write(nfd, "watch\n", 6);

    struct pollfd pfd[2];
    unsigned char buf[16384];
    int n = fileno(stdin);
    int lfd = fileno(stdout);
    int plen = 16384;

    pfd[0].fd = nfd;
    pfd[0].events = POLLIN;

    while (pfd[0].fd != -1) {

        if ((n = poll(pfd, 1, -1)) < 0) {
            close(nfd);
            perror("polling error");
            exit(1);
        }

        if (pfd[0].revents & POLLIN) {
            if ((n = read(nfd, buf, plen)) < 0)
                perror("read error"), exit(1); /* possibly not an error, just disconnection */
            else if (n == 0) {
                shutdown(nfd, SHUT_RD);
                pfd[0].fd = -1;
                pfd[0].events = 0;
            } else {
                if (atomicio(write_colored, lfd, buf, n) != n)
                    perror("atomicio failure"), exit(1);
            }
        }
    }
}

size_t atomicio(ssize_t (*f) (int, void *, size_t), int fd, void *_s, size_t n)
{
    char *s = _s;
    size_t pos = 0;
    ssize_t res;
    struct pollfd pfd;

    pfd.fd = fd;
    pfd.events = f == read ? POLLIN : POLLOUT;
    while (n > pos) {
        res = (f) (fd, s + pos, n - pos);
        switch (res) {
            case -1:
                if (errno == EINTR)
                    continue;
                if ((errno == EAGAIN) || (errno == ENOBUFS)) {
                    (void)poll(&pfd, 1, -1);
                    continue;
                }
                return 0;
            case 0:
                errno = EPIPE;
                return pos;
            default:
                pos += (size_t)res;
        }
    }
    return (pos);
}

int unix_connect(char* path) {
    struct sockaddr_un sun;
    int s;

    if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
        return (-1);
    (void)fcntl(s, F_SETFD, 1);

    memset(&sun, 0, sizeof(struct sockaddr_un));
    sun.sun_family = AF_UNIX;

    if (strlcpy(sun.sun_path, path, sizeof(sun.sun_path)) >= sizeof(sun.sun_path)) {
        close(s);
        errno = ENAMETOOLONG;
        return (-1);
    }
    if (connect(s, (struct sockaddr *)&sun, SUN_LEN(&sun)) < 0) {
        close(s);
        return (-1);
    }

    return (s);
}

#define LINE_REGEX "(\\w+\\s+\\d+\\s+\\d+:\\d+:\\d+)\\s+(\\S+|)\\s+(\\w+)\\[(\\d+)\\]\\s+\\<(\\w+)\\>:\\s(.*)"

ssize_t write_colored(int fd, void* buffer, size_t len) {

    char *escapedBuffer = malloc(len + 1);
    memcpy(escapedBuffer, buffer, len);
    escapedBuffer[len] = '\0';

    NSString *str = [NSString stringWithUTF8String:escapedBuffer];
    free(escapedBuffer);

    NSError *error = nil;
    NSRegularExpression *regex = [NSRegularExpression
                                  regularExpressionWithPattern:@LINE_REGEX
                                  options:NSRegularExpressionCaseInsensitive
                                  error:&error];

    NSArray *matches = [regex matchesInString:str
                                      options:0
                                        range:NSMakeRange(0, [str length])];

    if ([matches count] == 0)
        return write(fd, buffer, len);

    for (NSTextCheckingResult *match in matches) {

        if ([match numberOfRanges] < 6) {
            write(fd, buffer, len); // if entry doesn't match regex, print uncolored
            continue;
        }

        NSRange dateRange    =  [match rangeAtIndex:1];
        NSRange deviceRange  =  [match rangeAtIndex:2];
        NSRange processRange =  [match rangeAtIndex:3];
        NSRange pidRange     =  [match rangeAtIndex:4];
        NSRange typeRange    =  [match rangeAtIndex:5];
        NSRange logRange     =  [match rangeAtIndex:6];

        NSString *date       =  [str substringWithRange:dateRange];
        NSString *device     =  [str substringWithRange:deviceRange];
        NSString *process    =  [str substringWithRange:processRange];
        NSString *pid        =  [str substringWithRange:pidRange];
        NSString *type       =  [str substringWithRange:typeRange];
        NSString *log        =  [str substringWithRange:
                                 NSMakeRange(logRange.location,
                                             [str length] - logRange.location)];

        log = [log stringByTrimmingCharactersInSet:
               [NSCharacterSet newlineCharacterSet]];

        NSMutableString *build = [NSMutableString new];

        [build appendString:@COLOR_DARK_WHITE];
        [build appendString:date];
        [build appendString:@" "];
        [build appendString:device];
        [build appendString:@" "];

        [build appendString:@COLOR_CYAN];
        [build appendString:process];
        [build appendString:@"["];
        [build appendString:pid];
        [build appendString:@"]"];

        char *typeColor = COLOR_DARK_WHITE;
        char *darkTypeColor = COLOR_DARK_WHITE;

        if ([type isEqualToString:@"Notice"]) {
            typeColor = COLOR_GREEN;
            darkTypeColor = COLOR_DARK_GREEN;
        } else if ([type isEqualToString:@"Warning"]) {
            typeColor = COLOR_YELLOW;
            darkTypeColor = COLOR_DARK_YELLOW;
        } else if ([type isEqualToString:@"Error"]) {
            typeColor = COLOR_RED;
            darkTypeColor = COLOR_DARK_RED;
        } else if ([type isEqualToString:@"Debug"]) {
            typeColor = COLOR_MAGENTA;
            darkTypeColor = COLOR_DARK_MAGENTA;
        }

        [build appendString:@(darkTypeColor)];
        [build appendString:@" <"];
        [build appendString:@(typeColor)];
        [build appendString:type];
        [build appendString:@(darkTypeColor)];
        [build appendString:@">"];
        [build appendString:@COLOR_RESET];
        [build appendString:@": "];
        [build appendString:log];

        printf("%s\n", [build UTF8String]);
    }

    return len;
}

@end

答案 1 :(得分:0)

见下面的代码:

 aslmsg q, m;
 int i;
 const char *key, *val;
 q = asl_new(ASL_TYPE_QUERY);
 aslresponse r = asl_search(NULL, q);
 while (NULL != (m = aslresponse_next(r)))
{
    NSMutableDictionary *tmpDict = [NSMutableDictionary dictionary];
    for (i = 0; (NULL != (key = asl_key(m, i))); i++)
    {
        NSString *keyString = [NSString stringWithUTF8String:(char *)key];
        val = asl_get(m, key);
        NSString *string = val?[NSString stringWithUTF8String:val]:@"";
        [tmpDict setObject:string forKey:keyString];
    }
    NSLog(@"%@", tmpDict);
}
aslresponse_free(r);