1/* 2 * Copyright (C) 2016 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 17package com.android.server.wifi; 18 19import android.annotation.NonNull; 20 21import javax.annotation.CheckReturnValue; 22 23/** 24 * Provides an abstraction of logging back-ends. 25 * 26 * The abstraction is designed to 27 * a) minimize the cost of disabled log messages, 28 * b) allow callers to tag message parameters as containing sensitive 29 * information, 30 * c) avoid the use of format codes, and 31 * d) easily support additional data types. 32 * 33 * Implementations of WifiLog may or may not be thread-safe. 34 * Implementations of LogMessage are expected _not_ to be thread-safe, 35 * as LogMessage instances are not expected to be shared between threads. 36 */ 37public interface WifiLog { 38 char PLACEHOLDER = '%'; 39 40 // New-style API. 41 /** 42 * Allocate an error-level log message, which the caller will fill with 43 * additional parameters according to |format|. After filling the message 44 * with parameters, the caller must call flush(), to actually log the message. 45 * 46 * Error-level messages should be used when a malfunction has occurred, 47 * and the malfunction is likely to cause an externally visible problem. 48 * For example: we failed to initialize the Wifi interface. 49 * 50 * Typical usage is as follows: 51 * WifiDevice() { 52 * mLog = new LogcatLog("ModuleName"); 53 * } 54 * 55 * void start() { 56 * // ... 57 * mLog.err("error % while starting interface %").c(errNum).c(ifaceName).flush(); 58 * } 59 * 60 * void stop() { 61 * // ... 62 * mLog.err("error % while stopping interface %").c(errNum).c(ifaceName).flush(); 63 * } 64 */ 65 @CheckReturnValue 66 @NonNull 67 LogMessage err(@NonNull String format); 68 69 /** 70 * Like {@link #err(String) err()}, except that a warning-level message is 71 * allocated. 72 * 73 * Warning-level messages should be used when a malfunction has occurred, 74 * but the malfunction is _unlikely_ to cause an externally visible problem 75 * on its own. For example: if we fail to start the debugging subsystem. 76 */ 77 @CheckReturnValue 78 @NonNull 79 LogMessage warn(@NonNull String format); 80 81 /** 82 * Like {@link #err(String) err()}, except that a info-level message is 83 * allocated. 84 * 85 * Info-level messages should be used to report progress or status messages 86 * that help understand the program's external behavior. For example: we 87 * might log an info message before initiating a Wifi association. 88 */ 89 @CheckReturnValue 90 @NonNull 91 LogMessage info(@NonNull String format); 92 93 /** 94 * Like {@link #err(String) err()}, except that a trace-level message is 95 * allocated. 96 * 97 * Trace-level messages should be used to report progress or status messages 98 * that help understand the program's internal behavior. For example: 99 * "Reached myCoolMethod()". 100 */ 101 @CheckReturnValue 102 @NonNull 103 LogMessage trace(@NonNull String format); 104 105 /** 106 * Like {@link #err(String) err()}, except that a dump-level message is 107 * allocated. 108 * 109 * Dump-level messages should be used to report detailed internal state. 110 */ 111 @CheckReturnValue 112 @NonNull 113 LogMessage dump(@NonNull String format); 114 115 /** 116 * Log a warning using the default tag for this WifiLog instance. Mark 117 * the message as 'clean' (i.e. _not_ containing any sensitive data). 118 * 119 * NOTE: this method should only be used for literal strings. For messages with 120 * parameters, use err(). 121 * 122 * @param msg the message to be logged 123 */ 124 void eC(String msg); 125 126 /** 127 * Like {@link #eC(String)} eC()}, except that a warning-level message 128 * is logged. 129 */ 130 void wC(String msg); 131 132 /** 133 * Like {@link #eC(String)} eC()}, except that an info-level message 134 * is logged. 135 */ 136 void iC(String msg); 137 138 /** 139 * Like {@link #eC(String)} eC()}, except that a trace-level message 140 * is logged. 141 */ 142 void tC(String msg); 143 144 /** 145 * Note: dC() is deliberately omitted, as "dumping" is inherently at 146 * odds with the intention that the caller pass in a literal string. 147 */ 148 149 /** 150 * Represents a single log message. 151 * 152 * Implementations are expected _not_ to be thread-safe. 153 */ 154 interface LogMessage { 155 /** 156 * Replace the first available placeholder in this LogMessage's format 157 * with the specified value. Mark the value as 'raw', to inform the 158 * logging daemon that the value may contain sensitive data. 159 * 160 * @return |this|, to allow chaining of calls 161 */ 162 @CheckReturnValue 163 @NonNull 164 LogMessage r(String value); 165 166 /** 167 * Like {@link #r(String) r()}, except that the value is marked 168 * as 'clean', to inform the logging daemon that the value does _not_ 169 * contain sensitive data. 170 */ 171 @CheckReturnValue 172 @NonNull 173 LogMessage c(String value); 174 175 /** 176 * Like {@link #c(String) c(String)}, except that the value is a long. 177 */ 178 @CheckReturnValue 179 @NonNull 180 LogMessage c(long value); 181 182 /** 183 * Like {@link #c(String) c(String)}, except that the value is a char. 184 */ 185 @CheckReturnValue 186 @NonNull 187 LogMessage c(char value); 188 189 /** 190 * Like {@link #c(String) c(String)}, except that the value is a boolean. 191 */ 192 @CheckReturnValue 193 @NonNull 194 LogMessage c(boolean value); 195 196 /** 197 * Write this LogMessage to the logging daemon. Writing the 198 * message is best effort. More specifically: 199 * 1) The operation is non-blocking. If we’re unable to write 200 * the log message to the IPC channel, the message is 201 * dropped silently. 202 * 2) If the number of |value|s provided exceeds the number of 203 * placeholders in the |format|, then extraneous |value|s 204 * are silently dropped. 205 * 3) If the number of placeholders in the |format| exceeds 206 * the number of |value|s provided, the message is sent to 207 * the logging daemon without generating an Exception. 208 * 4) If the total message length exceeds the logging 209 * protocol’s maximum message length, the message is 210 * silently truncated. 211 */ 212 void flush(); 213 } 214 215 // Legacy API. 216 /** 217 * Log an error using the default tag for this WifiLog instance. 218 * @param msg the message to be logged 219 * TODO(b/30736737): Remove this method, once all code has migrated to alternatives. 220 */ 221 void e(String msg); 222 223 /** 224 * Log a warning using the default tag for this WifiLog instance. 225 * @param msg the message to be logged 226 * TODO(b/30736737): Remove this method, once all code has migrated to alternatives. 227 */ 228 void w(String msg); 229 230 /** 231 * Log an informational message using the default tag for this WifiLog instance. 232 * @param msg the message to be logged 233 * TODO(b/30736737): Remove this method, once all code has migrated to alternatives. 234 */ 235 void i(String msg); 236 237 /** 238 * Log a debug message using the default tag for this WifiLog instance. 239 * @param msg the message to be logged 240 * TODO(b/30736737): Remove this method, once all code has migrated to alternatives. 241 */ 242 void d(String msg); 243 244 /** 245 * Log a verbose message using the default tag for this WifiLog instance. 246 * @param msg the message to be logged 247 * TODO(b/30736737): Remove this method, once all code has migrated to alternatives. 248 */ 249 void v(String msg); 250} 251