You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@skywalking.apache.org by wu...@apache.org on 2018/04/07 14:33:14 UTC

[incubator-skywalking] branch master updated: Feature/1032 (#1045)

This is an automated email from the ASF dual-hosted git repository.

wusheng pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-skywalking.git


The following commit(s) were added to refs/heads/master by this push:
     new c42172f  Feature/1032 (#1045)
c42172f is described below

commit c42172f348b713d9317bd07bcad0cfd53d3e6a72
Author: 彭勇升 pengys <80...@qq.com>
AuthorDate: Sat Apr 7 22:33:10 2018 +0800

    Feature/1032 (#1045)
    
    * 1. Add the performance collection point.
    2. Report formatter.
    
    #1032
    
    * Add a new cache implementation by caffeine.
    
    #1032
    
    * Performance optimization:
    Make all the loggers class variable to have the static modifier.
    
    * Time stamp format to time bucket performance optimization.
    
    #1032
---
 .../ApplicationComponentSpanListener.java          |  6 +++-
 .../mapping/ApplicationMappingSpanListener.java    |  6 +++-
 .../worker/global/GlobalTraceSpanListener.java     |  7 +++-
 .../mapping/InstanceMappingSpanListener.java       |  6 +++-
 .../segment/SegmentDurationSpanListener.java       |  6 +++-
 .../ServiceReferenceMetricSpanListener.java        |  6 +++-
 .../parser/define/decorator/SpanDecorator.java     |  9 +++++
 .../parser/provider/parser/SegmentParse.java       |  6 ++++
 .../apm/collector/core/util/TimeBucketUtils.java   | 38 ++++++++++------------
 .../collector/core/util/TimeBucketUtilsTest.java   | 38 ++++++++++++++++++----
 .../src/test/resources/log4j2.xml                  | 31 ++++++++++++++++++
 11 files changed, 127 insertions(+), 32 deletions(-)

diff --git a/apm-collector/apm-collector-analysis/analysis-metric/metric-provider/src/main/java/org/apache/skywalking/apm/collector/analysis/metric/provider/worker/application/component/ApplicationComponentSpanListener.java b/apm-collector/apm-collector-analysis/analysis-metric/metric-provider/src/main/java/org/apache/skywalking/apm/collector/analysis/metric/provider/worker/application/component/ApplicationComponentSpanListener.java
index d6743d7..6408b6e 100644
--- a/apm-collector/apm-collector-analysis/analysis-metric/metric-provider/src/main/java/org/apache/skywalking/apm/collector/analysis/metric/provider/worker/application/component/ApplicationComponentSpanListener.java
+++ b/apm-collector/apm-collector-analysis/analysis-metric/metric-provider/src/main/java/org/apache/skywalking/apm/collector/analysis/metric/provider/worker/application/component/ApplicationComponentSpanListener.java
@@ -77,7 +77,11 @@ public class ApplicationComponentSpanListener implements EntrySpanListener, Exit
     @Override
     public void parseFirst(SpanDecorator spanDecorator, int applicationId, int instanceId,
         String segmentId) {
-        timeBucket = TimeBucketUtils.INSTANCE.getMinuteTimeBucket(spanDecorator.getStartTime());
+        if (spanDecorator.getStartTimeMinuteTimeBucket() == 0) {
+            long startTimeMinuteTimeBucket = TimeBucketUtils.INSTANCE.getMinuteTimeBucket(spanDecorator.getStartTime());
+            spanDecorator.setStartTimeMinuteTimeBucket(startTimeMinuteTimeBucket);
+        }
+        timeBucket = spanDecorator.getStartTimeMinuteTimeBucket();
     }
 
     @Override public void build() {
diff --git a/apm-collector/apm-collector-analysis/analysis-metric/metric-provider/src/main/java/org/apache/skywalking/apm/collector/analysis/metric/provider/worker/application/mapping/ApplicationMappingSpanListener.java b/apm-collector/apm-collector-analysis/analysis-metric/metric-provider/src/main/java/org/apache/skywalking/apm/collector/analysis/metric/provider/worker/application/mapping/ApplicationMappingSpanListener.java
index 8f51fdb..c0f2e88 100644
--- a/apm-collector/apm-collector-analysis/analysis-metric/metric-provider/src/main/java/org/apache/skywalking/apm/collector/analysis/metric/provider/worker/application/mapping/ApplicationMappingSpanListener.java
+++ b/apm-collector/apm-collector-analysis/analysis-metric/metric-provider/src/main/java/org/apache/skywalking/apm/collector/analysis/metric/provider/worker/application/mapping/ApplicationMappingSpanListener.java
@@ -77,7 +77,11 @@ public class ApplicationMappingSpanListener implements FirstSpanListener, EntryS
     @Override
     public void parseFirst(SpanDecorator spanDecorator, int applicationId, int instanceId,
         String segmentId) {
-        timeBucket = TimeBucketUtils.INSTANCE.getMinuteTimeBucket(spanDecorator.getStartTime());
+        if (spanDecorator.getStartTimeMinuteTimeBucket() == 0) {
+            long startTimeMinuteTimeBucket = TimeBucketUtils.INSTANCE.getMinuteTimeBucket(spanDecorator.getStartTime());
+            spanDecorator.setStartTimeMinuteTimeBucket(startTimeMinuteTimeBucket);
+        }
+        timeBucket = spanDecorator.getStartTimeMinuteTimeBucket();
     }
 
     @Override public void build() {
diff --git a/apm-collector/apm-collector-analysis/analysis-metric/metric-provider/src/main/java/org/apache/skywalking/apm/collector/analysis/metric/provider/worker/global/GlobalTraceSpanListener.java b/apm-collector/apm-collector-analysis/analysis-metric/metric-provider/src/main/java/org/apache/skywalking/apm/collector/analysis/metric/provider/worker/global/GlobalTraceSpanListener.java
index 0bdd414..a13e5e4 100644
--- a/apm-collector/apm-collector-analysis/analysis-metric/metric-provider/src/main/java/org/apache/skywalking/apm/collector/analysis/metric/provider/worker/global/GlobalTraceSpanListener.java
+++ b/apm-collector/apm-collector-analysis/analysis-metric/metric-provider/src/main/java/org/apache/skywalking/apm/collector/analysis/metric/provider/worker/global/GlobalTraceSpanListener.java
@@ -51,8 +51,13 @@ public class GlobalTraceSpanListener implements FirstSpanListener, GlobalTraceId
     @Override
     public void parseFirst(SpanDecorator spanDecorator, int applicationId, int instanceId,
         String segmentId) {
-        this.timeBucket = TimeBucketUtils.INSTANCE.getMinuteTimeBucket(spanDecorator.getStartTime());
         this.segmentId = segmentId;
+        
+        if (spanDecorator.getStartTimeMinuteTimeBucket() == 0) {
+            long startTimeMinuteTimeBucket = TimeBucketUtils.INSTANCE.getMinuteTimeBucket(spanDecorator.getStartTime());
+            spanDecorator.setStartTimeMinuteTimeBucket(startTimeMinuteTimeBucket);
+        }
+        timeBucket = spanDecorator.getStartTimeMinuteTimeBucket();
     }
 
     @Override public void parseGlobalTraceId(UniqueId uniqueId) {
diff --git a/apm-collector/apm-collector-analysis/analysis-metric/metric-provider/src/main/java/org/apache/skywalking/apm/collector/analysis/metric/provider/worker/instance/mapping/InstanceMappingSpanListener.java b/apm-collector/apm-collector-analysis/analysis-metric/metric-provider/src/main/java/org/apache/skywalking/apm/collector/analysis/metric/provider/worker/instance/mapping/InstanceMappingSpanListener.java
index 3308b32..6c75744 100644
--- a/apm-collector/apm-collector-analysis/analysis-metric/metric-provider/src/main/java/org/apache/skywalking/apm/collector/analysis/metric/provider/worker/instance/mapping/InstanceMappingSpanListener.java
+++ b/apm-collector/apm-collector-analysis/analysis-metric/metric-provider/src/main/java/org/apache/skywalking/apm/collector/analysis/metric/provider/worker/instance/mapping/InstanceMappingSpanListener.java
@@ -64,7 +64,11 @@ public class InstanceMappingSpanListener implements FirstSpanListener, EntrySpan
     @Override
     public void parseFirst(SpanDecorator spanDecorator, int applicationId, int instanceId,
         String segmentId) {
-        timeBucket = TimeBucketUtils.INSTANCE.getMinuteTimeBucket(spanDecorator.getStartTime());
+        if (spanDecorator.getStartTimeMinuteTimeBucket() == 0) {
+            long startTimeMinuteTimeBucket = TimeBucketUtils.INSTANCE.getMinuteTimeBucket(spanDecorator.getStartTime());
+            spanDecorator.setStartTimeMinuteTimeBucket(startTimeMinuteTimeBucket);
+        }
+        timeBucket = spanDecorator.getStartTimeMinuteTimeBucket();
     }
 
     @Override public void build() {
diff --git a/apm-collector/apm-collector-analysis/analysis-metric/metric-provider/src/main/java/org/apache/skywalking/apm/collector/analysis/metric/provider/worker/segment/SegmentDurationSpanListener.java b/apm-collector/apm-collector-analysis/analysis-metric/metric-provider/src/main/java/org/apache/skywalking/apm/collector/analysis/metric/provider/worker/segment/SegmentDurationSpanListener.java
index 07082cf..9a7a3a2 100644
--- a/apm-collector/apm-collector-analysis/analysis-metric/metric-provider/src/main/java/org/apache/skywalking/apm/collector/analysis/metric/provider/worker/segment/SegmentDurationSpanListener.java
+++ b/apm-collector/apm-collector-analysis/analysis-metric/metric-provider/src/main/java/org/apache/skywalking/apm/collector/analysis/metric/provider/worker/segment/SegmentDurationSpanListener.java
@@ -60,7 +60,11 @@ public class SegmentDurationSpanListener implements EntrySpanListener, ExitSpanL
     @Override
     public void parseFirst(SpanDecorator spanDecorator, int applicationId, int instanceId,
         String segmentId) {
-        timeBucket = TimeBucketUtils.INSTANCE.getSecondTimeBucket(spanDecorator.getStartTime());
+        if (spanDecorator.getStartTimeMinuteTimeBucket() == 0) {
+            long startTimeMinuteTimeBucket = TimeBucketUtils.INSTANCE.getMinuteTimeBucket(spanDecorator.getStartTime());
+            spanDecorator.setStartTimeMinuteTimeBucket(startTimeMinuteTimeBucket);
+        }
+        timeBucket = spanDecorator.getStartTimeMinuteTimeBucket();
 
         SegmentDuration segmentDuration = new SegmentDuration();
         segmentDuration.setId(segmentId);
diff --git a/apm-collector/apm-collector-analysis/analysis-metric/metric-provider/src/main/java/org/apache/skywalking/apm/collector/analysis/metric/provider/worker/service/refmetric/ServiceReferenceMetricSpanListener.java b/apm-collector/apm-collector-analysis/analysis-metric/metric-provider/src/main/java/org/apache/skywalking/apm/collector/analysis/metric/provider/worker/service/refmetric/ServiceReferenceMetricSpanListener.java
index 650e626..a1e8d7a 100644
--- a/apm-collector/apm-collector-analysis/analysis-metric/metric-provider/src/main/java/org/apache/skywalking/apm/collector/analysis/metric/provider/worker/service/refmetric/ServiceReferenceMetricSpanListener.java
+++ b/apm-collector/apm-collector-analysis/analysis-metric/metric-provider/src/main/java/org/apache/skywalking/apm/collector/analysis/metric/provider/worker/service/refmetric/ServiceReferenceMetricSpanListener.java
@@ -68,7 +68,11 @@ public class ServiceReferenceMetricSpanListener implements FirstSpanListener, En
     @Override
     public void parseFirst(SpanDecorator spanDecorator, int applicationId, int instanceId,
         String segmentId) {
-        this.timeBucket = TimeBucketUtils.INSTANCE.getMinuteTimeBucket(spanDecorator.getStartTime());
+        if (spanDecorator.getStartTimeMinuteTimeBucket() == 0) {
+            long startTimeMinuteTimeBucket = TimeBucketUtils.INSTANCE.getMinuteTimeBucket(spanDecorator.getStartTime());
+            spanDecorator.setStartTimeMinuteTimeBucket(startTimeMinuteTimeBucket);
+        }
+        timeBucket = spanDecorator.getStartTimeMinuteTimeBucket();
     }
 
     @Override
diff --git a/apm-collector/apm-collector-analysis/analysis-segment-parser/segment-parser-define/src/main/java/org/apache/skywalking/apm/collector/analysis/segment/parser/define/decorator/SpanDecorator.java b/apm-collector/apm-collector-analysis/analysis-segment-parser/segment-parser-define/src/main/java/org/apache/skywalking/apm/collector/analysis/segment/parser/define/decorator/SpanDecorator.java
index d8ed791..a504add 100644
--- a/apm-collector/apm-collector-analysis/analysis-segment-parser/segment-parser-define/src/main/java/org/apache/skywalking/apm/collector/analysis/segment/parser/define/decorator/SpanDecorator.java
+++ b/apm-collector/apm-collector-analysis/analysis-segment-parser/segment-parser-define/src/main/java/org/apache/skywalking/apm/collector/analysis/segment/parser/define/decorator/SpanDecorator.java
@@ -31,6 +31,7 @@ public class SpanDecorator implements StandardBuilder {
     private StandardBuilder standardBuilder;
     private SpanObject spanObject;
     private SpanObject.Builder spanBuilder;
+    private long startTimeMinuteTimeBucket = 0;
     private final ReferenceDecorator[] referenceDecorators;
 
     public SpanDecorator(SpanObject spanObject, StandardBuilder standardBuilder) {
@@ -94,6 +95,14 @@ public class SpanDecorator implements StandardBuilder {
         }
     }
 
+    public void setStartTimeMinuteTimeBucket(long startTimeMinuteTimeBucket) {
+        this.startTimeMinuteTimeBucket = startTimeMinuteTimeBucket;
+    }
+
+    public long getStartTimeMinuteTimeBucket() {
+        return startTimeMinuteTimeBucket;
+    }
+
     public long getStartTime() {
         if (isOrigin) {
             return spanObject.getStartTime();
diff --git a/apm-collector/apm-collector-analysis/analysis-segment-parser/segment-parser-provider/src/main/java/org/apache/skywalking/apm/collector/analysis/segment/parser/provider/parser/SegmentParse.java b/apm-collector/apm-collector-analysis/analysis-segment-parser/segment-parser-provider/src/main/java/org/apache/skywalking/apm/collector/analysis/segment/parser/provider/parser/SegmentParse.java
index 5a6736e..516ac89 100644
--- a/apm-collector/apm-collector-analysis/analysis-segment-parser/segment-parser-provider/src/main/java/org/apache/skywalking/apm/collector/analysis/segment/parser/provider/parser/SegmentParse.java
+++ b/apm-collector/apm-collector-analysis/analysis-segment-parser/segment-parser-provider/src/main/java/org/apache/skywalking/apm/collector/analysis/segment/parser/provider/parser/SegmentParse.java
@@ -153,6 +153,7 @@ public class SegmentParse {
             if (spanDecorator.getSpanId() == 0) {
                 notifyFirstListener(spanDecorator, applicationId, applicationInstanceId, segmentId);
                 timeBucket = TimeBucketUtils.INSTANCE.getMinuteTimeBucket(spanDecorator.getStartTime());
+                spanDecorator.setStartTimeMinuteTimeBucket(timeBucket);
             }
 
             if (SpanType.Exit.equals(spanDecorator.getSpanType())) {
@@ -193,6 +194,7 @@ public class SegmentParse {
         spanListeners.forEach(SpanListener::build);
     }
 
+    @GraphComputingMetric(name = "/segment/parse/notifyExitListener")
     private void notifyExitListener(SpanDecorator spanDecorator, int applicationId, int applicationInstanceId,
         String segmentId) {
         for (SpanListener listener : spanListeners) {
@@ -202,6 +204,7 @@ public class SegmentParse {
         }
     }
 
+    @GraphComputingMetric(name = "/segment/parse/notifyEntryListener")
     private void notifyEntryListener(SpanDecorator spanDecorator, int applicationId, int applicationInstanceId,
         String segmentId) {
         for (SpanListener listener : spanListeners) {
@@ -211,6 +214,7 @@ public class SegmentParse {
         }
     }
 
+    @GraphComputingMetric(name = "/segment/parse/notifyLocalListener")
     private void notifyLocalListener(SpanDecorator spanDecorator, int applicationId, int applicationInstanceId,
         String segmentId) {
         for (SpanListener listener : spanListeners) {
@@ -220,6 +224,7 @@ public class SegmentParse {
         }
     }
 
+    @GraphComputingMetric(name = "/segment/parse/notifyFirstListener")
     private void notifyFirstListener(SpanDecorator spanDecorator, int applicationId, int applicationInstanceId,
         String segmentId) {
         for (SpanListener listener : spanListeners) {
@@ -229,6 +234,7 @@ public class SegmentParse {
         }
     }
 
+    @GraphComputingMetric(name = "/segment/parse/notifyGlobalsListener")
     private void notifyGlobalsListener(UniqueId uniqueId) {
         for (SpanListener listener : spanListeners) {
             if (listener instanceof GlobalTraceIdsListener) {
diff --git a/apm-collector/apm-collector-core/src/main/java/org/apache/skywalking/apm/collector/core/util/TimeBucketUtils.java b/apm-collector/apm-collector-core/src/main/java/org/apache/skywalking/apm/collector/core/util/TimeBucketUtils.java
index 3b3d64e..02bf416 100644
--- a/apm-collector/apm-collector-core/src/main/java/org/apache/skywalking/apm/collector/core/util/TimeBucketUtils.java
+++ b/apm-collector/apm-collector-core/src/main/java/org/apache/skywalking/apm/collector/core/util/TimeBucketUtils.java
@@ -22,6 +22,7 @@ import java.text.ParseException;
 import java.text.SimpleDateFormat;
 import java.util.Calendar;
 import java.util.Date;
+import org.apache.skywalking.apm.collector.core.annotations.trace.GraphComputingMetric;
 
 /**
  * @author peng-yongsheng
@@ -29,36 +30,33 @@ import java.util.Date;
 public enum TimeBucketUtils {
     INSTANCE;
 
+    @GraphComputingMetric(name = "/utils/timeBucket/getMinuteTimeBucket")
     public long getMinuteTimeBucket(long time) {
-        SimpleDateFormat minuteDateFormat = new SimpleDateFormat("yyyyMMddHHmm");
         Calendar calendar = Calendar.getInstance();
         calendar.setTimeInMillis(time);
-        String timeStr = minuteDateFormat.format(calendar.getTime());
-        return Long.valueOf(timeStr);
+
+        long year = calendar.get(Calendar.YEAR);
+        long month = calendar.get(Calendar.MONTH) + 1;
+        long day = calendar.get(Calendar.DAY_OF_MONTH);
+        long hour = calendar.get(Calendar.HOUR_OF_DAY);
+        long minute = calendar.get(Calendar.MINUTE);
+
+        return year * 100000000 + month * 1000000 + day * 10000 + hour * 100 + minute;
     }
 
+    @GraphComputingMetric(name = "/utils/timeBucket/getSecondTimeBucket")
     public long getSecondTimeBucket(long time) {
-        SimpleDateFormat secondDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
         Calendar calendar = Calendar.getInstance();
         calendar.setTimeInMillis(time);
-        String timeStr = secondDateFormat.format(calendar.getTime());
-        return Long.valueOf(timeStr);
-    }
 
-    public long getHourTimeBucket(long time) {
-        SimpleDateFormat hourDateFormat = new SimpleDateFormat("yyyyMMddHH");
-        Calendar calendar = Calendar.getInstance();
-        calendar.setTimeInMillis(time);
-        String timeStr = hourDateFormat.format(calendar.getTime()) + "00";
-        return Long.valueOf(timeStr);
-    }
+        long year = calendar.get(Calendar.YEAR);
+        long month = calendar.get(Calendar.MONTH) + 1;
+        long day = calendar.get(Calendar.DAY_OF_MONTH);
+        long hour = calendar.get(Calendar.HOUR_OF_DAY);
+        long minute = calendar.get(Calendar.MINUTE);
+        long second = calendar.get(Calendar.SECOND);
 
-    public long getDayTimeBucket(long time) {
-        SimpleDateFormat dayDateFormat = new SimpleDateFormat("yyyyMMdd");
-        Calendar calendar = Calendar.getInstance();
-        calendar.setTimeInMillis(time);
-        String timeStr = dayDateFormat.format(calendar.getTime()) + "0000";
-        return Long.valueOf(timeStr);
+        return year * 10000000000L + month * 100000000 + day * 1000000 + hour * 10000 + minute * 100 + second;
     }
 
     public String formatMinuteTimeBucket(long minuteTimeBucket) throws ParseException {
diff --git a/apm-collector/apm-collector-core/src/test/java/org/apache/skywalking/apm/collector/core/util/TimeBucketUtilsTest.java b/apm-collector/apm-collector-core/src/test/java/org/apache/skywalking/apm/collector/core/util/TimeBucketUtilsTest.java
index dcc6599..f119e3d 100644
--- a/apm-collector/apm-collector-core/src/test/java/org/apache/skywalking/apm/collector/core/util/TimeBucketUtilsTest.java
+++ b/apm-collector/apm-collector-core/src/test/java/org/apache/skywalking/apm/collector/core/util/TimeBucketUtilsTest.java
@@ -18,15 +18,41 @@
 
 package org.apache.skywalking.apm.collector.core.util;
 
-import java.util.TimeZone;
-import org.junit.Before;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import org.junit.Assert;
+import org.junit.Test;
 
 /**
- * @author wu-sheng
+ * @author peng-yongsheng
  */
 public class TimeBucketUtilsTest {
-    @Before
-    public void setup() {
-        TimeZone.setDefault(TimeZone.getTimeZone("Asia/Shanghai"));
+
+    @Test
+    public void testGetMinuteTimeBucket() throws ParseException {
+        SimpleDateFormat minuteDateFormat = new SimpleDateFormat("yyyyMMddHHmm");
+        long timeBucket = TimeBucketUtils.INSTANCE.getMinuteTimeBucket(minuteDateFormat.parse("201803010201").getTime());
+        Assert.assertEquals(201803010201L, timeBucket);
+    }
+
+    @Test
+    public void testGetSecondTimeBucket() throws ParseException {
+        SimpleDateFormat minuteDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
+        long timeBucket = TimeBucketUtils.INSTANCE.getSecondTimeBucket(minuteDateFormat.parse("20180301020102").getTime());
+        Assert.assertEquals(20180301020102L, timeBucket);
+    }
+
+    /**
+     * Performance tests
+     * Running with vm option: -javaagent: collector-instrument-agent.jar
+     *
+     * @param args
+     */
+    public static void main(String[] args) {
+        long now = System.currentTimeMillis();
+
+        for (int i = 0; i < 500000; i++) {
+            TimeBucketUtils.INSTANCE.getMinuteTimeBucket(now);
+        }
     }
 }
diff --git a/apm-collector/apm-collector-core/src/test/resources/log4j2.xml b/apm-collector/apm-collector-core/src/test/resources/log4j2.xml
new file mode 100644
index 0000000..c9eec4f
--- /dev/null
+++ b/apm-collector/apm-collector-core/src/test/resources/log4j2.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one or more
+  ~ contributor license agreements.  See the NOTICE file distributed with
+  ~ this work for additional information regarding copyright ownership.
+  ~ The ASF licenses this file to You under the Apache License, Version 2.0
+  ~ (the "License"); you may not use this file except in compliance with
+  ~ the License.  You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  ~
+  -->
+
+<Configuration status="info">
+    <Appenders>
+        <Console name="Console" target="SYSTEM_OUT">
+            <PatternLayout charset="UTF-8" pattern="%d - %c -%-4r [%t] %-5p %x - %m%n"/>
+        </Console>
+    </Appenders>
+    <Loggers>
+        <Root level="info">
+            <AppenderRef ref="Console"/>
+        </Root>
+    </Loggers>
+</Configuration>

-- 
To stop receiving notification emails like this one, please contact
wusheng@apache.org.