1

众所周知,我们可以在 Objective C 中使用 ASL(Apple System Logger)API 来读取日志,并且使用 asl_search 可以检索特定的应用程序日志。但问题是 asl 的输出不包括创建日志的时间。例如,当您使用 Apple System Logger 打开目录 /var/log 中的 system.log 时,您会看到如下日志:

11 月 28 日 09:19:37 本地主机引导日志 [0]:BOOT_TIME 1354123177 0

但是当用objective C查询asl时,它会报告日志的每个属性,除了创建日志的时间,这意味着在上面提到的例子中,asl_search没有报告11月28日09:19:37
无论如何要包括创建日志的时间在目标 C 中查询 asl?如果这是不可能的,那么检索日志时间的另一种方法是什么?


这是我的代码,请注意我们可以在 /var/log 的 system.log 文件中看到的日志时间不会出现在我的代码输出中。

int main (int argc, const char * argv[]) {

NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
aslmsg q, m;
int i;
const char *key, *val;
q = asl_new(ASL_TYPE_QUERY);
asl_set_query(q, ASL_KEY_SENDER, "bootlog", ASL_QUERY_OP_EQUAL);

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 = [NSString stringWithUTF8String:val];
        [tmpDict setObject:string forKey:keyString];
    }

    NSLog(@"%@", tmpDict);

}
aslresponse_free(r);

[pool drain];
return 0;

}

4

2 回答 2

3

日志消息的时间戳是消息中ASL_KEY_TIME键的值。该值是 UNIX 时间(自 1.1.1970 以来的秒数)。

您可以将日志消息的时间戳转换NSDate

NSDate *time = [NSDate dateWithTimeIntervalSince1970:(strtod(asl_get(m, ASL_KEY_TIME), NULL))];
于 2013-01-12T07:15:49.203 回答
0

如果您使用的是 Swift,那么有一个名为CleanroomASL的新开源项目,它提供了一个类型安全的 API,用于读取和写入 Apple 系统日志条目。

查询日志会返回每个条目的时间戳:

let client = ASLClient()
let query = ASLQueryObject()

client.search(query) { record in
    if let record = record {
        // we've gotten a log entry for the search.
        // 'record' is of type ASLQueryObject.ResultRecord;
        // you can access the timestamp as an NSDate
        // using the record.timestamp property
    }
    else {
        // there are no more log entries to process
    }
    // return true while we still want to get results
    // or return false when we don't want to process more
    return true
}

您可以通过设置其他查询键来限制您的搜索查询:

query.setQueryKey(.Message, value: nil, operation: .KeyExists, modifiers: .None)
query.setQueryKey(.Time, value: Int(NSDate().timeIntervalSince1970 - (60 * 60)), operation: .GreaterThanOrEqualTo, modifiers: .None)

上面的代码将返回过去 5 分钟内记录的所有 ASL 日志条目,这些条目也具有该.Message属性的值。

注意:在 iOS 设备上,ASL只会返回您的进程创建的日志条目。此外,日志会被相当积极地修剪,并且可能只包含当前运行应用程序的条目。如果您想在此之外保留日志条目,您可能需要研究更强大的 Swift 日志记录包,例如CleanroomLogger

Mac/iOS 模拟器和 iOS 设备上的 ASL 行为之间的差异在 GitHub 上的 CleanroomASL 项目页面上的设备和模拟器之间的差异部分中进一步解释。

于 2015-05-12T18:11:46.063 回答