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