001    /**
002     * Licensed to the Apache Software Foundation (ASF) under one
003     * or more contributor license agreements.  See the NOTICE file
004     * distributed with this work for additional information
005     * regarding copyright ownership.  The ASF licenses this file
006     * to you under the Apache License, Version 2.0 (the
007     * "License"); you may not use this file except in compliance
008     * with the License.  You may obtain a copy of the License at
009     *
010     *     http://www.apache.org/licenses/LICENSE-2.0
011     *
012     * Unless required by applicable law or agreed to in writing, software
013     * distributed under the License is distributed on an "AS IS" BASIS,
014     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015     * See the License for the specific language governing permissions and
016     * limitations under the License.
017     */
018    package org.apache.hadoop.log.metrics;
019    
020    import org.apache.hadoop.classification.InterfaceAudience;
021    import org.apache.hadoop.classification.InterfaceStability;
022    
023    import org.apache.log4j.AppenderSkeleton;
024    import org.apache.log4j.Level;
025    import org.apache.log4j.spi.LoggingEvent;
026    
027    /**
028     * A log4J Appender that simply counts logging events in three levels:
029     * fatal, error and warn. The class name is used in log4j.properties
030     */
031    @InterfaceAudience.Public
032    @InterfaceStability.Stable
033    public class EventCounter extends AppenderSkeleton {
034      private static final int FATAL = 0;
035      private static final int ERROR = 1;
036      private static final int WARN = 2;
037      private static final int INFO = 3;
038    
039      private static class EventCounts {
040        private final long[] counts = {0, 0, 0, 0};
041    
042        private synchronized void incr(int i) {
043          ++counts[i];
044        }
045    
046        private synchronized long get(int i) {
047          return counts[i];
048        }
049      }
050    
051      private static EventCounts counts = new EventCounts();
052    
053      @InterfaceAudience.Private
054      public static long getFatal() {
055        return counts.get(FATAL);
056      }
057    
058      @InterfaceAudience.Private
059      public static long getError() {
060        return counts.get(ERROR);
061      }
062    
063      @InterfaceAudience.Private
064      public static long getWarn() {
065        return counts.get(WARN);
066      }
067    
068      @InterfaceAudience.Private
069      public static long getInfo() {
070        return counts.get(INFO);
071      }
072    
073      @Override
074      public void append(LoggingEvent event) {
075        Level level = event.getLevel();
076        // depends on the api, == might not work
077        // see HADOOP-7055 for details
078        if (level.equals(Level.INFO)) {
079          counts.incr(INFO);
080        }
081        else if (level.equals(Level.WARN)) {
082          counts.incr(WARN);
083        }
084        else if (level.equals(Level.ERROR)) {
085          counts.incr(ERROR);
086        }
087        else if (level.equals(Level.FATAL)) {
088          counts.incr(FATAL);
089        }
090      }
091    
092      @Override
093      public void close() {
094      }
095    
096      @Override
097      public boolean requiresLayout() {
098        return false;
099      }
100    }