| /* | |
| * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. | |
| * | |
| * Use of this source code is governed by a BSD-style license | |
| * that can be found in the LICENSE file in the root of the source | |
| * tree. An additional intellectual property rights grant can be found | |
| * in the file PATENTS. All contributing project authors may | |
| * be found in the AUTHORS file in the root of the source tree. | |
| */ | |
| package org.webrtc; | |
| import androidx.annotation.Nullable; | |
| import java.io.PrintWriter; | |
| import java.io.StringWriter; | |
| import java.util.EnumSet; | |
| import java.util.logging.Level; | |
| import java.util.logging.Logger; | |
| import org.webrtc.Loggable; | |
| /** | |
| * Java wrapper for WebRTC logging. Logging defaults to java.util.logging.Logger, but a custom | |
| * logger implementing the Loggable interface can be injected along with a Severity. All subsequent | |
| * log messages will then be redirected to the injected Loggable, except those with a severity lower | |
| * than the specified severity, which will be discarded. | |
| * | |
| * It is also possible to switch to native logging (rtc::LogMessage) if one of the following static | |
| * functions are called from the app: | |
| * - Logging.enableLogThreads | |
| * - Logging.enableLogTimeStamps | |
| * - Logging.enableLogToDebugOutput | |
| * | |
| * The priority goes: | |
| * 1. Injected loggable | |
| * 2. Native logging | |
| * 3. Fallback logging. | |
| * Only one method will be used at a time. | |
| * | |
| * Injecting a Loggable or using any of the enable... methods requires that the native library is | |
| * loaded, using PeerConnectionFactory.initialize. | |
| */ | |
| public class Logging { | |
| private static final Logger fallbackLogger = createFallbackLogger(); | |
| private static volatile boolean loggingEnabled; | |
| @Nullable private static Loggable loggable; | |
| private static Severity loggableSeverity; | |
| private static Logger createFallbackLogger() { | |
| final Logger fallbackLogger = Logger.getLogger("org.webrtc.Logging"); | |
| fallbackLogger.setLevel(Level.ALL); | |
| return fallbackLogger; | |
| } | |
| static void injectLoggable(Loggable injectedLoggable, Severity severity) { | |
| if (injectedLoggable != null) { | |
| loggable = injectedLoggable; | |
| loggableSeverity = severity; | |
| } | |
| } | |
| static void deleteInjectedLoggable() { | |
| loggable = null; | |
| } | |
| // TODO(solenberg): Remove once dependent projects updated. | |
| @Deprecated | |
| public enum TraceLevel { | |
| TRACE_NONE(0x0000), | |
| TRACE_STATEINFO(0x0001), | |
| TRACE_WARNING(0x0002), | |
| TRACE_ERROR(0x0004), | |
| TRACE_CRITICAL(0x0008), | |
| TRACE_APICALL(0x0010), | |
| TRACE_DEFAULT(0x00ff), | |
| TRACE_MODULECALL(0x0020), | |
| TRACE_MEMORY(0x0100), | |
| TRACE_TIMER(0x0200), | |
| TRACE_STREAM(0x0400), | |
| TRACE_DEBUG(0x0800), | |
| TRACE_INFO(0x1000), | |
| TRACE_TERSEINFO(0x2000), | |
| TRACE_ALL(0xffff); | |
| public final int level; | |
| TraceLevel(int level) { | |
| this.level = level; | |
| } | |
| } | |
| // Keep in sync with webrtc/rtc_base/logging.h:LoggingSeverity. | |
| public enum Severity { LS_VERBOSE, LS_INFO, LS_WARNING, LS_ERROR, LS_NONE } | |
| public static void enableLogThreads() { | |
| nativeEnableLogThreads(); | |
| } | |
| public static void enableLogTimeStamps() { | |
| nativeEnableLogTimeStamps(); | |
| } | |
| // TODO(solenberg): Remove once dependent projects updated. | |
| @Deprecated | |
| public static void enableTracing(String path, EnumSet<TraceLevel> levels) {} | |
| // Enable diagnostic logging for messages of `severity` to the platform debug | |
| // output. On Android, the output will be directed to Logcat. | |
| // Note: this function starts collecting the output of the RTC_LOG() macros. | |
| // TODO(bugs.webrtc.org/8491): Remove NoSynchronizedMethodCheck suppression. | |
| @SuppressWarnings("NoSynchronizedMethodCheck") | |
| public static synchronized void enableLogToDebugOutput(Severity severity) { | |
| if (loggable != null) { | |
| throw new IllegalStateException( | |
| "Logging to native debug output not supported while Loggable is injected. " | |
| + "Delete the Loggable before calling this method."); | |
| } | |
| nativeEnableLogToDebugOutput(severity.ordinal()); | |
| loggingEnabled = true; | |
| } | |
| public static void log(Severity severity, String tag, String message) { | |
| if (tag == null || message == null) { | |
| throw new IllegalArgumentException("Logging tag or message may not be null."); | |
| } | |
| if (loggable != null) { | |
| // Filter log messages below loggableSeverity. | |
| if (severity.ordinal() < loggableSeverity.ordinal()) { | |
| return; | |
| } | |
| loggable.onLogMessage(message, severity, tag); | |
| return; | |
| } | |
| // Try native logging if no loggable is injected. | |
| if (loggingEnabled) { | |
| nativeLog(severity.ordinal(), tag, message); | |
| return; | |
| } | |
| // Fallback to system log. | |
| Level level; | |
| switch (severity) { | |
| case LS_ERROR: | |
| level = Level.SEVERE; | |
| break; | |
| case LS_WARNING: | |
| level = Level.WARNING; | |
| break; | |
| case LS_INFO: | |
| level = Level.INFO; | |
| break; | |
| default: | |
| level = Level.FINE; | |
| break; | |
| } | |
| fallbackLogger.log(level, tag + ": " + message); | |
| } | |
| public static void d(String tag, String message) { | |
| log(Severity.LS_INFO, tag, message); | |
| } | |
| public static void e(String tag, String message) { | |
| log(Severity.LS_ERROR, tag, message); | |
| } | |
| public static void w(String tag, String message) { | |
| log(Severity.LS_WARNING, tag, message); | |
| } | |
| public static void e(String tag, String message, Throwable e) { | |
| log(Severity.LS_ERROR, tag, message); | |
| log(Severity.LS_ERROR, tag, e.toString()); | |
| log(Severity.LS_ERROR, tag, getStackTraceString(e)); | |
| } | |
| public static void w(String tag, String message, Throwable e) { | |
| log(Severity.LS_WARNING, tag, message); | |
| log(Severity.LS_WARNING, tag, e.toString()); | |
| log(Severity.LS_WARNING, tag, getStackTraceString(e)); | |
| } | |
| public static void v(String tag, String message) { | |
| log(Severity.LS_VERBOSE, tag, message); | |
| } | |
| private static String getStackTraceString(Throwable e) { | |
| if (e == null) { | |
| return ""; | |
| } | |
| StringWriter sw = new StringWriter(); | |
| PrintWriter pw = new PrintWriter(sw); | |
| e.printStackTrace(pw); | |
| return sw.toString(); | |
| } | |
| private static native void nativeEnableLogToDebugOutput(int nativeSeverity); | |
| private static native void nativeEnableLogThreads(); | |
| private static native void nativeEnableLogTimeStamps(); | |
| private static native void nativeLog(int severity, String tag, String message); | |
| } |