From 2b1e4d54f9ae334cec73a851e56375a978ebe251 Mon Sep 17 00:00:00 2001 From: Konstantin Pastbin Date: Tue, 14 Jun 2022 01:08:35 +0300 Subject: [PATCH] [android] Add source point logging - add source point info "file:line method()" to file logging, debug builds and ERRORs - make logcat, core and file logging formats more similar Signed-off-by: Konstantin Pastbin --- android/jni/com/mapswithme/core/logging.cpp | 8 +-- .../src/com/mapswithme/util/log/Logger.java | 63 +++++++++++++------ .../com/mapswithme/util/log/LogsManager.java | 4 +- base/src_point.cpp | 2 +- 4 files changed, 53 insertions(+), 24 deletions(-) diff --git a/android/jni/com/mapswithme/core/logging.cpp b/android/jni/com/mapswithme/core/logging.cpp index fad6d129ed..7a34b839cd 100644 --- a/android/jni/com/mapswithme/core/logging.cpp +++ b/android/jni/com/mapswithme/core/logging.cpp @@ -31,12 +31,12 @@ void AndroidMessage(LogLevel level, SrcPoint const & src, std::string const & s) } ScopedEnv env(jni::GetJVM()); - static jmethodID const logCoreMsgMethod = jni::GetStaticMethodID(env.get(), g_loggerClazz, - "logCoreMessage", "(ILjava/lang/String;)V"); + static jmethodID const logMethod = jni::GetStaticMethodID(env.get(), g_loggerClazz, + "log", "(ILjava/lang/String;Ljava/lang/String;Ljava/lang/Throwable;)V"); - std::string const out = DebugPrint(src) + " " + s; + std::string const out = DebugPrint(src) + s; jni::TScopedLocalRef msg(env.get(), jni::ToJavaString(env.get(), out)); - env->CallStaticVoidMethod(g_loggerClazz, logCoreMsgMethod, pr, msg.get()); + env->CallStaticVoidMethod(g_loggerClazz, logMethod, pr, NULL, msg.get(), NULL); } void AndroidLogMessage(LogLevel level, SrcPoint const & src, std::string const & s) diff --git a/android/src/com/mapswithme/util/log/Logger.java b/android/src/com/mapswithme/util/log/Logger.java index 6430affa58..335061729c 100644 --- a/android/src/com/mapswithme/util/log/Logger.java +++ b/android/src/com/mapswithme/util/log/Logger.java @@ -73,29 +73,56 @@ public final class Logger log(Log.ERROR, tag, msg, tr); } - // Called from JNI to proxy native code logging. - @SuppressWarnings("unused") - @Keep - private static void logCoreMessage(int level, String msg) + // Index of stacktrace depth where the original log method call resides. + private static final int CALL_STACK_INDEX = 3; + + @NonNull + private static String getSourcePoint() { - log(level, CORE_TAG, msg, null); + final StackTraceElement[] stackTrace = new Throwable().getStackTrace(); + assert stackTrace.length > CALL_STACK_INDEX : "Synthetic stacktrace doesn't have enough elements"; + + final StackTraceElement st = stackTrace[CALL_STACK_INDEX]; + StringBuilder sb = new StringBuilder(80); + final String fileName = st.getFileName(); + if (fileName != null) + { + sb.append(fileName); + final int lineNumber = st.getLineNumber(); + if (lineNumber >= 0) + sb.append(':').append(lineNumber); + sb.append(' '); + } + sb.append(st.getMethodName()).append("()"); + return sb.toString(); } - public static void log(int level, @NonNull String tag, @NonNull String msg, @Nullable Throwable tr) + // Also called from JNI to proxy native code logging (with tag == null). + @Keep + private static void log(int level, @Nullable String tag, @NonNull String msg, @Nullable Throwable tr) { final String logsFolder = LogsManager.INSTANCE.getEnabledLogsFolder(); - if (logsFolder != null) + + if (logsFolder != null || BuildConfig.DEBUG || level >= Log.INFO) { - final String data = getLevelChar(level) + "/" + tag + ": " + msg + (tr != null ? '\n' + Log.getStackTraceString(tr) : ""); - LogsManager.EXECUTOR.execute(new WriteTask(logsFolder + File.separator + FILENAME, - data, Thread.currentThread().getName())); - } - else if (BuildConfig.DEBUG || level >= Log.INFO) - { - // Only Debug builds log DEBUG level to Android system log. + final StringBuilder sb = new StringBuilder(180); + // Add source point info for file logging, debug builds and ERRORs if its not from core. + if (tag != null && (logsFolder != null || BuildConfig.DEBUG || level == Log.ERROR)) + sb.append(getSourcePoint()).append(": "); + sb.append(msg); if (tr != null) - msg += '\n' + Log.getStackTraceString(tr); - Log.println(level, tag, msg); + sb.append('\n').append(Log.getStackTraceString(tr)); + if (tag == null) + tag = CORE_TAG; + + if (logsFolder != null) + { + sb.insert(0, String.valueOf(getLevelChar(level)) + '/' + tag + ": "); + LogsManager.EXECUTOR.execute(new WriteTask(logsFolder + File.separator + FILENAME, + sb.toString(), Thread.currentThread().getName())); + } + else + Log.println(level, tag, sb.toString()); } } @@ -151,8 +178,8 @@ public final class Logger { fw = new FileWriter(mFilePath, true); } - DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS", Locale.US); - fw.write(formatter.format(new Date()) + " " + mCallingThread + ": " + mData + "\n"); + final DateFormat fmt = new SimpleDateFormat("MM-dd HH:mm:ss.SSS", Locale.US); + fw.write(fmt.format(new Date()) + " (" + mCallingThread + ") " + mData + "\n"); } catch (IOException e) { diff --git a/android/src/com/mapswithme/util/log/LogsManager.java b/android/src/com/mapswithme/util/log/LogsManager.java index d600a8af0e..640ab5473c 100644 --- a/android/src/com/mapswithme/util/log/LogsManager.java +++ b/android/src/com/mapswithme/util/log/LogsManager.java @@ -35,7 +35,7 @@ import java.util.concurrent.Executors; * (Logger calls getEnabledLogsFolder() in preparation to write). */ @ThreadSafe -public class LogsManager +public final class LogsManager { public interface OnZipCompletedListener { @@ -246,10 +246,12 @@ public class LogsManager .append("\nNetworks: "); final ConnectivityManager manager = (ConnectivityManager) mApplication.getSystemService(Context.CONNECTIVITY_SERVICE); if (manager != null) + { // TODO: getAllNetworkInfo() is deprecated, for alternatives check // https://stackoverflow.com/questions/32547006/connectivitymanager-getnetworkinfoint-deprecated for (NetworkInfo info : manager.getAllNetworkInfo()) sb.append("\n\t").append(info.toString()); + } sb.append("\nLocation providers:"); final LocationManager locMngr = (android.location.LocationManager) mApplication.getSystemService(Context.LOCATION_SERVICE); if (locMngr != null) diff --git a/base/src_point.cpp b/base/src_point.cpp index 0f1cd33ff7..5e4d19ed9c 100644 --- a/base/src_point.cpp +++ b/base/src_point.cpp @@ -25,7 +25,7 @@ std::string DebugPrint(SrcPoint const & srcPoint) std::ostringstream out; if (srcPoint.Line() > 0) out << srcPoint.FileName() << ":" << srcPoint.Line() << " " << srcPoint.Function() - << srcPoint.Postfix() << " "; + << srcPoint.Postfix() << ": "; return out.str(); } } // namespace base