1 /* 2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 package org.webrtc; 12 13 import java.io.PrintWriter; 14 import java.io.StringWriter; 15 import java.util.EnumSet; 16 import java.util.logging.Logger; 17 import java.util.logging.Level; 18 19 /** Java wrapper for WebRTC logging. */ 20 public class Logging { 21 private static final Logger fallbackLogger = Logger.getLogger("org.webrtc.Logging"); 22 private static volatile boolean tracingEnabled; 23 private static volatile boolean nativeLibLoaded; 24 25 static { 26 try { 27 System.loadLibrary("jingle_peerconnection_so"); 28 nativeLibLoaded = true; 29 } catch (UnsatisfiedLinkError t) { 30 // If native logging is unavailable, log to system log. 31 fallbackLogger.setLevel(Level.ALL); 32 33 fallbackLogger.log(Level.WARNING, "Failed to load jingle_peerconnection_so: ", t); 34 } 35 } 36 37 // Keep in sync with webrtc/common_types.h:TraceLevel. 38 public enum TraceLevel { 39 TRACE_NONE(0x0000), 40 TRACE_STATEINFO(0x0001), 41 TRACE_WARNING(0x0002), 42 TRACE_ERROR(0x0004), 43 TRACE_CRITICAL(0x0008), 44 TRACE_APICALL(0x0010), 45 TRACE_DEFAULT(0x00ff), 46 TRACE_MODULECALL(0x0020), 47 TRACE_MEMORY(0x0100), 48 TRACE_TIMER(0x0200), 49 TRACE_STREAM(0x0400), 50 TRACE_DEBUG(0x0800), 51 TRACE_INFO(0x1000), 52 TRACE_TERSEINFO(0x2000), 53 TRACE_ALL(0xffff); 54 55 public final int level; TraceLevel(int level)56 TraceLevel(int level) { 57 this.level = level; 58 } 59 }; 60 61 // Keep in sync with webrtc/base/logging.h:LoggingSeverity. 62 public enum Severity { 63 LS_SENSITIVE, LS_VERBOSE, LS_INFO, LS_WARNING, LS_ERROR, 64 }; 65 enableLogThreads()66 public static void enableLogThreads() { 67 if (!nativeLibLoaded) { 68 fallbackLogger.log(Level.WARNING, "Cannot enable log thread because native lib not loaded."); 69 return; 70 } 71 nativeEnableLogThreads(); 72 } 73 enableLogTimeStamps()74 public static void enableLogTimeStamps() { 75 if (!nativeLibLoaded) { 76 fallbackLogger.log(Level.WARNING, 77 "Cannot enable log timestamps because native lib not loaded."); 78 return; 79 } 80 nativeEnableLogTimeStamps(); 81 } 82 83 // Enable tracing to |path| of messages of |levels| and |severity|. 84 // On Android, use "logcat:" for |path| to send output there. enableTracing( String path, EnumSet<TraceLevel> levels, Severity severity)85 public static synchronized void enableTracing( 86 String path, EnumSet<TraceLevel> levels, Severity severity) { 87 if (!nativeLibLoaded) { 88 fallbackLogger.log(Level.WARNING, "Cannot enable tracing because native lib not loaded."); 89 return; 90 } 91 92 if (tracingEnabled) { 93 return; 94 } 95 int nativeLevel = 0; 96 for (TraceLevel level : levels) { 97 nativeLevel |= level.level; 98 } 99 nativeEnableTracing(path, nativeLevel, severity.ordinal()); 100 tracingEnabled = true; 101 } 102 log(Severity severity, String tag, String message)103 public static void log(Severity severity, String tag, String message) { 104 if (tracingEnabled) { 105 nativeLog(severity.ordinal(), tag, message); 106 return; 107 } 108 109 // Fallback to system log. 110 Level level; 111 switch (severity) { 112 case LS_ERROR: 113 level = Level.SEVERE; 114 break; 115 case LS_WARNING: 116 level = Level.WARNING; 117 break; 118 case LS_INFO: 119 level = Level.INFO; 120 break; 121 default: 122 level = Level.FINE; 123 break; 124 } 125 fallbackLogger.log(level, tag + ": " + message); 126 } 127 d(String tag, String message)128 public static void d(String tag, String message) { 129 log(Severity.LS_INFO, tag, message); 130 } 131 e(String tag, String message)132 public static void e(String tag, String message) { 133 log(Severity.LS_ERROR, tag, message); 134 } 135 w(String tag, String message)136 public static void w(String tag, String message) { 137 log(Severity.LS_WARNING, tag, message); 138 } 139 e(String tag, String message, Throwable e)140 public static void e(String tag, String message, Throwable e) { 141 log(Severity.LS_ERROR, tag, message); 142 log(Severity.LS_ERROR, tag, e.toString()); 143 log(Severity.LS_ERROR, tag, getStackTraceString(e)); 144 } 145 w(String tag, String message, Throwable e)146 public static void w(String tag, String message, Throwable e) { 147 log(Severity.LS_WARNING, tag, message); 148 log(Severity.LS_WARNING, tag, e.toString()); 149 log(Severity.LS_WARNING, tag, getStackTraceString(e)); 150 } 151 v(String tag, String message)152 public static void v(String tag, String message) { 153 log(Severity.LS_VERBOSE, tag, message); 154 } 155 getStackTraceString(Throwable e)156 private static String getStackTraceString(Throwable e) { 157 if (e == null) { 158 return ""; 159 } 160 161 StringWriter sw = new StringWriter(); 162 PrintWriter pw = new PrintWriter(sw); 163 e.printStackTrace(pw); 164 return sw.toString(); 165 } 166 nativeEnableTracing( String path, int nativeLevels, int nativeSeverity)167 private static native void nativeEnableTracing( 168 String path, int nativeLevels, int nativeSeverity); nativeEnableLogThreads()169 private static native void nativeEnableLogThreads(); nativeEnableLogTimeStamps()170 private static native void nativeEnableLogTimeStamps(); nativeLog(int severity, String tag, String message)171 private static native void nativeLog(int severity, String tag, String message); 172 } 173