/**
* 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.
*/
package org.apache.hadoop.hive.ql.exec.tez.monitoring;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.hive.ql.exec.Utilities;
import org.apache.hadoop.hive.ql.session.SessionState;
import org.apache.tez.common.counters.FileSystemCounter;
import org.apache.tez.common.counters.TezCounters;
import org.apache.tez.dag.api.TezException;
import org.apache.tez.dag.api.client.DAGClient;
import org.apache.tez.dag.api.client.Progress;
import org.apache.tez.dag.api.client.StatusGetOpts;
import java.io.IOException;
import java.util.*;
import static org.apache.hadoop.hive.ql.exec.tez.monitoring.Constants.SEPARATOR;
import static org.apache.hadoop.hive.ql.exec.tez.monitoring.TezJobMonitor.getCounterValueByGroupName;
public class FSCountersSummary implements PrintSummary {
private static final String FORMATTING_PATTERN = "%10s %15s %13s %18s %18s %13s";
private static final String HEADER = String.format(FORMATTING_PATTERN,
"VERTICES", "BYTES_READ", "READ_OPS", "LARGE_READ_OPS", "BYTES_WRITTEN", "WRITE_OPS");
private Map<String, Progress> progressMap;
private DAGClient dagClient;
FSCountersSummary(Map<String, Progress> progressMap, DAGClient dagClient) {
this.progressMap = progressMap;
this.dagClient = dagClient;
}
@Override
public void print(SessionState.LogHelper console) {
console.printInfo("FileSystem Counters Summary");
SortedSet<String> keys = new TreeSet<>(progressMap.keySet());
Set<StatusGetOpts> statusOptions = new HashSet<>(1);
statusOptions.add(StatusGetOpts.GET_COUNTERS);
// Assuming FileSystem.getAllStatistics() returns all schemes that are accessed on task side
// as well. If not, we need a way to get all the schemes that are accessed by the tez task/llap.
for (FileSystem.Statistics statistics : FileSystem.getAllStatistics()) {
final String scheme = statistics.getScheme().toUpperCase();
console.printInfo("");
console.printInfo("Scheme: " + scheme);
console.printInfo(SEPARATOR);
console.printInfo(HEADER);
console.printInfo(SEPARATOR);
for (String vertexName : keys) {
TezCounters vertexCounters = vertexCounters(statusOptions, vertexName);
if (vertexCounters != null) {
console.printInfo(summary(scheme, vertexName, vertexCounters));
}
}
console.printInfo(SEPARATOR);
}
}
private String summary(String scheme, String vertexName, TezCounters vertexCounters) {
final String counterGroup = FileSystemCounter.class.getName();
final long bytesRead = getCounterValueByGroupName(vertexCounters,
counterGroup, scheme + "_" + FileSystemCounter.BYTES_READ.name());
final long bytesWritten = getCounterValueByGroupName(vertexCounters,
counterGroup, scheme + "_" + FileSystemCounter.BYTES_WRITTEN.name());
final long readOps = getCounterValueByGroupName(vertexCounters,
counterGroup, scheme + "_" + FileSystemCounter.READ_OPS.name());
final long largeReadOps = getCounterValueByGroupName(vertexCounters,
counterGroup, scheme + "_" + FileSystemCounter.LARGE_READ_OPS.name());
final long writeOps = getCounterValueByGroupName(vertexCounters,
counterGroup, scheme + "_" + FileSystemCounter.WRITE_OPS.name());
return String.format(FORMATTING_PATTERN,
vertexName,
Utilities.humanReadableByteCount(bytesRead),
readOps,
largeReadOps,
Utilities.humanReadableByteCount(bytesWritten),
writeOps);
}
private TezCounters vertexCounters(Set<StatusGetOpts> statusOptions, String vertexName) {
try {
return dagClient.getVertexStatus(vertexName, statusOptions).getVertexCounters();
} catch (IOException | TezException e) {
// best attempt, shouldn't really kill DAG for this
}
return null;
}
}