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 */
018package org.apache.hadoop.hdfs;
019
020import org.apache.hadoop.fs.StorageStatistics;
021import org.apache.hadoop.hdfs.protocol.HdfsConstants;
022
023import java.util.EnumMap;
024import java.util.HashMap;
025import java.util.Iterator;
026import java.util.Map;
027import java.util.Map.Entry;
028import java.util.NoSuchElementException;
029import java.util.concurrent.atomic.AtomicLong;
030
031/**
032 * This storage statistics tracks how many times each DFS operation was issued.
033 *
034 * For each tracked DFS operation, there is a respective entry in the enum
035 * {@link OpType}. To use, increment the value the {@link DistributedFileSystem}
036 * and {@link org.apache.hadoop.hdfs.web.WebHdfsFileSystem}.
037 *
038 * This class is thread safe, and is generally shared by multiple threads.
039 */
040public class DFSOpsCountStatistics extends StorageStatistics {
041
042  /** This is for counting distributed file system operations. */
043  public enum OpType {
044    ALLOW_SNAPSHOT("op_allow_snapshot"),
045    APPEND(CommonStatisticNames.OP_APPEND),
046    CONCAT("op_concat"),
047    COPY_FROM_LOCAL_FILE(CommonStatisticNames.OP_COPY_FROM_LOCAL_FILE),
048    CREATE(CommonStatisticNames.OP_CREATE),
049    CREATE_NON_RECURSIVE(CommonStatisticNames.OP_CREATE_NON_RECURSIVE),
050    CREATE_SNAPSHOT("op_create_snapshot"),
051    CREATE_SYM_LINK("op_create_symlink"),
052    DELETE(CommonStatisticNames.OP_DELETE),
053    DELETE_SNAPSHOT("op_delete_snapshot"),
054    DISALLOW_SNAPSHOT("op_disallow_snapshot"),
055    EXISTS(CommonStatisticNames.OP_EXISTS),
056    GET_BYTES_WITH_FUTURE_GS("op_get_bytes_with_future_generation_stamps"),
057    GET_CONTENT_SUMMARY(CommonStatisticNames.OP_GET_CONTENT_SUMMARY),
058    GET_FILE_BLOCK_LOCATIONS("op_get_file_block_locations"),
059    GET_FILE_CHECKSUM(CommonStatisticNames.OP_GET_FILE_CHECKSUM),
060    GET_FILE_LINK_STATUS("op_get_file_link_status"),
061    GET_FILE_STATUS(CommonStatisticNames.OP_GET_FILE_STATUS),
062    GET_LINK_TARGET("op_get_link_target"),
063    GET_QUOTA_USAGE("op_get_quota_usage"),
064    GET_STATUS(CommonStatisticNames.OP_GET_STATUS),
065    GET_STORAGE_POLICIES("op_get_storage_policies"),
066    GET_STORAGE_POLICY("op_get_storage_policy"),
067    GET_XATTR("op_get_xattr"),
068    LIST_LOCATED_STATUS(CommonStatisticNames.OP_LIST_LOCATED_STATUS),
069    LIST_STATUS(CommonStatisticNames.OP_LIST_STATUS),
070    MKDIRS(CommonStatisticNames.OP_MKDIRS),
071    MODIFY_ACL_ENTRIES(CommonStatisticNames.OP_MODIFY_ACL_ENTRIES),
072    OPEN(CommonStatisticNames.OP_OPEN),
073    PRIMITIVE_CREATE("op_primitive_create"),
074    PRIMITIVE_MKDIR("op_primitive_mkdir"),
075    REMOVE_ACL(CommonStatisticNames.OP_REMOVE_ACL),
076    REMOVE_ACL_ENTRIES(CommonStatisticNames.OP_REMOVE_ACL_ENTRIES),
077    REMOVE_DEFAULT_ACL(CommonStatisticNames.OP_REMOVE_DEFAULT_ACL),
078    REMOVE_XATTR("op_remove_xattr"),
079    RENAME(CommonStatisticNames.OP_RENAME),
080    RENAME_SNAPSHOT("op_rename_snapshot"),
081    RESOLVE_LINK("op_resolve_link"),
082    SET_ACL(CommonStatisticNames.OP_SET_ACL),
083    SET_OWNER(CommonStatisticNames.OP_SET_OWNER),
084    SET_PERMISSION(CommonStatisticNames.OP_SET_PERMISSION),
085    SET_REPLICATION("op_set_replication"),
086    SET_STORAGE_POLICY("op_set_storagePolicy"),
087    SET_TIMES(CommonStatisticNames.OP_SET_TIMES),
088    SET_XATTR("op_set_xattr"),
089    TRUNCATE(CommonStatisticNames.OP_TRUNCATE),
090    UNSET_STORAGE_POLICY("op_unset_storage_policy");
091
092    private static final Map<String, OpType> SYMBOL_MAP =
093        new HashMap<>(OpType.values().length);
094    static {
095      for (OpType opType : values()) {
096        SYMBOL_MAP.put(opType.getSymbol(), opType);
097      }
098    }
099
100    private final String symbol;
101
102    OpType(String symbol) {
103      this.symbol = symbol;
104    }
105
106    public String getSymbol() {
107      return symbol;
108    }
109
110    public static OpType fromSymbol(String symbol) {
111      return SYMBOL_MAP.get(symbol);
112    }
113  }
114
115  public static final String NAME = "DFSOpsCountStatistics";
116
117  private final Map<OpType, AtomicLong> opsCount = new EnumMap<>(OpType.class);
118
119  public DFSOpsCountStatistics() {
120    super(NAME);
121    for (OpType opType : OpType.values()) {
122      opsCount.put(opType, new AtomicLong(0));
123    }
124  }
125
126  public void incrementOpCounter(OpType op) {
127    opsCount.get(op).addAndGet(1);
128  }
129
130  private class LongIterator implements Iterator<LongStatistic> {
131    private Iterator<Entry<OpType, AtomicLong>> iterator =
132        opsCount.entrySet().iterator();
133
134    @Override
135    public boolean hasNext() {
136      return iterator.hasNext();
137    }
138
139    @Override
140    public LongStatistic next() {
141      if (!iterator.hasNext()) {
142        throw new NoSuchElementException();
143      }
144      final Entry<OpType, AtomicLong> entry = iterator.next();
145      return new LongStatistic(entry.getKey().getSymbol(),
146          entry.getValue().get());
147    }
148
149    @Override
150    public void remove() {
151      throw new UnsupportedOperationException();
152    }
153  }
154
155  @Override
156  public String getScheme() {
157    return HdfsConstants.HDFS_URI_SCHEME;
158  }
159
160  @Override
161  public Iterator<LongStatistic> getLongStatistics() {
162    return new LongIterator();
163  }
164
165  @Override
166  public Long getLong(String key) {
167    final OpType type = OpType.fromSymbol(key);
168    return type == null ? null : opsCount.get(type).get();
169  }
170
171  @Override
172  public boolean isTracked(String key) {
173    return OpType.fromSymbol(key) != null;
174  }
175
176  @Override
177  public void reset() {
178    for (AtomicLong count : opsCount.values()) {
179      count.set(0);
180    }
181  }
182
183}