• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

SpringBoot获取项目日志

武飞扬头像
qq_41084438
帮助1

目的

对于布署在远端的服务,我们想快速的获取到日志。对于使用了日志服务,也可能因为上报间隔太长,日志不够实时。

所以想通过一些方式,可以不用进入到容器内也可以简单快速获取到日志,而且是实时的日志。目标就是获取最新的n条日志,搜索啥的功能也不需要,这是ES的功能。

思路

1、想办法获取到项目里的所有日志,然后保存在内存中。

2、读取日志文件里的内容。

思路一

对于思路一有三种方法,要全局的获取日志,只要打日志的入口统一就可以了。获取之后把日志放到一个list或queue中,因为日志会无限增长,所以要限制在内存里日志数量。

方法一:统一对打印日志的类进行封装,实现简单,缺点是需要对现有代码进行改造。

方法二:一般日志框架都使用logback,或者其他的框架,它们会有类似全局入口的地方,这就需要深入了解框架,然后定制化的开发。这种方式不用去改造代码,侵入比较小,缺点是不通用,门槛高。

eg:

学新通

这是我找到的logback能获取项目日志的全局入口,只要在这里收集日志就可以了(二选一)。侵入到了配置文件,感觉用起来也不是很爽,做不到通用。而且在使用这个的时候,发现jpa不是用了logback,对于sql日志就拿不到了。

 方式三:使用AOP去切打印日志的方法。

上面三种实现都绕不开一个问题,日志的储存。需要限制条数,数据的正确性。如果不加锁,最后可能造成日志的丢失,本来查日志就是为了排查问题,结果日志先来捣乱。加了锁对性能有影响,毕竟日志是很底层的东西,使用频率很高,可能会影响整个系统的性能。而且这段逻辑是和业务一起执行的,需要保证它的正确性和稳定性,不然因为查看日志的这个小需求造成业务崩溃,实属得不偿失。

思路二

这种实现方式就不用去管使用了什么日志框架了,只要你给了我日志文件就可以了。但是还是有方式二说的问题,拿不到sql,因为 jpa打印的日志保存不了到文件。这种方式的优点也是缺点,没有日志文件什么都干不了。另外,新功能和原先的业务没有任何关联,就算有问题也不会影响到业务,没有存储、线程安全问题,唯一有点瑕疵的就是,从文件读的数据都是字符串,只能白纸黑字的展示了,前端要渲染成彩色就很难了。

这种实现方式也没什么好讲的,就文件操作,需要注意的点是,不能从前往后去获取日志,要从后往前读,Java提供了这样的IO操作类。

主要代码:

  1.  
    /**
  2.  
    * 使用RandomAccessFile,可以倒着读日志的最后n条日志,而不至于从头遍历到末尾
  3.  
    */
  4.  
    try (RandomAccessFile file = new RandomAccessFile(logStoreMap.get(logStore), "r")) {
  5.  
    final long fileLength = file.length();
  6.  
    long position = fileLength - 1;
  7.  
     
  8.  
    // 把光标定位到文件末尾
  9.  
    file.seek(position);
  10.  
     
  11.  
    final List<String> logList = new ArrayList<>(size);
  12.  
    for (int i = 0; i < size; i) {
  13.  
     
  14.  
    StringBuilder log = new StringBuilder();
  15.  
    while (true) {
  16.  
     
  17.  
    final byte currentByte = file.readByte();
  18.  
    final char currentChar = (char) currentByte;
  19.  
     
  20.  
    log.append(currentChar);
  21.  
    position--;
  22.  
    file.seek(position);
  23.  
     
  24.  
    if (currentChar == '\n') {
  25.  
    break;
  26.  
    }
  27.  
     
  28.  
    if (position < 0) {
  29.  
    break;
  30.  
    }
  31.  
     
  32.  
    }
  33.  
     
  34.  
    // 倒着读 内容需要反转
  35.  
    logList.add(log.reverse().toString());
  36.  
     
  37.  
    if (position < 0) {
  38.  
    break;
  39.  
    }
  40.  
     
  41.  
    }
  42.  
     
  43.  
    // 倒着读 内容需要反转
  44.  
    Collections.reverse(logList);
  45.  
    return logList;
  46.  
     
  47.  
    } catch (FileNotFoundException e) {
  48.  
    return List.of(exAlert, String.format("FileNotFoundException %s %s:", logStore,
  49.  
    logStoreMap.get(logStore)), ThrowableUtil.getStackTrace(e));
  50.  
    } catch (IOException e) {
  51.  
    return List.of(exAlert,
  52.  
    String.format("IOException %s %s", logStore, logStoreMap.get(logStore)),
  53.  
    ThrowableUtil.getStackTrace(e));
  54.  
    } catch (Throwable e) {
  55.  
    return List.of(exAlert, ThrowableUtil.getStackTrace(e));
  56.  
    }
学新通

源码:qq_41084438 / spingboot-log · GitCode

效果

学新通学新通

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhifkfig
系列文章
更多 icon
同类精品
更多 icon
继续加载