【问题标题】:Optimize apple system logs优化苹果系统日志
【发布时间】:2013-07-17 14:34:04
【问题描述】:
+ (NSArray *)systemLogDictionariesForAppName:(NSString *)appName {   
  aslmsg q = asl_new(ASL_TYPE_QUERY);
  asl_set_query(q, ASL_KEY_SENDER, [appName cStringUsingEncoding:NSASCIIStringEncoding], ASL_QUERY_OP_EQUAL);
  aslresponse r = asl_search(NULL, q);
  aslmsg m;
  uint32_t i;
  const char *key, *val;
  NSMutableArray *systemLogDictionaries = [NSMutableArray array];

  while (NULL != (m = aslresponse_next(r)))
  {
      NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
      for (i = 0; (NULL != (key = asl_key(m, i))); i++)
      {
          val = asl_get(m, key);
          NSString *stringKey = [NSString stringWithCString:key encoding:NSUTF8StringEncoding];
          NSString *stringVal = [NSString stringWithCString:val encoding:NSUTF8StringEncoding];

          [dictionary setObject:stringVal forKey:stringKey];
      }
      [systemLogDictionaries addObject:dictionary];
  }
  aslresponse_free(r);

  return systemLogDictionaries;
}

以上代码将获取苹果系统日志。问题是,从 Apple 系统日志 (ASL) 中提取所有日志大约需要 8 秒。有什么方法可以优化 asl_set_query 以更快地获取数据或我缺少的任何其他方式。

注意:我们能否创建一个 ASL 查询,该查询需要时间戳,并且我们可以获得更少数量的数据来处理。这将解决我认为的问题。

【问题讨论】:

    标签: ios objective-c macos


    【解决方案1】:

    ASL 支持几种不同的日志记录级别,因此您可以指定更严格的级别。

    例如,您可以添加另一个查询(根据手册页,它们通过逻辑 AND 连接):

        // ...
        asl_set_query(q, ASL_KEY_SENDER, [appName cStringUsingEncoding:NSASCIIStringEncoding], ASL_QUERY_OP_EQUAL);
        // 3 is error messages
        asl_set_query(q, ASL_KEY_LEVEL, "3", ASL_QUERY_OP_LESS_EQUAL | ASL_QUERY_OP_NUMERIC);
    
        //-- Check for time --//
    
        /* A dumped entry with your code looks like:
    
             ASLMessageID = 1825403;
             "CFLog Local Time" = "2013-07-20 08:33:12.943";
             "CFLog Thread" = 951f;
             Facility = "com.apple.Safari";
             GID = 20;
             Host = "XXX.local";
             Level = 4;
             Message = "CFPropertyListCreateFromXMLData(): Old-style plist parser: missing semicolon in dictionary on line 3. Parsing will be abandoned. Break on _CFPropertyListMissingSemicolon to debug.";
             PID = 183;
             ReadUID = 501;
             Sender = Safari;
             Time = 1374305592;
             TimeNanoSec = 943173000;
             UID = 501;
    
        Time is a Unix timestamp, so you can use it in your query with ASL_KEY_TIME and one of these operators: ASL_QUERY_OP_EQUAL, ASL_QUERY_OP_GREATER, ASL_QUERY_OP_GREATER_EQUAL, ASL_QUERY_OP_LESS, ASL_QUERY_OP_LESS_EQUAL, ASL_QUERY_OP_NOT_EQUAL
    
        The code below, generates a unix timestamp for yesterday and dumps all messages that occurred yesterday or later. 
        (Nevermind the dirty/hacky way I generate the timestamp, that was just for testing purposes)
    */
        NSDate *yesterday = [NSDate dateWithTimeIntervalSinceNow: -(60.0f*60.0f*24.0f)];
        NSString *theDate = [NSString stringWithFormat:@"%d", (int)[yesterday timeIntervalSince1970]];
    
        asl_set_query(q, ASL_KEY_TIME, [theDate cStringUsingEncoding:NSASCIIStringEncoding], ASL_QUERY_OP_GREATER_EQUAL | ASL_QUERY_OP_NUMERIC);
        aslresponse r = asl_search(NULL, q);
        //...
    

    有关不同错误级别的更多信息,请查看:http://www.cocoanetics.com/2011/03/accessing-the-ios-system-log/

    请注意,根据您设置的级别和日志消息的级别,进一步过滤可能无效(即,如果实际为您的应用记录的所有消息都处于同一级别)

    进一步说明,与调试级别查询不同,我还没有在任何生产代码中使用时间戳查询,但在测试中它似乎工作得非常好,并且正在做它应该做的事情。

    【讨论】:

    • 我已经看过这篇文章并尝试过,但对我的情况没有多大帮助。不过谢谢你的回答。
    • @AmitVyawahare 我在答案中添加了时间戳查询,让我知道它是否适合您。
    • 它确实有帮助,但没有解决问题。
    • @AmitVyawahare 您能否进一步细化您感兴趣的时间范围,比如最后 30 秒/分钟/小时/12 小时,或者在您的情况下这不可行/可能吗?
    • 信息丰富的答案,谢谢。但是,这适用于 iOS7 吗?在下面的帖子中,用户 Trung 评论了一个似乎相关的问题:“从 IOS 7 开始,这种方法将不再有效。由于安全原因,Apple 删除了对 ASL 的访问。” stackoverflow.com/questions/6144347/… 如果Trung 是正确的,您是否知道另一种(非越狱)方法可以从新应用程序中访问和搜索外国应用程序的日志数据,用于报告?
    猜你喜欢
    • 1970-01-01
    • 2012-09-29
    • 2014-04-30
    • 2013-01-03
    • 1970-01-01
    • 2013-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多