• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 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 java.io.PrintWriter;
19 import java.io.StringWriter;
20 import java.text.SimpleDateFormat;
21 import java.util.Date;
22 import java.util.Locale;
23 
24 /**
25  * Log class that mirrors the API in main Android sources.
26  *
27  * <p>Default behavior outputs the log to {@link System#out}. Use {@link #setLogOutput(ILogOutput)}
28  * to redirect the log somewhere else.
29  */
30 public final class Log {
31 
32     /** Log Level enum. */
33     public enum LogLevel {
34         VERBOSE(2, "verbose", 'V'), // $NON-NLS-1$
35         DEBUG(3, "debug", 'D'), // $NON-NLS-1$
36         INFO(4, "info", 'I'), // $NON-NLS-1$
37         WARN(5, "warn", 'W'), // $NON-NLS-1$
38         ERROR(6, "error", 'E'), // $NON-NLS-1$
39         ASSERT(7, "assert", 'A'); // $NON-NLS-1$
40 
41         private int mPriorityLevel;
42         private String mStringValue;
43         private char mPriorityLetter;
44 
LogLevel(int intPriority, String stringValue, char priorityChar)45         LogLevel(int intPriority, String stringValue, char priorityChar) {
46             mPriorityLevel = intPriority;
47             mStringValue = stringValue;
48             mPriorityLetter = priorityChar;
49         }
50 
getByString(String value)51         public static LogLevel getByString(String value) {
52             for (LogLevel mode : values()) {
53                 if (mode.mStringValue.equals(value)) {
54                     return mode;
55                 }
56             }
57 
58             return null;
59         }
60 
61         /**
62          * Returns the {@link LogLevel} enum matching the specified letter.
63          *
64          * @param letter the letter matching a <code>LogLevel</code> enum
65          * @return a <code>LogLevel</code> object or <code>null</code> if no match were found.
66          */
getByLetter(char letter)67         public static LogLevel getByLetter(char letter) {
68             for (LogLevel mode : values()) {
69                 if (mode.mPriorityLetter == letter) {
70                     return mode;
71                 }
72             }
73 
74             return null;
75         }
76 
77         /**
78          * Returns the {@link LogLevel} enum matching the specified letter.
79          *
80          * <p>The letter is passed as a {@link String} argument, but only the first character is
81          * used.
82          *
83          * @param letter the letter matching a <code>LogLevel</code> enum
84          * @return a <code>LogLevel</code> object or <code>null</code> if no match were found.
85          */
getByLetterString(String letter)86         public static LogLevel getByLetterString(String letter) {
87             if (!letter.isEmpty()) {
88                 return getByLetter(letter.charAt(0));
89             }
90 
91             return null;
92         }
93 
94         /** Returns the letter identifying the priority of the {@link LogLevel}. */
getPriorityLetter()95         public char getPriorityLetter() {
96             return mPriorityLetter;
97         }
98 
99         /** Returns the numerical value of the priority. */
getPriority()100         public int getPriority() {
101             return mPriorityLevel;
102         }
103 
104         /** Returns a non translated string representing the LogLevel. */
getStringValue()105         public String getStringValue() {
106             return mStringValue;
107         }
108 
convertFromDdmlib(com.android.ddmlib.Log.LogLevel level)109         public static LogLevel convertFromDdmlib(com.android.ddmlib.Log.LogLevel level) {
110             switch (level) {
111                 case VERBOSE:
112                     return VERBOSE;
113                 case DEBUG:
114                     return DEBUG;
115                 case INFO:
116                     return INFO;
117                 case WARN:
118                     return WARN;
119                 case ERROR:
120                     return ERROR;
121                 case ASSERT:
122                     return ASSERT;
123                 default:
124                     return VERBOSE;
125             }
126         }
127     }
128 
129     /**
130      * Classes which implement this interface provides methods that deal with outputting log
131      * messages.
132      */
133     public interface ILogOutput {
134         /**
135          * Sent when a log message needs to be printed.
136          *
137          * @param logLevel The {@link LogLevel} enum representing the priority of the message.
138          * @param tag The tag associated with the message.
139          * @param message The message to display.
140          */
printLog(LogLevel logLevel, String tag, String message)141         public void printLog(LogLevel logLevel, String tag, String message);
142 
143         /**
144          * Sent when a log message needs to be printed, and, if possible, displayed to the user in a
145          * dialog box.
146          *
147          * @param logLevel The {@link LogLevel} enum representing the priority of the message.
148          * @param tag The tag associated with the message.
149          * @param message The message to display.
150          */
printAndPromptLog(LogLevel logLevel, String tag, String message)151         public void printAndPromptLog(LogLevel logLevel, String tag, String message);
152     }
153 
154     private static LogLevel sLevel = LogLevel.VERBOSE;
155 
156     private static ILogOutput sLogOutput;
157 
Log()158     private Log() {}
159 
160     /**
161      * Outputs a {@link LogLevel#VERBOSE} level message.
162      *
163      * @param tag The tag associated with the message.
164      * @param message The message to output.
165      */
v(String tag, String message)166     public static void v(String tag, String message) {
167         println(LogLevel.VERBOSE, tag, message);
168     }
169 
170     /**
171      * Outputs a {@link LogLevel#DEBUG} level message.
172      *
173      * @param tag The tag associated with the message.
174      * @param message The message to output.
175      */
d(String tag, String message)176     public static void d(String tag, String message) {
177         println(LogLevel.DEBUG, tag, message);
178     }
179 
180     /**
181      * Outputs a {@link LogLevel#INFO} level message.
182      *
183      * @param tag The tag associated with the message.
184      * @param message The message to output.
185      */
i(String tag, String message)186     public static void i(String tag, String message) {
187         println(LogLevel.INFO, tag, message);
188     }
189 
190     /**
191      * Outputs a {@link LogLevel#WARN} level message.
192      *
193      * @param tag The tag associated with the message.
194      * @param message The message to output.
195      */
w(String tag, String message)196     public static void w(String tag, String message) {
197         println(LogLevel.WARN, tag, message);
198     }
199 
200     /**
201      * Outputs a {@link LogLevel#ERROR} level message.
202      *
203      * @param tag The tag associated with the message.
204      * @param message The message to output.
205      */
e(String tag, String message)206     public static void e(String tag, String message) {
207         println(LogLevel.ERROR, tag, message);
208     }
209 
210     /**
211      * Outputs a log message and attempts to display it in a dialog.
212      *
213      * @param tag The tag associated with the message.
214      * @param message The message to output.
215      */
logAndDisplay(LogLevel logLevel, String tag, String message)216     public static void logAndDisplay(LogLevel logLevel, String tag, String message) {
217         if (sLogOutput != null) {
218             sLogOutput.printAndPromptLog(logLevel, tag, message);
219         } else {
220             println(logLevel, tag, message);
221         }
222     }
223 
224     /**
225      * Outputs a {@link LogLevel#ERROR} level {@link Throwable} information.
226      *
227      * @param tag The tag associated with the message.
228      * @param throwable The {@link Throwable} to output.
229      */
e(String tag, Throwable throwable)230     public static void e(String tag, Throwable throwable) {
231         if (throwable != null) {
232             StringWriter sw = new StringWriter();
233             PrintWriter pw = new PrintWriter(sw);
234 
235             throwable.printStackTrace(pw);
236             println(LogLevel.ERROR, tag, throwable.getMessage() + '\n' + sw.toString());
237         }
238     }
239 
setLevel(LogLevel logLevel)240     static void setLevel(LogLevel logLevel) {
241         sLevel = logLevel;
242     }
243 
244     /**
245      * Sets the {@link ILogOutput} to use to print the logs. If not set, {@link System#out} will be
246      * used.
247      *
248      * @param logOutput The {@link ILogOutput} to use to print the log.
249      */
setLogOutput(ILogOutput logOutput)250     public static void setLogOutput(ILogOutput logOutput) {
251         sLogOutput = logOutput;
252     }
253 
254     /* currently prints to stdout; could write to a log window */
println(LogLevel logLevel, String tag, String message)255     private static void println(LogLevel logLevel, String tag, String message) {
256         if (logLevel.getPriority() >= sLevel.getPriority()) {
257             if (sLogOutput != null) {
258                 sLogOutput.printLog(logLevel, tag, message);
259             } else {
260                 printLog(logLevel, tag, message);
261             }
262         }
263     }
264 
265     /**
266      * Prints a log message.
267      *
268      * @param logLevel
269      * @param tag
270      * @param message
271      */
printLog(LogLevel logLevel, String tag, String message)272     public static void printLog(LogLevel logLevel, String tag, String message) {
273         System.out.print(getLogFormatString(logLevel, tag, message));
274     }
275 
276     /**
277      * Formats a log message.
278      *
279      * @param logLevel
280      * @param tag
281      * @param message
282      */
getLogFormatString(LogLevel logLevel, String tag, String message)283     public static String getLogFormatString(LogLevel logLevel, String tag, String message) {
284         SimpleDateFormat formatter = new SimpleDateFormat("MM-dd HH:mm:ss", Locale.getDefault());
285         return String.format(
286                 "%s %c/%s: %s\n",
287                 formatter.format(new Date()), logLevel.getPriorityLetter(), tag, message);
288     }
289 }
290