前言

三位学弟实现前台编写后,须要进行集成测试,然而这个时候我却因为无奈实现日志零碎犯了难。最初本人查来查去发现潘老师居然有这个博客,由此是让本人大略了解了这个实现过程。

日志零碎形容

咱们心愿在以后零碎在产生warning或者error后,咱们可能及时的获取到错误信息,以便进行及时无效的解决。 日志零碎应运而生,他的次要性能是记录每个零碎产生指定level的状况。

我的尝试过程

首先去查:如何获取日志,抉择下图圈中的(第一个是广告,能够认为他就是第一个)。

理解log4j2

Log4jApache的一个开源我的项目,通过应用Log4j,咱们能够管制日志信息输送的目的地是控制台文件GUI组件,甚至是套接口服务器、NT的事件记录器、UNIX Syslog守护过程等;咱们也能够管制每一条日志的输入格局;通过定义每一条日志信息的级别,咱们可能更加粗疏地管制日志的生成过程。最令人感兴趣的就是,这些能够通过一个配置文件来灵便地进行配置,而不须要批改利用的代码。log4j2则是log4j的升级版。

log4j2应用:增加依赖

<dependency>    <groupId>org.apache.logging.log4j</groupId>    <artifactId>log4j-core</artifactId>    <version>2.7</version></dependency><dependency>    <groupId>org.apache.logging.log4j</groupId>    <artifactId>log4j-core</artifactId>    <version>2.7</version>    <type>test-jar</type>    <scope>test</scope></dependency>


而后我就:

ERROR in ch.qos.logback.core.joran.spi.Interpreter@3:16 - no applicable action for [Appenders], current ElementPath  is [[Configuration][Appenders]]ERROR in ch.qos.logback.core.joran.spi.Interpreter@4:61 - no applicable action for [Console], current ElementPath  is [[Configuration][Appenders][Console]]ERROR in ch.qos.logback.core.joran.spi.Interpreter@6:80 - no applicable action for [PatternLayout], current ElementPath  is [[Configuration][Appenders][Console][PatternLayout]]ERROR in ch.qos.logback.core.joran.spi.Interpreter@9:14 - no applicable action for [Loggers], current ElementPath  is [[Configuration][Loggers]]ERROR in ch.qos.logback.core.joran.spi.Interpreter@10:29 - no applicable action for [Root], current ElementPath  is [[Configuration][Loggers][Root]]ERROR in ch.qos.logback.core.joran.spi.Interpreter@11:49 - no applicable action for [AppenderRef], current ElementPath  is [[Configuration][Loggers][Root][AppenderRef]]

查了之后发现说须要把Springboot内置的lockBack删了,删了之后又来了其余的问题:JsonView的依赖也被删了。

目前来看这条路我就走死了。如果有同样问题能够参考:Logback configuration error detected的终极解决方案

我的项目日志零碎实现

具体代码实现和测试能够参考文章:spring-boot下应用LogBack,应用HTTP协定将日志推送到日志服务器

1.增加依赖:

第一个依赖是

        <!--http log-->        <dependency>            <groupId>org.logback-extensions</groupId>            <artifactId>logback-ext-loggly</artifactId>            <version>0.1.5</version>        </dependency>        <!--log to json-->        <dependency>            <groupId>ch.qos.logback.contrib</groupId>            <artifactId>logback-jackson</artifactId>            <version>0.1.5</version>        </dependency>        <!--log to json-->        <dependency>            <groupId>ch.qos.logback.contrib</groupId>            <artifactId>logback-json-classic</artifactId>            <version>0.1.5</version>        </dependency>

配置lockback:新建lockback.xml

<?xml version="1.0" encoding="UTF-8"?><!--启用debug模式后,将在`spring-boot 大LOG`上方打印中logBack的配置信息--><configuration debug="true">    <!--蕴含配置文件 org/springframework/boot/logging/logback/defaults.xml-->    <include resource="org/springframework/boot/logging/logback/defaults.xml" />    <!--引入第三方appender, 起名为http-->    <appender name="HTTP" class="ch.qos.logback.ext.loggly.LogglyAppender">        <!--申请的地址-->        <endpointUrl>http://localhost:8081/log</endpointUrl>    </appender>    <!--定义日志等级-->    <root level="WARNING">        <!--启用第三个appender为HTTP-->        <appender-ref ref="HTTP" />    </root></configuration>

咱们看一下LogglyAppender内容:

  /**   * 事件传入   */  protected void append(E var1) {    String var2 = this.layout.doLayout(var1);        // 调用办法向loggly传输的办法    this.postToLoggly(var2);  }  private void postToLoggly(String var1) {    try {      assert this.endpointUrl != null;      // endpointUrl为xml配置文件的传入属性值      URL var2 = new URL(this.endpointUrl);      HttpURLConnection var3;      if (this.proxy == null) {        // 与日志零碎连贯,例localhost:8005/api/batchSave        var3 = (HttpURLConnection)var2.openConnection();      } else {        var3 = (HttpURLConnection)var2.openConnection(this.proxy);      }      var3.setRequestMethod("POST");      var3.setDoOutput(true);      var3.addRequestProperty("Content-Type", this.layout.getContentType());      var3.connect();      this.sendAndClose(var1, var3.getOutputStream());      var3.disconnect();      int var4 = var3.getResponseCode();      if (var4 != 200) {        String var5 = this.readResponseBody(var3.getInputStream());        this.addError("Loggly post failed (HTTP " + var4 + ").  Response body:\n" + var5);      }    } catch (IOException var6) {      this.addError("IOException while attempting to communicate with Loggly", var6);    }

每条日志都会发送一次,这无疑给零碎减少了很大的难度,接下来改成本人的logglyAppender,进而实现多少条或者多久发送一次。

private void postToLoggly(final String event) {        events.add(event);        Calendar calendar = Calendar.getInstance();        // 日志条数够100条或者间隔上次发送够6分钟,则发送到日志零碎批量保留        if (events.size() >= 100 || (calendar.getTimeInMillis() - lastSendTime.getTimeInMillis() >= 6000)) {            try {                lastSendTime = calendar;                List<String> sendEvents = events;                events = new ArrayList<>();                assert this.endpointUrl != null;                URL endpoint = new URL(this.endpointUrl);                final HttpURLConnection connection;                if (this.proxy == null) {                    connection = (HttpURLConnection) endpoint.openConnection();                } else {                    connection = (HttpURLConnection) endpoint.openConnection(this.proxy);                }                connection.setRequestMethod("POST");                connection.setDoOutput(true);                connection.addRequestProperty("Content-Type", this.layout.getContentType());                connection.connect();                this.sendAndClose(sendEvents, connection.getOutputStream());                connection.disconnect();                final int responseCode = connection.getResponseCode();                if (responseCode != 200) {                    final String message = this.readResponseBody(connection.getInputStream());                    this.addError("Loggly post failed (HTTP " + responseCode + ").  Response body:\n" + message);                }            } catch (final IOException e) {                this.addError("IOException while attempting to communicate with Loggly", e);            }        }    }

有个疑难:他为啥有时候过5分钟主动申请,有时又没反馈:

总结

教训比拟不足,在找团队我的项目应用的库始终没找到,本人找的也不会用,还是须要一直的积攒教训。最初也是感激团队,因为有了团队的资源能力让本人看的更远。