001/** 002 * 003 * Licensed to the Apache Software Foundation (ASF) under one 004 * or more contributor license agreements. See the NOTICE file 005 * distributed with this work for additional information 006 * regarding copyright ownership. The ASF licenses this file 007 * to you under the Apache License, Version 2.0 (the 008 * "License"); you may not use this file except in compliance 009 * with the License. You may obtain a copy of the License at 010 * 011 * http://www.apache.org/licenses/LICENSE-2.0 012 * 013 * Unless required by applicable law or agreed to in writing, software 014 * distributed under the License is distributed on an "AS IS" BASIS, 015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 016 * See the License for the specific language governing permissions and 017 * limitations under the License. 018 */ 019package org.apache.hadoop.hbase.monitoring; 020 021import java.io.BufferedReader; 022import java.io.File; 023import java.io.FileInputStream; 024import java.io.IOException; 025import java.io.InputStreamReader; 026import java.io.PrintWriter; 027import java.nio.channels.FileChannel; 028import java.util.Enumeration; 029import java.util.Set; 030 031import org.apache.yetus.audience.InterfaceAudience; 032import org.apache.hadoop.io.IOUtils; 033import org.apache.log4j.Appender; 034import org.apache.log4j.FileAppender; 035import org.apache.log4j.Logger; 036 037import org.apache.hbase.thirdparty.com.google.common.collect.Sets; 038 039/** 040 * Utility functions for reading the log4j logs that are 041 * being written by HBase. 042 */ 043@InterfaceAudience.Private 044public abstract class LogMonitoring { 045 public static Set<File> getActiveLogFiles() throws IOException { 046 Set<File> ret = Sets.newHashSet(); 047 Appender a; 048 @SuppressWarnings("unchecked") 049 Enumeration<Appender> e = Logger.getRootLogger().getAllAppenders(); 050 while (e.hasMoreElements()) { 051 a = e.nextElement(); 052 if (a instanceof FileAppender) { 053 FileAppender fa = (FileAppender) a; 054 String filename = fa.getFile(); 055 ret.add(new File(filename)); 056 } 057 } 058 return ret; 059 } 060 061 062 public static void dumpTailOfLogs( 063 PrintWriter out, long tailKb) throws IOException { 064 Set<File> logs = LogMonitoring.getActiveLogFiles(); 065 for (File f : logs) { 066 out.println("+++++++++++++++++++++++++++++++"); 067 out.println(f.getAbsolutePath()); 068 out.println("+++++++++++++++++++++++++++++++"); 069 try { 070 dumpTailOfLog(f, out, tailKb); 071 } catch (IOException ioe) { 072 out.println("Unable to dump log at " + f); 073 ioe.printStackTrace(out); 074 } 075 out.println("\n\n"); 076 } 077 } 078 079 private static void dumpTailOfLog(File f, PrintWriter out, long tailKb) 080 throws IOException { 081 FileInputStream fis = new FileInputStream(f); 082 BufferedReader r = null; 083 try { 084 FileChannel channel = fis.getChannel(); 085 channel.position(Math.max(0, channel.size() - tailKb*1024)); 086 r = new BufferedReader(new InputStreamReader(fis)); 087 r.readLine(); // skip the first partial line 088 String line; 089 while ((line = r.readLine()) != null) { 090 out.println(line); 091 } 092 } finally { 093 if (r != null) IOUtils.closeStream(r); 094 IOUtils.closeStream(fis); 095 } 096 } 097}