1 /* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.android.tradefed.log; 17 18 import com.android.tradefed.config.Option; 19 import com.android.tradefed.config.OptionClass; 20 import com.android.tradefed.config.OptionCopier; 21 import com.android.tradefed.result.ByteArrayInputStreamSource; 22 import com.android.tradefed.result.InputStreamSource; 23 import com.android.tradefed.result.SnapshotInputStreamSource; 24 import com.android.tradefed.util.SizeLimitedOutputStream; 25 import com.android.tradefed.util.StreamUtil; 26 27 import com.google.common.annotations.VisibleForTesting; 28 29 import java.io.IOException; 30 import java.io.InputStream; 31 32 /** A {@link ILeveledLogOutput} that directs log messages to a file and to stdout. */ 33 @OptionClass(alias = "file") 34 public class FileLogger extends BaseStreamLogger<SizeLimitedOutputStream> { 35 private static final String TEMP_FILE_PREFIX = "tradefed_log_"; 36 private static final String TEMP_FILE_SUFFIX = ".txt"; 37 38 @Option(name = "max-log-size", description = "maximum allowable size of tmp log data in mB.") 39 private long mMaxLogSizeMbytes = 20; 40 41 @Override init()42 public void init() throws IOException { 43 init(TEMP_FILE_PREFIX, TEMP_FILE_SUFFIX); 44 } 45 46 /** 47 * Alternative to {@link #init()} where we can specify the file name and suffix. 48 * 49 * @param logPrefix the file name where to log without extension. 50 * @param fileSuffix the extension of the file where to log. 51 */ init(String logPrefix, String fileSuffix)52 protected void init(String logPrefix, String fileSuffix) { 53 mOutputStream = 54 new SizeLimitedOutputStream(mMaxLogSizeMbytes * 1024 * 1024, logPrefix, fileSuffix); 55 } 56 57 /** 58 * Creates a new {@link FileLogger} with the same log level settings as the current object. 59 * <p/> 60 * Does not copy underlying log file content (ie the clone's log data will be written to a new 61 * file.) 62 */ 63 @Override clone()64 public ILeveledLogOutput clone() { 65 FileLogger logger = new FileLogger(); 66 OptionCopier.copyOptionsNoThrow(this, logger); 67 return logger; 68 } 69 70 /** Returns the max log size of the log in MBytes. */ getMaxLogSizeMbytes()71 public long getMaxLogSizeMbytes() { 72 return mMaxLogSizeMbytes; 73 } 74 75 @Override getLog()76 public InputStreamSource getLog() { 77 if (mOutputStream != null) { 78 try { 79 // create a InputStream from log file 80 mOutputStream.flush(); 81 return new SnapshotInputStreamSource("FileLogger", mOutputStream.getData()); 82 } catch (IOException e) { 83 System.err.println("Failed to get log"); 84 e.printStackTrace(); 85 } 86 } 87 return new ByteArrayInputStreamSource(new byte[0]); 88 } 89 90 @Override closeLog()91 public void closeLog() { 92 doCloseLog(); 93 } 94 95 /** Flushes stream and closes log file. */ 96 @VisibleForTesting doCloseLog()97 void doCloseLog() { 98 SizeLimitedOutputStream stream = mOutputStream; 99 mOutputStream = null; 100 StreamUtil.flushAndCloseStream(stream); 101 if (stream != null) { 102 stream.delete(); 103 } 104 } 105 106 /** 107 * Dump the contents of the input stream to this log 108 * 109 * @param inputStream input stream to dump 110 * @throws IOException if an I/O error occurs 111 */ dumpToLog(InputStream inputStream)112 void dumpToLog(InputStream inputStream) throws IOException { 113 if (mOutputStream != null) { 114 StreamUtil.copyStreams(inputStream, mOutputStream); 115 } 116 } 117 } 118