1 /* 2 * Copyright (C) 2021 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 17 package com.android.server.utils; 18 19 import android.annotation.Nullable; 20 import android.os.Trace; 21 import android.util.Log; 22 import android.util.Slog; 23 import android.util.TimingsTraceLog; 24 25 import com.android.internal.annotations.GuardedBy; 26 27 import java.util.Formatter; 28 import java.util.Locale; 29 30 /** 31 * Extends {@link Slog} by providing overloaded methods that take string formatting. 32 * 33 * <p><strong>Note: </strong>Like the other logging classes, e.g. {@link Log} and {@link Slog}, the 34 * methods in this class log unconditionally regardless of {@link Log#isLoggable(String, int)}. 35 * Therefore, these methods exist just for the convenience of handling formatting. (Even if they 36 * did check {@link Log#isLoggable(String, int)} before formatting and logging, calling a varargs 37 * method in Java still involves an array allocation.) If you need to avoid the overhead of logging 38 * on a performance-critical path, either don't use logging in that place, or make the logging 39 * conditional on a static boolean defaulting to false. 40 */ 41 public final class Slogf { 42 43 @GuardedBy("sMessageBuilder") 44 private static final StringBuilder sMessageBuilder; 45 46 @GuardedBy("sMessageBuilder") 47 private static final Formatter sFormatter; 48 49 static { 50 TimingsTraceLog t = new TimingsTraceLog("SLog", Trace.TRACE_TAG_SYSTEM_SERVER); 51 t.traceBegin("static_init"); 52 sMessageBuilder = new StringBuilder(); 53 sFormatter = new Formatter(sMessageBuilder, Locale.ENGLISH); t.traceEnd()54 t.traceEnd(); 55 } 56 Slogf()57 private Slogf() { 58 throw new UnsupportedOperationException("provides only static methods"); 59 } 60 61 /** Same as {@link Slog#v(String, String)}. */ v(String tag, String msg)62 public static int v(String tag, String msg) { 63 return Slog.v(tag, msg); 64 } 65 66 /** Same as {@link Slog#v(String, String, Throwable)}. */ v(String tag, String msg, Throwable tr)67 public static int v(String tag, String msg, Throwable tr) { 68 return Slog.v(tag, msg, tr); 69 } 70 71 /** Same as {@link Slog#d(String, String)}. */ d(String tag, String msg)72 public static int d(String tag, String msg) { 73 return Slog.d(tag, msg); 74 } 75 76 /** Same as {@link Slog#d(String, String, Throwable)}. */ d(String tag, String msg, Throwable tr)77 public static int d(String tag, String msg, Throwable tr) { 78 return Slog.d(tag, msg, tr); 79 } 80 81 /** Same as {@link Slog#i(String, String)}. */ i(String tag, String msg)82 public static int i(String tag, String msg) { 83 return Slog.i(tag, msg); 84 } 85 86 /** Same as {@link Slog#i(String, String, Throwable)}. */ i(String tag, String msg, Throwable tr)87 public static int i(String tag, String msg, Throwable tr) { 88 return Slog.i(tag, msg, tr); 89 } 90 91 /** Same as {@link Slog#w(String, String)}. */ w(String tag, String msg)92 public static int w(String tag, String msg) { 93 return Slog.w(tag, msg); 94 } 95 96 /** Same as {@link Slog#w(String, String, Throwable)}. */ w(String tag, String msg, Throwable tr)97 public static int w(String tag, String msg, Throwable tr) { 98 return Slog.w(tag, msg, tr); 99 } 100 101 /** Same as {@link Slog#w(String, String)}. */ w(String tag, Throwable tr)102 public static int w(String tag, Throwable tr) { 103 return Slog.w(tag, tr); 104 } 105 106 /** Same as {@link Slog#e(String, String)}. */ e(String tag, String msg)107 public static int e(String tag, String msg) { 108 return Slog.e(tag, msg); 109 } 110 111 /** Same as {@link Slog#e(String, String, Throwable)}. */ e(String tag, String msg, Throwable tr)112 public static int e(String tag, String msg, Throwable tr) { 113 return Slog.e(tag, msg, tr); 114 } 115 116 /** Same as {@link Slog#wtf(String, String)}. */ wtf(String tag, String msg)117 public static int wtf(String tag, String msg) { 118 return Slog.wtf(tag, msg); 119 } 120 121 /** Same as {@link Slog#wtfQuiet(String, String)}. */ wtfQuiet(String tag, String msg)122 public static void wtfQuiet(String tag, String msg) { 123 Slog.wtfQuiet(tag, msg); 124 } 125 126 /** Same as {@link Slog#wtfStack(String, String). */ wtfStack(String tag, String msg)127 public static int wtfStack(String tag, String msg) { 128 return Slog.wtfStack(tag, msg); 129 } 130 131 /** Same as {@link Slog#wtf(String, Throwable). */ wtf(String tag, Throwable tr)132 public static int wtf(String tag, Throwable tr) { 133 return Slog.wtf(tag, tr); 134 } 135 136 /** Same as {@link Slog#wtf(String, String, Throwable)}. */ wtf(String tag, String msg, Throwable tr)137 public static int wtf(String tag, String msg, Throwable tr) { 138 return Slog.wtf(tag, msg, tr); 139 } 140 141 /** Same as {@link Slog#println(int, String, String)}. */ println(int priority, String tag, String msg)142 public static int println(int priority, String tag, String msg) { 143 return Slog.println(priority, tag, msg); 144 } 145 146 /** Logs a {@link Log.VERBOSE} message. */ v(String tag, String format, @Nullable Object... args)147 public static void v(String tag, String format, @Nullable Object... args) { 148 v(tag, getMessage(format, args)); 149 } 150 151 /** Logs a {@link Log.VERBOSE} message with a throwable. */ v(String tag, Throwable throwable, String format, @Nullable Object... args)152 public static void v(String tag, Throwable throwable, String format, @Nullable Object... args) { 153 v(tag, getMessage(format, args), throwable); 154 } 155 156 /** Logs a {@link Log.DEBUG} message. */ d(String tag, String format, @Nullable Object... args)157 public static void d(String tag, String format, @Nullable Object... args) { 158 d(tag, getMessage(format, args)); 159 } 160 161 /** Logs a {@link Log.DEBUG} message with a throwable. */ d(String tag, Throwable throwable, String format, @Nullable Object... args)162 public static void d(String tag, Throwable throwable, String format, @Nullable Object... args) { 163 d(tag, getMessage(format, args), throwable); 164 } 165 166 /** Logs a {@link Log.INFO} message. */ i(String tag, String format, @Nullable Object... args)167 public static void i(String tag, String format, @Nullable Object... args) { 168 i(tag, getMessage(format, args)); 169 } 170 171 /** Logs a {@link Log.INFO} message with a throwable. */ i(String tag, Throwable throwable, String format, @Nullable Object... args)172 public static void i(String tag, Throwable throwable, String format, @Nullable Object... args) { 173 i(tag, getMessage(format, args), throwable); 174 } 175 176 /** Logs a {@link Log.WARN} message. */ w(String tag, String format, @Nullable Object... args)177 public static void w(String tag, String format, @Nullable Object... args) { 178 w(tag, getMessage(format, args)); 179 } 180 181 /** Logs a {@link Log.WARN} message with a throwable. */ w(String tag, Throwable throwable, String format, @Nullable Object... args)182 public static void w(String tag, Throwable throwable, String format, @Nullable Object... args) { 183 w(tag, getMessage(format, args), throwable); 184 } 185 186 /** Logs a {@link Log.ERROR} message. */ e(String tag, String format, @Nullable Object... args)187 public static void e(String tag, String format, @Nullable Object... args) { 188 e(tag, getMessage(format, args)); 189 } 190 191 /** Logs a {@link Log.ERROR} message with a throwable. */ e(String tag, Throwable throwable, String format, @Nullable Object... args)192 public static void e(String tag, Throwable throwable, String format, @Nullable Object... args) { 193 e(tag, getMessage(format, args), throwable); 194 } 195 196 /** Logs a {@code wtf} message. */ wtf(String tag, String format, @Nullable Object... args)197 public static void wtf(String tag, String format, @Nullable Object... args) { 198 wtf(tag, getMessage(format, args)); 199 } 200 201 /** Logs a {@code wtf} message with a throwable. */ wtf(String tag, Throwable throwable, String format, @Nullable Object... args)202 public static void wtf(String tag, Throwable throwable, String format, 203 @Nullable Object... args) { 204 wtf(tag, getMessage(format, args), throwable); 205 } 206 getMessage(String format, @Nullable Object... args)207 private static String getMessage(String format, @Nullable Object... args) { 208 synchronized (sMessageBuilder) { 209 sFormatter.format(format, args); 210 String message = sMessageBuilder.toString(); 211 sMessageBuilder.setLength(0); 212 return message; 213 } 214 } 215 } 216